Vahid E-Portfolio https://sites.temple.edu/vahid Mon, 05 Feb 2024 14:25:01 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.3 Emigration https://sites.temple.edu/vahid/2024/02/05/emigration/ https://sites.temple.edu/vahid/2024/02/05/emigration/#respond Mon, 05 Feb 2024 14:25:00 +0000 https://sites.temple.edu/vahid/?p=167 This weblog is transfered to vahidkhalkhali.wordpress.com.

]]>
https://sites.temple.edu/vahid/2024/02/05/emigration/feed/ 0
Some HackerRank Solutions https://sites.temple.edu/vahid/2022/03/05/some-hackerrank-solutions/ https://sites.temple.edu/vahid/2022/03/05/some-hackerrank-solutions/#respond Sun, 06 Mar 2022 01:13:22 +0000 https://sites.temple.edu/vahid/?p=165 Balanced Brackets

https://www.hackerrank.com/challenges/balanced-brackets/problem

#!/bin/python3

import math
import os
import random
import re
import sys

#
# Complete the 'isBalanced' function below.
#
# The function is expected to return a STRING.
# The function accepts STRING s as parameter.
#

def isBalanced(s):
    # Write your code here
    br = []
    isbal = 'YES'
    for c in s:
        if c in ['{', '(', '[']:
            br.append(c)
        elif c in ['}', ')', ']']:
            if len(br) == 0:
                isbal = 'NO'
                break
            elif ((c == '}') & (br[-1] != '{') | 
                (c == ')') & (br[-1] != '(') | 
                (c == ']') & (br[-1] != '[')):
                isbal = 'NO'
                break
            else:
                br.pop(-1)
    if len(br) > 0:
        isbal = 'NO'
    return isbal                

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    t = int(input().strip())

    for t_itr in range(t):
        s = input()

        result = isBalanced(s)

        fptr.write(result + '\n')

    fptr.close()

Queue using Two Stacks

https://www.hackerrank.com/challenges/queue-using-two-stacks/problem

# Enter your code here. Read input from STDIN. Print output to STDOUT

if __name__ == '__main__':
    nq = int(input())
    q = []
    for _ in range(nq):
        a = input()
        if a[0] == '1':
            b = int(a[2:])
            q = q + [b]
        elif a[0] == '2':
            q = q[1:]
        elif a[0] == '3':
            print(q[0])

Merge two sorted linked lists

https://www.hackerrank.com/challenges/merge-two-sorted-linked-lists/problem

#!/bin/python3

import math
import os
import random
import re
import sys

class SinglyLinkedListNode:
    def __init__(self, node_data):
        self.data = node_data
        self.next = None

class SinglyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def insert_node(self, node_data):
        node = SinglyLinkedListNode(node_data)

        if not self.head:
            self.head = node
        else:
            self.tail.next = node


        self.tail = node

def print_singly_linked_list(node, sep, fptr):
    while node:
        fptr.write(str(node.data))

        node = node.next

        if node:
            fptr.write(sep)

# Complete the mergeLists function below.

#
# For your reference:
#
# SinglyLinkedListNode:
#     int data
#     SinglyLinkedListNode next
#
#
def mergeLists(head1, head2):
    h1, h2 = [], []
    while(head1):
        h1.append(head1.data)
        head1 = head1.next
    while(head2):
        h2.append(head2.data)
        head2 = head2.next
    s = sorted(h1+h2)
    ret = SinglyLinkedList();
    for v in s:
        ret.insert_node(v)
    return ret.head


if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    tests = int(input())

    for tests_itr in range(tests):
        llist1_count = int(input())

        llist1 = SinglyLinkedList()

        for _ in range(llist1_count):
            llist1_item = int(input())
            llist1.insert_node(llist1_item)
            
        llist2_count = int(input())

        llist2 = SinglyLinkedList()

        for _ in range(llist2_count):
            llist2_item = int(input())
            llist2.insert_node(llist2_item)

        llist3 = mergeLists(llist1.head, llist2.head)

        print_singly_linked_list(llist3, ' ', fptr)
        fptr.write('\n')

    fptr.close()
]]>
https://sites.temple.edu/vahid/2022/03/05/some-hackerrank-solutions/feed/ 0
HackerRank Solutions: Jesse and Cookies https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-jesse-and-cookies/ https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-jesse-and-cookies/#respond Sun, 06 Mar 2022 00:57:25 +0000 https://sites.temple.edu/vahid/?p=163 Problem

