git quick tip – branching and merging

Sometimes you want to do experiment work or wants to patch the git master branch with some experimental code, in that case, it’s not the good idea to change the local master branch. Below are steps to do the changes in an experimental branch made with master and merge back to master and the pushback server.

Scenario:

    • Create a new branch locally with the existing branch
    • Make changes and commit these changes
    • Merge them with the local branch from where we have made the branch
    • push to the git server.

Example:
# Make a master_dev from master branch
$ git checkout -b master_dev master

# Do changes in master_dev branch
$ git commit -am "Commit message"

# Checkout master branch
$ git checkout master

# Merge the changes of master_dev to master
$ git merge --no-ff master_dev

# Push the changes of master to origin master
$ git push origin master

# Optionally one can push the master_dev branch to remote
# DO ONLY IF YOU WANT MASTER_DEV BRANCH ALSO ON SERVER
$ git push origin master_dev

 

Happy programming!

grep and map-Two magical operators

Over the years I have extensively used map and grep in Perl, JavaScript, Python, Linux. I am sure most of the programmers love using these two operators. Read below some of my personal notes gathered from several resources and own understanding.

map – transforms the values of a list

The “map” function applies a transformation to each element of a list and returns the result, leaving the original list unchanged. A map can also be seen as the form of foreach loop but with the map, the implementation is much cleaner.

Ex: map { $_ => undef} is better than, map{$_=>1} the former one will save memory. It’s a better idea to use undef instead of 1.

Instead of one scalar of the value ‘1’ for every key, you get to share the same undef value for all the keys and thus don’t have to allocate tons of memory you aren’t going to use anyway.

The above idiom is a simple way of creating a list of unique values from another list, as the output of the code aptly demonstrates. However, with all those curly braces it may not be immediately obvious what’s going on, so let’s break it down.

map { $_ => 1 } @list

This is pretty straight-forward – create a list of key-value pairs where the keys are the values from @list

{ map { $_ => 1 } @list }

The surrounding pair of curly braces creates an anonymous hash which is populated with they key-value pairs from the map statement. So we now have a hash reference to an anonymous hash whose keys are the elements from @list, and because hash keys are unique, the keys of the anonymous hash represents a unique set of values.

keys %{ { map { $_ => 1 } @list } }

Finally, with the last pair of curly braces, the hash reference to the anonymous hash is dereferenced and we get its list of keys.

grep – filters a list

The “grep” function returns only the elements of a list that meet a certain condition:

@positive_numbers = grep($_ > 0, @numbers);

As you can see, each element is refered to as “$_”. This (plus the fact that parentheses are optional) allows you write commands that look similar to invocations of the Unix “grep” program:

@non_blank_lines = grep /S/, @lines;

In addition, you can specify a code block rather than a single condition:

@non_blank_lines = grep { /S/ } @lines; # Equivalent to the above.

Obviously it doesn’t matter in this case, but code blocks are helpful when you want a complex filter with multiple lines of code. The result of the code block is the result of the last statement executed:

# All positive numbers can be used as exponents,
# but negative exponents must be integers.
@can_be_used_as_exponent = grep {
if ( $_ < 0 ) {
! /./; # No decimal point -> integer.
}
else {
1; # Always true.
}
} @array;

What “grep” and “map” have in common?

"grep" and "map" have a lot in common. They both “magically” take a piece of code (either an expression or a code block) as a parameter. You need to put a comma after an expression but shouldn’t put a comma after a code block. Changing "$_" in "grep" or "map" will change the original list.

This isn’t generally a good idea because it makes the code hard to read. Remember that "map" builds a list of results by evaluating an expression, NOT by setting "$_". A side effect of this fact is that you should not use "s///" with "map". The "s///" operator changes "$_" rather than returning a result, so you won’t get what you would expect if you use it with "map" (and you CERTAINLY shouldn’t use it with "grep").

Happy programming!

References:
Discussion on PerlMonks
perldoc

Deep learning specialization notes