Jesse loves cookies and wants the sweetness of some cookies to be greater than value . To do this, two cookies with the least sweetness are repeatedly mixed. This creates a special combined cookie with:

sweetness  Least sweet cookie   2nd least sweet cookie).

This occurs until all the cookies have a sweetness .

Given the sweetness of a number of cookies, determine the minimum number of operations required. If it is not possible, return .

Example

The smallest values are .
Remove them then return  to the array. Now .
Remove  and return  to the array. Now .
Remove , return  and .
Finally, remove  and return  to . Now .
All values are  so the process stops after  iterations. Return .

Function Description
Complete the cookies function in the editor below.

cookies has the following parameters:

  • int k: the threshold value
  • int A[n]: an array of sweetness values

Returns

  • int: the number of iterations required or 

Input Format

The first line has two space-separated integers,  and , the size of  and the minimum required sweetness respectively.

The next line contains  space-separated integers, .

Constraints

Sample Input

STDIN               Function
-----               --------
6 7                 A[] size n = 6, k = 7
1 2 3 9 10 12       A = [1, 2, 3, 9, 10, 12]  

Sample Output

2

Explanation

Combine the first two cookies to create a cookie with sweetness  = 
After this operation, the cookies are .
Then, combine the cookies with sweetness  and sweetness , to create a cookie with resulting sweetness  = 
Now, the cookies are .
All the cookies have a sweetness .

Thus,  operations are required to increase the sweetness.

Solution

#!/bin/python3

import math
import os
import random
import re
import sys
import heapq

#
# Complete the 'cookies' function below.
#
# The function is expected to return an INTEGER.
# The function accepts following parameters:
#  1. INTEGER k
#  2. INTEGER_ARRAY A
#

def cookies(k, A):
    # Write your code here
    heapq.heapify(A)
    opc = 0
    while A[0] < k:
        if len(A) < 2:
            return -1
        a = heapq.heappop(A)
        b = heapq.heappop(A)
        heapq.heappush(A, a + 2*b)
        opc += 1
    return (opc if opc >= 0 else -1)

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')

    first_multiple_input = input().rstrip().split()

    n = int(first_multiple_input[0])

    k = int(first_multiple_input[1])

    A = list(map(int, input().rstrip().split()))

    result = cookies(k, A)

    fptr.write(str(result) + '\n')

    fptr.close()
]]>
https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-jesse-and-cookies/feed/ 0
HackerRank Solutions: No Prefix Set https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-no-prefix-set/ https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-no-prefix-set/#respond Sun, 06 Mar 2022 00:53:10 +0000 https://sites.temple.edu/vahid/?p=159 Problem

There is a given list of strings where each string contains only lowercase letters from , inclusive. The set of strings is said to be a GOOD SET if no string is a prefix of another string. In this case, print GOOD SET. Otherwise, print BAD SET on the first line followed by the string being checked.

Note If two strings are identical, they are prefixes of each other.

Example

Here ‘abcd’ is a prefix of ‘abcde’ and ‘bcd’ is a prefix of ‘bcde’. Since ‘abcde’ is tested first, print

BAD SET  
abcde

No string is a prefix of another so print

GOOD SET 

Function Description
Complete the noPrefix function in the editor below.

noPrefix has the following parameter(s):
– string words[n]: an array of strings

Prints
– string(s): either GOOD SET or BAD SET on one line followed by the word on the next line. No return value is expected.

Input Format
First line contains , the size of .
Then next  lines each contain a string, .

Constraints

 the length of words[i] 
All letters in  are in the range ‘a’ through ‘j’, inclusive.