A couple of months back I have completed Deep Learning Specialization taught by AI guru Andrew NG. During the learning process, I have made personal notes from all the 5 courses.  Notes are based on lecture video and supplementary material provided and my own understanding of the topic. I have used lots of diagrams and code snippets which I made from course videos and slides. I am fully complying with The Honor Code. No programming assignment and solutions are published on GitHub or any other site.

Please note that most of the places I am not using exact mathematical symbol and other notation, instead using plain English name this is just to save some time, also please note that this is a personal diary made during course and I guess a bit longer too and few places not very well organized, so in any form doesn’t replace the content and learning process one follows during course which includes quizzes, programming assignments, project etc. This is a great course so I encourage you to enroll.

What you will learn at the end of the specialization:

Neural Networks and Deep Learning: This course gives foundations of neural networks and deep learning. How to build and train. At the end of this course, we’ll in position to recognize cat so will make a cat recognizer.  [PDF]

Improving Deep Neural Networks – Hyperparameter Tuning, Regularization and Optimization: In this course, we’ll learn about practical aspects of the NN. Now you have made NN/deep network so the focus is on how to make it perform well. We’ll fine tune various things like hyperparamater tuning, regularization algorithms and optimization algorithms like RMSProp, Adam etc. So this course helps greatly in making model perform well.  [PDF]

Structuring your Machine Learning Project: In this course, we’ll learn how to structure machine learning projects. It is observed that strategy for machine learning projects has been changed a lot in deep learning era. For example, the way you divide data in train/test/dev set has been changed in the era of deep learning also whether train and test data comes from the same distributions etc.? we’ll also learn about end-to-end deep learning. The material in this course is relatively unique.  [PDF]

Convolutional Neural Networks(CNN): CNN is often applied in images mainly in computer vision problems. In this course, we’ll learn about how to make these models using CNN’s.  [PDF]

Natural Language Processing-Building Sequence Models: In this course, we’ll learn about algorithms like Recurrent Neural Network (RNN’s), LSTM (Long Short-Term Memory) and learn how to apply them with the sequence of data like natural language processing, speech recognition, music generation etc.  [PDF]

 

Happy learning!

Pl, drop a note in case of any feedback.

 

References:

Deep Learning Specialization:
https://www.deeplearning.ai/

Github (Source code and diagrams used in notes):
https://github.com/ppant/deeplearning.ai-notes

Deep learning Specialization completion certificate: https://www.coursera.org/account/accomplishments/specialization/WVPVCUMH94YS

 

Data Structures and Algorithms in Python – Graphs

Graph Implementation – Adjacency list

  • We’ve used dictionaries to implement the adjacency list in Python which is the easiest way.
  • To implement Graph ADT we’ll create two classes, Graph, which holds the master list of vertices, and Vertex, which will represent each vertex in the graph.
  • Each Vertex uses a dictionary to keep track of the vertices to which it is connected, and the weight of each edge. This dictionary is called connectedTo.
# Create six vertices numbered 0 through 5. 
# Display the vertex dictionary
g = Graph()
for i in range(6):
    g.addVertex(i)
print(g.vertList)

# Add the edges that connect the vertices together
g.addEdge(0,1,5)
g.addEdge(0,5,2)
g.addEdge(1,2,4)
g.addEdge(2,3,9)
g.addEdge(3,4,7)
g.addEdge(3,5,3)
g.addEdge(4,0,1)
g.addEdge(5,4,8)
g.addEdge(5,2,1)
# Nested loop verifies that each edge in the graph is properly stored. 
for v in g:
   for w in v.getConnections():
       print("( %s , %s )" % (v.getId(), w.getId()))

Graph Implementation – Solving Word Ladder Problem using Breadth First Search (BFS)

let’s consider the following puzzle called a word ladder. Transform the word “FOOL” into the word “SAGE”. In a word ladder puzzle you must make the change occur gradually by changing one letter at a time. At each step you must transform one word into another word, you are not allowed to transform a word into a non-word. The following sequence of words shows one possible solution to the problem posed above.

  • FOOL
  • POOL
  • POLL
  • POLE
  • PALE
  • SALE
  • SAGE

This is implemented using dictionary

# The Graph class, contains a dictionary that maps vertex names to vertex objects.
# Graph() creates a new, empty graph.
Graph()   

buildGraph()

#BFS begins at the starting vertex s and colors start gray to show that 
#it is currently being explored. Two other values, the distance and the 
#predecessor, are initialized to 0 and None respectively for the starting
#vertex. Finally, start is placed on a Queue. The next step is to begin 
#to systematically explore vertices at the front of the queue. We explore 
#each new node at the front of the queue by iterating over its adjacency 
#list. As each node on the adjacency list is examined its color is 
#checked. If it is white, the vertex is unexplored, and four things happen:
#	* The new, unexplored vertex nbr, is colored gray.
#	* The predecessor of nbr is set to the current node currentVert
#The distance to nbr is set to the distance to currentVert + 1
#nbr is added to the end of a queue. Adding nbr to the end of the queue 
#effectively schedules this node for further exploration, but not until all the 
#other vertices on the adjacency list of currentVert have been explored.

bfs()

Graph Implementation – Solving Knight tour problem using Depth First Search (DFS)

The knight’s tour puzzle is played on a chess board with a single chess piece, the knight. The object of the puzzle is to find a sequence of moves that allow the knight to visit every square on the board exactly once. One such sequence is called a “tour.”
we will solve the problem using two main steps: Represent the legal moves of a knight on a chessboard as a graph. Use a graph algorithm to find a path of length rows×columns−1rows×columns−1 where every vertex on the graph is visited exactly once. To represent the knight’s tour problem as a graph we will use the following two ideas: Each square on the chessboard can be represented as a node in the graph. Each legal move by the knight can be represented as an edge in the graph.

# The Graph class, contains a dictionary that maps vertex names to vertex objects.
# Graph() creates a new, empty graph.
Graph()

# To represent the knight’s tour problem as a graph we will use the 
# following two ideas: Each square on the chessboard can be represented 
# as a node in the graph. Each legal move by the knight can be represented
# as an edge in the graph. 

knightGraph()

# The genLegalMoves function takes the position of the knight on the 
# board and generates each of the eight possible moves. The legalCoord 
# helper function makes sure that a particular move that is generated is 
# still on the board.
genLegalMoves()

# DFS implementation
        
# we will look at two algorithms that implement a depth first search. 
# The first algorithm we will look at directly solves the knight’s tour 
# problem by explicitly forbidding a node to be visited more than once. 
# The second implementation is more general, but allows nodes to be visited 
# more than once as the tree is constructed. The second version is used in 
# subsequent sections to develop additional graph algorithms.

# The depth first exploration of the graph is exactly what we need in 
# order to find a path that has exactly 63 edges. We will see that when 
# the depth first search algorithm finds a dead end (a place in the graph 
# where there are no more moves possible) it backs up the tree to the next
# deepest vertex that allows it to make a legal move.
        
# The knightTour function takes four parameters: n, the current depth in 
# the search tree; path, a list of vertices visited up to this point; u, 
# the vertex in the graph we wish to explore; and limit the number of nodes 
# in the path. The knightTour function is recursive. When the knightTour 
# function is called, it first checks the base case condition. If we have 
# a path that contains 64 vertices, we return from knightTour with a status 
# of True, indicating that we have found a successful tour. If the path is not 
# long enough we continue to explore one level deeper by choosing a new vertex 
# to explore and calling knightTour recursively for that vertex.

# DFS also uses colors to keep track of which vertices in the graph have been visited. 
# Unvisited vertices are colored white, and visited vertices are colored gray. 
# If all neighbors of a particular vertex have been explored and we have not yet reached 
# our goal length of 64 vertices, we have reached a dead end. When we reach a dead end we 
# must backtrack. Backtracking happens when we return from knightTour with a status of False. 
# In the breadth first search we used a queue to keep track of which vertex to visit next. 
# Since depth first search is recursive, we are implicitly using a stack to help us with 
# our backtracking. When we return from a call to knightTour with a status of False, in line 11, 
# we remain inside the while loop and look at the next vertex in nbrList.

knightTour()