Sample Input00

STDIN       Function
-----       --------
7            words[] size n = 7
aab          words = ['aab', 'defgab', 'abcde', 'aabcde', 'bbbbbbbbbb', 'jabjjjad']
defgab  
abcde
aabcde
cedaaa
bbbbbbbbbb
jabjjjad

Sample Output00

BAD SET
aabcde

Explanation
‘aab’ is prefix of ‘aabcde’ so it is a BAD SET and fails at string ‘aabcde’.

Sample Input01

4
aab
aac
aacghgh
aabghgh

Sample Output01

BAD SET
aacghgh

Explanation
‘aab’ is a prefix of ‘aabghgh’, and aac’ is prefix of ‘aacghgh’. The set is a BAD SET. ‘aacghgh’ is tested before ‘aabghgh’, so and it fails at ‘aacghgh’.

Solution

#!/bin/python3

import math
import os
import random
import re
import sys

#
# Complete the 'noPrefix' function below.
#
# The function accepts STRING_ARRAY words as parameter.
#

class Node:
    def __init__(self, parent=None, childrean=dict()):
        self.parent = parent
        self.children = childrean
        self.leaf = False

def noPrefix(words):
    # Write your code here
    # make Trie
    root = Node(None)
    for word in words:
        node = root
        prefix = False
        for let in word:
            exists = []
            if let in node.children.keys():
                child = node.children[let]
                exists.append(True)
            else:
                exists.append(False)
                child = Node(node, dict())
                node.children[let] = child
            node = child
            if node.leaf:
                prefix = True
                break
        if prefix | all(exists):
            prefix = True
            break
        node.leaf = True
    if prefix:
        print('BAD SET')
        print(word)
    else:
        print('GOOD SET')
            
    
    
if __name__ == '__main__':
    n = int(input().strip())

    words = []

    for _ in range(n):
        words_item = input()
        words.append(words_item)

    noPrefix(words)
]]>
https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-no-prefix-set/feed/ 0
HackerRank Solutions: Tree: Huffman Decoding https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-tree-huffman-decoding/ https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-tree-huffman-decoding/#respond Sun, 06 Mar 2022 00:48:52 +0000 https://sites.temple.edu/vahid/?p=156 Problem

Huffman coding assigns variable length codewords to fixed length input characters based on their frequencies. More frequent characters are assigned shorter codewords and less frequent characters are assigned longer codewords. All edges along the path to a character contain a code digit. If they are on the left side of the tree, they will be a 0 (zero). If on the right, they’ll be a 1 (one). Only the leaves will contain a letter and its frequency count. All other nodes will contain a null instead of a character, and the count of the frequency of all of it and its descendant characters.

For instance, consider the string ABRACADABRA. There are a total of  characters in the string. This number should match the count in the ultimately determined root of the tree. Our frequencies are  and . The two smallest frequencies are for  and , both equal to , so we’ll create a tree with them. The root node will contain the sum of the counts of its descendants, in this case . The left node will be the first character encountered, , and the right will contain . Next we have  items with a character count of : the tree we just created, the character  and the character . The tree came first, so it will go on the left of our new root node.  will go on the right. Repeat until the tree is complete, then fill in the ‘s and ‘s for the edges. The finished graph looks like:

image

Input characters are only present in the leaves. Internal nodes have a character value of ϕ (NULL). We can determine that our values for characters are:

A - 0
B - 111
C - 1100
D - 1101
R - 10

Our Huffman encoded string is:

A B    R  A C     A D     A B    R  A
0 111 10 0 1100 0 1101 0 111 10 0
or
01111001100011010111100

To avoid ambiguity, Huffman encoding is a prefix free encoding technique. No codeword appears as a prefix of any other codeword.

To decode the encoded string, follow the zeros and ones to a leaf and return the character there.

You are given pointer to the root of the Huffman tree and a binary coded string to decode. You need to print the decoded string.

Function Description

Complete the function decode_huff in the editor below. It must return the decoded string.

decode_huff has the following parameters:

  • root: a reference to the root node of the Huffman tree
  • s: a Huffman encoded string

Input Format

There is one line of input containing the plain string, . Background code creates the Huffman tree then passes the head node and the encoded string to the function.

Constraints

Output Format

Output the decoded string on a single line.

Sample Input

image
s="1001011"

Sample Output

ABACA

Explanation

S="1001011"
Processing the string from left to right.
S[0]='1' : we move to the right child of the root. We encounter a leaf node with value 'A'. We add 'A' to the decoded string.
We move back to the root.

S[1]='0' : we move to the left child. 
S[2]='0' : we move to the left child. We encounter a leaf node with value 'B'. We add 'B' to the decoded string.
We move back to the root.

S[3] = '1' : we move to the right child of the root. We encounter a leaf node with value 'A'. We add 'A' to the decoded string.
We move back to the root.

S[4]='0' : we move to the left child. 
S[5]='1' : we move to the right child. We encounter a leaf node with value C'. We add 'C' to the decoded string.
We move back to the root.

 S[6] = '1' : we move to the right child of the root. We encounter a leaf node with value 'A'. We add 'A' to the decoded string.
We move back to the root.

Decoded String = "ABACA"

Solution

import queue as Queue

cntr = 0

class Node:
    def __init__(self, freq, data):
        self.freq = freq
        self.data = data
        self.left = None
        self.right = None
        global cntr
        self._count = cntr
        cntr = cntr + 1
        
    def __lt__(self, other):
        if self.freq != other.freq:
            return self.freq < other.freq
        return self._count < other._count

def huffman_hidden():#builds the tree and returns root
    q = Queue.PriorityQueue()

    
    for key in freq:
        q.put((freq[key], key, Node(freq[key], key) ))
    
    while q.qsize() != 1:
        a = q.get()
        b = q.get()
        obj = Node(a[0] + b[0], '\0' )
        obj.left = a[2]
        obj.right = b[2]
        q.put((obj.freq, obj.data, obj ))
        
    root = q.get()
    root = root[2]#contains root object
    return root

def dfs_hidden(obj, already):
    if(obj == None):
        return
    elif(obj.data != '\0'):
        code_hidden[obj.data] = already
        
    dfs_hidden(obj.right, already + "1")
    dfs_hidden(obj.left, already + "0")

"""class Node:
    def __init__(self, freq,data):
        self.freq= freq
        self.data=data
        self.left = None
        self.right = None
"""        

# Enter your code here. Read input from STDIN. Print output to STDOUT
def decodeHuff(root, s):
    #Enter Your Code Here
    
    # encoding
    msg = ''
    c = 0
    node = root
    while(c < len(s)):
        d = s[c]
        if (node.data == '\0'):
            node = node.left if d == '0' else node.right
            c += 1
        else:
            msg += node.data
            node = root
    msg += node.data
    print(msg)
    
    
    

ip = input()
freq = {}#maps each character to its frequency

cntr = 0

for ch in ip:
    if(freq.get(ch) == None):
        freq[ch] = 1
    else:
        freq[ch]+=1

root = huffman_hidden()#contains root of huffman tree

code_hidden = {}#contains code for each object

dfs_hidden(root, "")

if len(code_hidden) == 1:#if there is only one character in the i/p
    for key in code_hidden:
        code_hidden[key] = "0"

toBeDecoded = ""

for ch in ip:
   toBeDecoded += code_hidden[ch]

decodeHuff(root, toBeDecoded)
]]>
https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-tree-huffman-decoding/feed/ 0
HackerRank Solutions: Tree: Preorder Traversal https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-tree-preorder-traversal/ https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-tree-preorder-traversal/#respond Sun, 06 Mar 2022 00:44:28 +0000 https://sites.temple.edu/vahid/?p=152 Problem

Complete the  function in the editor below, which has  parameter: a pointer to the root of a binary tree. It must print the values in the tree’s preorder traversal as a single line of space-separated values.

Input Format

Our test code passes the root node of a binary tree to the preOrder function.