Please check GitHub for the full working code.

I will keep adding more problems/solutions.

Stay tuned!

Ref:  The inspiration of implementing DS in Python is from this course

Data Structures and Algorithms in Python – Sorting

Bubble Sort Implementation

The bubble sort makes multiple passes through a list. It compares adjacent items and exchanges those that are out of order. Each pass through the list places the next largest value in its proper place. In essence, each item “bubbles” up to the location where it belongs.

  • Regardless of how the items are arranged in the initial list, n−1 passes will be made to sort a list of size n, so 1 pass n-1 comparisons, 2 pass n-2 comparions and n-1 is 1 comparions.
  • A bubble sort is often considered the most inefficient sorting method since it must exchange items before the final location is known. These “wasted” exchange operations are very costly. However, because the bubble sort makes passes through the entire unsorted portion of the list, it has the capability to do something most sorting algorithms cannot. In particular, if during a pass there are no exchanges, then we know that the list must be sorted. A bubble sort can be modified to stop early if it finds that the list has become sorted. This means that for lists that require just a few passes, a bubble sort may have an advantage in that it will recognize the sorted list and stop.
  • Performance: – Worst case: O(n2) n-square – Best case: O(n) – Average case: O(n2) n-square
arr = [2,7,1,8,5,9,11,35,25]
bubble_sort(arr)
print (arr)
[1, 2, 5, 7, 8, 11, 25, 35]
Selection Sort Implementation
  • Selection sort is a in-place algorithm
  • It works well with small files
  • It is used for sorting the files with large values and small keys this is due to the fact that selection is based on keys and swaps are made only when required
  • The selection sort improves on the bubble sort by making only one exchange for every pass through the list. In order to do this, a selection sort looks for the largest value as it makes a pass and, after completing the pass, places it in the proper location. As with a bubble sort, after the first pass, the largest item is in the correct place. After the second pass, the next largest is in place. This process continues and requires n−1 passes to sort n items, since the final item must be in place after the (n−1) st pass
  • Performance: – Worst case: O(n2) n-square – Best case: O(n) – Average case: O(n2) n-square – worst case space complexity: O(1)
arr = [2,7,1,8,5,9,11,35,25]
selection_sort(arr)
print (arr)
[1, 2, 5, 7, 8, 11, 25, 35]

 

Insertion Sort Implementation

Insertion sort always maintains a sorted sub list in the lower portion of the list Each new item is then “inserted” back into the previous sublist such that the sorted sub list is one item larger complexity O(n2) square

arr = [2,7,1,8,5,9,11,35,25]
insertion_sort(arr)
print (arr)
[1, 2, 5, 7, 8, 11, 25, 35]

 

Merge Sort Implementation

Merge sort is a recursive algorithm (example of divide and conquer) that continually splits a list in half.

  • If the list is empty or has one item, it is sorted by definition (the base case).
  • If the list has more than one item, we split the list and recursively invoke a
  • Merge sort on both halves.
  • Once the two halves are sorted, the fundamental operation, called a merge, is performed.
  • Merging is the process of taking two smaller sorted lists and combining them
  • together into a single, sorted, new list.
  • This algorithm is used to sort a linked list
  • Performance: – Worst case: O(nlog n) – Best case: O(nlog n) – Average case: O(nlog n)
arr = [11,2,5,4,7,6,8,1,23]
merge_sort(arr)
print (arr)
[1, 2, 4, 5, 6, 7, 8, 11, 23]

 

Quick Sort Implementation

The quick sort uses divide and conquer to gain the same advantages as the merge sort, while not using additional storage also known as “partition exchange sort”.

  • As a trade-off, however, it is possible that the list may not be divided in half.
  • When this happens, we will see that performance is diminished.
  • A quick sort first selects a value, which is called the pivot value.
  • The role of the pivot value is to assist with splitting the list.
  • The actual position where the pivot value belongs in the final sorted list, commonly called the split point, will
    be used to divide the list for subsequent calls to the quick sort.
  • Performance:
    • Worst case: O(n square)
    • Best case: O(nlog n)
    • Average case: O(nlog n)