Constraints

 Nodes in the tree 

Output Format

Print the tree’s preorder traversal as a single line of space-separated values.

Sample Input

     1
      \
       2
        \
         5
        /  \
       3    6
        \
         4  

Sample Output

1 2 5 3 4 6 

Explanation

The preorder traversal of the binary tree is printed.

Solution

class Node:
    def __init__(self, info): 
        self.info = info  
        self.left = None  
        self.right = None 
        self.level = None 

    def __str__(self):
        return str(self.info) 

class BinarySearchTree:
    def __init__(self): 
        self.root = None

    def create(self, val):  
        if self.root == None:
            self.root = Node(val)
        else:
            current = self.root
         
            while True:
                if val < current.info:
                    if current.left:
                        current = current.left
                    else:
                        current.left = Node(val)
                        break
                elif val > current.info:
                    if current.right:
                        current = current.right
                    else:
                        current.right = Node(val)
                        break
                else:
                    break

"""
Node is defined as
self.left (the left child of the node)
self.right (the right child of the node)
self.info (the value of the node)
"""
def preOrder(root):
    #Write your code here
    stack = [root]
    sti = 0
    while (sti < len(stack)):
        currnode = stack[sti]
        if currnode.left:
            stack.insert(sti+1, currnode.left)
            if currnode.right:
                stack.insert(sti+2, currnode.right)
        elif currnode.right:
            stack.insert(sti+1, currnode.right)
        sti += 1
    for s in stack:
        print(s.info, end=' ')

]]>
https://sites.temple.edu/vahid/2022/03/05/hackerrank-solutions-tree-preorder-traversal/feed/ 0
Debugging in Python https://sites.temple.edu/vahid/2022/01/19/debugging-in-python/ https://sites.temple.edu/vahid/2022/01/19/debugging-in-python/#respond Wed, 19 Jan 2022 19:06:01 +0000 https://sites.temple.edu/vahid/?p=144 There are three main tools for debugging in Python.

In Python version less than 3, it was common to use the set_trace() command for making a starting debugger point, but in newer versions, it is possible to define the PYTHONBREAKPOINT environment variable before running the Python program and the debugger can be started by the breakpoint() command.

  • pdb

This is the default debugger in Python. It is similar to gdb in Gnu Linux with very limited capabilities, but enough to debug programs in Python.

It works in the terminal and by the “h” command, the list of available commands with brief descriptions appears.

  • ipdb

Colorful debugging with running the following command:

python -m ipdb test.py

Or calling from inside the Python code by:

import ipdb
breakpoint()

The commands are similar to pdb.

  • PuDB

This is a graphical debugger that runs in the terminal. The graphical feature makes it attractive and the usage is very similar to ipdb.

  • web-pdb

As the name shows, it works in the browser. The URL of localhost:5555 is used which can be redirected via ssh with the following command:

ssh -X username@server -L 5555:localhost:5555

At the top of the program, the following commands should be inserted:

import web_pdb
web_pdb.set_trace()

Or changing the environment variable as PYTHONBREAKPOINT=”web_pdb.set_trace” and then calling the breakpoint() command.

Then the debugger can be opened in the web browser.

]]>
https://sites.temple.edu/vahid/2022/01/19/debugging-in-python/feed/ 0
Ray.Tune Model Optimization https://sites.temple.edu/vahid/2022/01/11/ray-tune-model-optimization/ https://sites.temple.edu/vahid/2022/01/11/ray-tune-model-optimization/#respond Wed, 12 Jan 2022 00:21:45 +0000 https://sites.temple.edu/vahid/?p=138 One of the very important questions in the deep learning is what model is the best. There are two well-known methods to find the best models:

  1. Reinforcement Learning Methods
  2. Search Methods

There are some good resources for RL methods, such as:

  • 2018 – Learning Transferable Architectures for Scalable Image Recognition
  • 2018 – Neural Architecture Optimization
  • 2018 – Progressive neural architecture search