arr = [2,7,1,8,5,9,11,35,25]
quick_sort(arr)
print (arr)
[1, 2, 5, 7, 8, 11, 25, 35]

 

Shell Sort Implementation

This is also called diminishing incremental sort

  • The shell sort improves on insertion sort by breaking the original list into a number of smaller sublists.
  • The unique way these sun lists are chosen is the key to the shell sort
  • Instead of breaking the list into sublists of contiguous items, the shell sort uses an increment ”i” to create a sublist by choosing all items that are ”i” items apart.
  • Shell sort is efficient for medium size lists
  • Complexity somewhere between O(n) and O(n2) square
arr = [45,67,23,45,21,24,7,2,6,4,90]
shell_sort(arr)
print (arr)
[2, 4, 6, 7, 21, 23, 24, 45, 45, 67, 90]

Check GitHub for the full working code.

I will keep adding more problems/solutions.

Stay tuned!

Ref:  The inspiration of implementing DS in Python is from this course

Data Structures and Algorithms in Python – Recursion

Computes the cumulative sum – Recursion

Aim is to write a recursive function which takes an integer and computes the cumulative sum of 0 to that integer. For example, if n=4 , return 4+3+2+1+0, which is 10. We always should take care of the base case. In this case, we have a base case of n =0 (Note, you could have also designed the cut off to be 1). In this case, we have: n + (n-1) + (n-2) + …. + 0. Example:

print (recursion_cululative_sum(5))

Sum of digits – Recursion

Given an integer, create a function which returns the sum of all the individual digits in that integer. For example: if n = 4321, return 4+3+2+1 Example:

print (recursion_sum_digits(12))

Word split – Recursion

Create a function called word_split() which takes in a string phrase and a set list_of_words. The function will then determine if it is possible to split the string in a way in which words can be made from the list of words. You can assume the phrase will only contain words found in the dictionary if it is completely splittable. Example:

 print (word_split('themanran',['the','ran','man']))

Reverse a string – Recursion

Implement a recursive reverse. Example:

 print(reverse_str('hello world'))

List all the permutation of a string – Recursion

Given a string, write a function that uses recursion to output a list of all the possible permutations of that string. For example, given s=’abc’ the function should return [‘abc’, ‘acb’, ‘bac’, ‘bca’, ‘cab’, ‘cba’] This way of doing permutaion is for learning in real scenerios better to use excellant Python library “ltertools” with current approach there are n! permutations, so the it looks that algorithm will take O(n*n!)time Example:

 print(permute('abc'))

Implement fibonacci sequence with simple iteration

# We'll try to find the 9th no in the fibonacci sequence which is 34
print (fibonacci_itertaive(9))
# 34
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
# The recursive solution is exponential time Big-O , with O(n).

Implement fibonacci sequence – Recursion

Our function will accept a number n and return the nth number of the fibonacci sequence Remember that a fibonacci sequence: 0,1,1,2,3,5,8,13,21,… starts off with a base case checking to see if n = 0 or 1, then it returns 1. Else it returns fib(n-1)+fib(n+2).

# We'll try to find the 9th no in the fibnacci sequence which is 34
print (fibonacci_recursion(9))
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
# The recursive solution is exponential time Big-O , with O(2^n). However, 
# its a very simple and basic implementation to consider

Implement fibonacci sequence – Dynamic programming

Implement the function using dynamic programming by using a cache to store results (memoization). memoization + recursion = dynamic programming

# We'll try to find the 9th no in the fibnacci sequence which is 34
print (fibonacci_dynamic(9))
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
# The recursive-memoization solution is exponential time Big-O , with O(n)

Implement coin change problem – Recursion

Given a target amount n and a list (array) of distinct coin values, what’s the fewest coins needed to make the change amount. 1+1+1+1+1+1+1+1+1+1 5 + 1+1+1+1+1 5+5 10 With 1 coin being the minimum amount.

print (coin_change_recursion(8,[1,5]))
# 4
# Note:
# The problem with this approach is that it is very inefficient! It can take many, 
# many recursive calls to finish this problem and its also inaccurate for non 
# standard coin values (coin values that are not 1,5,10, etc.)

Implement coin change problem – Dynamic programming

Given a target amount n and a list (array) of distinct coin values, what’s the fewest coins needed to make the change amount.

1+1+1+1+1+1+1+1+1+1
5 + 1+1+1+1+1
5+5
10
With 1 coin being the minimum amount.
# Caching
target = 74
coins = [1,5,10,25]
known_results = [0]*(target+1)

print (coin_change_dynamic(target,coins,known_results))

Check GitHub for the full working code.

I will keep adding more problems/solutions.

Stay tuned!

Ref:  The inspiration of implementing DS in Python is from this course

Implemeting Data Structures and Algorithms in Python: Problems and solutions Contd..

Contd.. from last post

Array Pair SumArray Pair Sum

Given an integer array, output all the unique pairs that sum up to a specific value k. So the input:

sum_arr_uniq_pairs([1,2,2,3,4,1,1,3,2,1,3,1,2,2,4,0],5) 

would return 2 pairs:
(2,3)  (1,4)

Find a missing element in an array/list

Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array. Here is an example input, the first array is shuffled and the number 5 is removed to construct the second array.
Input:

 find_missing_ele([1,2,3,4,5,6,7],[3,7,2,1,4,6]) 

Output:5 is the missing numberStack class implementation

Implement basic stack operations (LIFO)

push() – Push an element in a stack pop()- POP an element from top of the stackpeek() – Just peek into top element of the stack (don’t perform any operation)Queue class implementation

Implement basic Queue operations (FIFO)

enqueue – adding a element to the queue dequeue – removing an element from the queueDeque (DECK) class implementation

Implement basic operation in deque (Add and remove elements both at front and rear)

addFront()

Add an element at the front

addRear()

Add an element at the rear

removeFront()

Remove from front

removeRear()

Remove from rear

Balance parentheses using stack/list

Given a string of opening and closing parentheses, check whether it’s balanced. We have 3 types of parentheses: round brackets: () square brackets: [] curly brackets: {}. Assume that the string doesn’t contain any other character than these, no spaces words or numbers. As a reminder, balanced parentheses require every opening parenthesis to be closed in the reverse order opened. For example ‘([])’ is balanced but ‘([)]’ is not. Algo will take a string as the input string and will return boolean (TRUE/FALSE) Examples:

print (check_parentheses_match('([])'))
print (check_parentheses_match('[](){([[[]]])'))

 

Queue with 2 stack implementation

This is a classic problem. We need to use the basic characteristics of the stack (popping out elements in reverse order) will make a queue. Example:

# Create a object of the class
qObj = QueueWith2Stack()
# Add an element 
qObj.enqueue(1)
# Add another element
qObj.enqueue(2)
# Add more element
qObj.enqueue(4)
# Add more element
qObj.enqueue(8)
# Remove item
print (qObj.dequeue())
# Remove item 
print (qObj.dequeue())
# Remove item
print (qObj.dequeue())
# Remove item 
print (qObj.dequeue())

 

Singly Linked List class implementation

Implement basic skeleton for a Singly Linked List Example:

# Added node
a = LinkedListNode(1)
b = LinkedListNode(2)
c = LinkedListNode(3)        
# Set the pointers
a.nextnode = bb.nextnode = c
print (a.value)
print (b.value)
print (c.value)
# Print using class 
print (a.nextnode.value)

Doubly Linked List class implementation

Implement basic skeleton for a Doubly Linked List Example:


# Added node
a = DoublyLinkedListNode(1)
b = DoublyLinkedListNode(2)
c = DoublyLinkedListNode(3)        
# Set the pointers
# setting b after a (a before b)
b.prev_node = a
a.next_node = b
# Setting c after a
b.next_node = c
c.prev_node = b
print (a.value)
print (b.value)
print (c.value)
# Print using class 
print (a.next_node.value)
print (b.next_node.value)
print (b.prev_node.value)
print (c.prev_node.value)

 

Reverse a linked list implementation