They designed a non-linear cost function (usually with RNN or LSTM) to predict the models’ performance without the need to train them. In this way, they save a huge amount of time and make the method feasible.

On the other hand, the search methods which are usually based on evolutionary algorithms try to narrow the search space with heuristic methods and find the optimum design.

Both methods need some manual modifications to successfully give better performance than human-made models. It does not seem a human can guess the successful architectures because there is no clear interpretation for connections between elements in the network.

But there is an important question that which is more important:

  1. A well-trained network with good performance
  2. A network with winner architecture and good performance

My opinion is that if we can train a network with too many parameters and reach a good performance, it is not important if the architecture is perfect or not. Even the perfect architecture is very controversial. When architecture is evaluated, in the best case, it will be retrained several times and the average performance will be taken as the architecture performance which is not completely true. We know that when the search space is huge, finding the optimum points needs very good luck. So, assigning a performance to a large neural network cannot show its capabilities, because it may be trained in another condition and gives much better results.

Hence, a well-trained network with good performance is more important than good architecture. Ray Tune can help to find an optimum neural network by tuning the hyperparameters.

Here, is a dummy example to show the Ray Tune operation combined with TensorBoard:

https://github.com/Vahid-GitHub/weblog/blob/main/02_raytune_checkpoint.py

Then by the following command, the TensorBoard can be opened in the Chrome browser.

tensorboard –logdir ./log/

The default server address in Google Chrome is:

http://localhost:6006/

]]>
https://sites.temple.edu/vahid/2022/01/11/ray-tune-model-optimization/feed/ 0
PyTorch Code Profiling https://sites.temple.edu/vahid/2022/01/10/pytorch-code-profiling/ https://sites.temple.edu/vahid/2022/01/10/pytorch-code-profiling/#respond Tue, 11 Jan 2022 03:17:23 +0000 https://sites.temple.edu/vahid/?p=133 There are some tools for profiling the PyTorch codes.

PyTorch Profiler

This can generate almost all is happening in PyTorch codes, such as CPU, GPU, memory, and stack usage. Moreover, it can generate enough information to be used in TensorBoard or even simple json format which can be opened in Chrome browser with chrome://tracing.

TensorBoard

After installing TensorBoard, this can be imported from torch.utils.tensorboard as SummaryWriter. This SummaryWriter can write images, audios, time series or any other scalar in a chronological order. So, it will be possible to keep the track of any parameters during epochs or any other specific steps. Then it can be seen in TensorBoard by showing the log directory to tensorboard command and tunneling via the ssh.

To run all these on our cluster, the following commands are needed:

>> tensorboard –logdir=./log/

>> ssh -CNL localhost:6006:localhost:6006 nedc_008

]]>
https://sites.temple.edu/vahid/2022/01/10/pytorch-code-profiling/feed/ 0
Interactive Plots in JupyterLab https://sites.temple.edu/vahid/2021/12/25/interactive-plots-in-jupyterlab/ https://sites.temple.edu/vahid/2021/12/25/interactive-plots-in-jupyterlab/#respond Sun, 26 Dec 2021 04:31:01 +0000 https://sites.temple.edu/vahid/?p=129 There are several ways to plot interactively in JupyterLab.

  • Altair
  • Plotly
  • Bokeh
  • ipywidgets

Between all the above, I found ipywidgets easier to use than the others.

To be able to use ipywidgets, some installations are needed:

  • If we work in user mode in Linux, then clone the actual environment with:
    • conda create –name mytorch –clone torch
  • Activate the new environment:
    • conda activate mytorch
  • Install all necessary software such as Jupyter-Lab if needed:
    • conda install -c conda-forge jupyterlab
  • Then install the following:
    • conda install -c conda-forge ipympl
    • conda install -c conda-forge nodejs
    • jupyter labextension install @jupyter-widgets/jupyterlab-manager
    • jupyter lab build
  • Then add “%matplotlib widget” to your jupyter notebook.

Enjoy it!

]]>
https://sites.temple.edu/vahid/2021/12/25/interactive-plots-in-jupyterlab/feed/ 0