The aim is to write a function to reverse a Linked List in place. The function will take in the head of the list as input and return the new head of the list. Example:


# Create a Linked List 
a = LinkedListNode(1)
b = LinkedListNode(2)
c = LinkedListNode(3)
d = LinkedListNode(4)
a.nextnode = b
b.nextnode = c
c.nextnode = d
print (a.nextnode.value)
print (b.nextnode.value)
print (c.nextnode.value)
# Call the reverse()
LinkedListNode().reverse(a)
print (d.nextnode.value)
print (c.nextnode.value)
print (b.nextnode.value)

 

Linked list Nth to the last node

The aim is a function that takes a head node and an integer value n and then returns the nth to last node in the linked list. Example:


# Create a Linked List 
a = LinkedListNode(1)
b = LinkedListNode(2)
c = LinkedListNode(3)
d = LinkedListNode(4)
e = LinkedListNode(5)

a.nextnode = b
b.nextnode = c
c.nextnode = d
d.nextnode = e

print (a.nextnode.value)
print (b.nextnode.value)
print (c.nextnode.value)
print (d.nextnode.value)

# This would return the node d with a value of 4, because its the 2nd to last node.
target_node = LinkedListNode().nth_to_last_node(2, a) 
print (target_node.value)
# Ans: d=4


Check GitHub for the full working code.

I will keep adding more problems/solutions.

Stay tuned!

Ref:  The inspiration of implementing DS in Python is from this course

Implemeting Data Structures and Algorithms in Python: Problems and solutions

Recently I have started using Python in a lot of places including writing algorithms for MI/data science,  so I thought to try to implement some common programming problems using data structures in Python. As I have mostly implemented in C/C++ and Perl.

Let’s get started with a very basic problem.

Anagram algorithm

An algorithm will take two strings and check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters, in other words, rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once

Some examples of anagram:
“dormitory” is an anagram of “dirty room”
“a perfectionist” is an anagram of “I often practice.”
“action man” is an anagram of “cannot aim”

Our anagram check algorithm with take two strings and will give a boolean TRUE/FALSE depends on anagram found or not?
I have used two approaches to solve the problem. First is to sorted function and compare two string after removing white spaces and changing to lower case. This is straightforward.

like


def anagram(str1,str2):
# First we'll remove white spaces and also convert string to lower case letters
str1 = str1.replace(' ','').lower()
str2 = str2.replace(' ','').lower()
# We'll show output in the form of boolean TRUE/FALSE for the sorted match hence return
return sorted(str1) == sorted(str2)

The second approach is to do things manually, this is because to learn more about making logic to check. In this approach, I have used a counting mechanism and Python dictionary to store the count letter. Though one can use inbuilt Python collections idea is to learn a bit about the hash table.

Check GitHub for the full working code.

I will keep adding more problems/solutions.

Stay tuned!

Ref:  The inspiration of implementing DS in Python is from this course

Choropleth Maps in Python

Choropleth maps are a great way to represent geographical data. I have done a basic implementation of two different data sets. I have used jupyter notebook to show the plots.

World Power Consumption 2014

First do Plotly imports

import plotly.graph_objs as go
from plotly.offline import init_notebook_mode,iplot
init_notebook_mode(connected=True)

Next step is to fetch the dataset, we’ll use Python pandas library to read the read the csv file

import pandas as pd
df = pd.read_csv('2014_World_Power_Consumption')

Next, we need to create data and layout variable which contains a dict

data = dict(type='choropleth',
locations = df['Country'],
locationmode = 'country names', z = df['Power Consumption KWH'],
text = df['Country'], colorbar = {'title':'Power Consumption KWH'},
colorscale = 'Viridis', reversescale = True)

Let’s make a layout

layout = dict(title='2014 World Power Consumption',
geo = dict(showframe=False,projection={'type':'Mercator'}))

Pass the data and layout and plot using iplot

choromap = go.Figure(data = [data],layout = layout)
iplot(choromap,validate=False)

The output will be be like below:

Check github for full code.

In next post I will try to make a choropleth for a different data set.

 References: 

https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp

      https://plot.ly/python/choropleth-maps/