Jump to content

User:Jimmy Novik/Python

From Wikipedia, the free encyclopedia

Python Code Snippets

Past Experience

[edit]

Remote Patient Monitoring at Covidien/Medtronic

[edit]
  • .NET MVC Framework
  • WebServices Access via Web Bridge Library Responsible for Abstraction of Web Services
  • Asynchronous Data Display via AJAX

Big-Data: Cashtag-CU

[edit]
  • EC2 Elastic Cloud
  • Node.js
    • V8 Engine
    • Non-blocking Event Queue/Loop
    • JavaScript
    • NPM Manager + Easy Command Line Tools
    • Express Server
    • MongoDB Driver
  • Webgl Libraries (Three.js, Tween.js)
  • MongoDB
    • Document Based
    • Scalable

BigO Complexity

[edit]

Data Structures

[edit]
Access (Time, Average) Search Insertion Deletion Access (Time, Worst) Search Insertion Deletion Space Complexity (Worst)
Array O(1) O(n) O(n) O(n) O(1) O(n) O(n) O(n) O(n)

Graph Operations

[edit]
Node / Edge Management Storage Add Vertex Add Edge Remove Vertex Remove Edge Query
Adjacency List V|+|E|) O(1) O(1) V|+|E|) E|) V|)
Incidence List V|+|E|) O(1) O(1) E|) E|) E|)
Adjacency Matrix V|^2) V|^2) O(1) V|^2) 1|) 1|)
Incidence Matrix V|*|E|) V|*|E|) V|*|E|) V|*|E|) V|*|E|) E|)

Clever Tricks in Python

[edit]

Generating a Dictionary with Keys Set to Alphabetic Characters

[edit]
import string
d = dict.fromkeys(string.ascii_lowercase, 0)

Flattening Lists

[edit]
>>> a = [[1, 2], [3, 4], [5, 6]]
>>> list(itertools.chain.from_iterable(a))
[1, 2, 3, 4, 5, 6]

Iterating over Dictionary Key and Value Pairs

[edit]
>>> m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> for k, v in m.iteritems():
...     print '{}: {}'.format(k, v)

System Design

[edit]

GFS

[edit]

Map Reduce

[edit]

What

  • Programming Model

Why

  • To Process & Generate Large Data Sets *

Key Terms

  • Map Function
(k1, v1) -> list(k2, v2)
  • Reduce Function
(k2, list(v2)) -> list(v2)
  • reduce hash (hash(key)modR)
  • input split (64MB)
  • Master (Chooses Workers)
    • Master Knows What Tasks Have to be Done the Workers at any Time
    • Checkpoints
    • Partitioning Function
  • Worker (Parses and Buffers)
  • Atomic Commits
  • Stragglers
  • Ordering Guarantee
  • Combiner Function (Combines Intermediate Keys)
  • Local Execution
  • Status Info

Sorting

[edit]

Bubble Sort

[edit]
def bubbleSort(array):
    for i in range(len(array)-2, 0, -1):
        for j in range(i+1):
            if array[j+1] < array[j]:
                temp = array[j+1]
                array[j+1] = array[j]
                array[j] = temp

Insertion Sort

[edit]
import random

def insertionSort(array):
    for j in range(1, len(array)):
        key = array[j]
        i = j-1
        while i>-1 and array[i]>key:
            array[i+1] = array[i]
            i -= 1
        array[i+1]=key
    

Heapsort

[edit]

CLRS VERSION

[edit]
import math

## NOTE TO SELF:
## What makes this implementation difficult, is
## that it you have to pay attention to indices.
## To find children and parents you have to mutiply and devide,
## and to make sure that you are not multiplying 0 by 2 (which
## gives 0) you have to watch for indices...

class MaxHeap:
    def __init__(self, array):
        self.array = array
        self.heapsize = len(array)

    def buildMaxHeap(self):
        for i in range(len(self.array), 0, -1):
            self.maxHeapify(i)
            
    def heapsort(self):
        self.buildMaxHeap()
        for i in range(len(self.array), 1, -1):
            self.swap(1, i)
            self.heapsize = self.heapsize - 1
            self.maxHeapify(1)
            
    def maxHeapify(self, i):
        l = self.left(i)
        r = self.right(i)

        if l <= self.heapsize and self.array[l-1] > self.array[i-1]:
            largest = l
        else:
            largest = i
            
        if r <= self.heapsize and self.array[r-1] > self.array[i-1]:
            if self.array[r-1] > self.array[largest-1]:
                largest = r

        if largest != i:
            self.swap(largest, i)
            self.maxHeapify(largest)

    ## PRIORITY QUEUE

    def heapMaximum(self):
        self.heapsort()
        return self.array[0]

    def heapExtractMax(self):
        if self.heapsize < 1:
            return "Error: Heap Underflow"
        maxVar = self.array[0]
        self.array[0] = self.array[self.heapsize-1]
        self.heapsize = self.heapsize - 1
        self.maxHeapify(1)
        return maxVar
        
    def heapIncreaseKey(self, i, key):
        if key < self.array[i-1]:
            print("Error: new key is smaller than current key")
        self.array[i-1] = key
        while i > 1 and self.array[self.parrent(i)-1] < self.array[i]:
            self.swap(i, self.parent(i))
            i = self.parent(i)

    def maxHeapInsert(self, key):
        self.heapsize = self.heapsize + 1
        self.array[self.heapsize] = -100000
        self.heapIncreaseKey(self, self.heapsize, key)
        
    ## AUXILARY        

    def parent(self, i):
        return math.floor(i/2)

    def left(self, i):
        return 2*i

    def right(self, i):
        return 2*i + 1

    def swap(self, i, j):
        temp = self.array[i-1]
        self.array[i-1] = self.array[j-1]
        self.array[j-1] = temp

mh = MaxHeap([4, 1, 3, 2, 16, 9, 10, 14, 8, 7])
mh.buildMaxHeap()
print(mh.array)

Other Version

[edit]
def HeapSort(A):
    def heapify(A):
        start = (len(A) - 2) / 2
        while start >= 0:
            siftDown(A, start, len(A) - 1)
            start -= 1

    def siftDown(A, start, end):
        root = start
        while root * 2 + 1 <= end:
            child = root * 2 + 1
            if child + 1 <= end and A[child] < A[child + 1]:
                child += 1
            if child <= end and A[root] < A[child]:
                A[root], A[child] = A[child], A[root]
                root = child
            else:
                return

    heapify(A)
    end = len(A) - 1
    while end > 0:
        A[end], A[0] = A[0], A[end]
        siftDown(A, 0, end - 1)
        end -= 1

if __name__ == '__main__':
    
    T = [13, 14, 94, 33, 82, 25, 59, 94, 65, 23, 45, 27, 73, 25, 39, 10] 

    HeapSort(T)
    print(T)

Quicksort

[edit]
import random

list_to_sort = [x for x in range(10000)]
random.shuffle(list_to_sort)

class quickSort:
    def __init__(self, list_to_sort):
        self.list = list_to_sort;

    def swap(self, index01, index02):
        temp = self.list[index01]
        self.list[index01] = self.list[index02]
        self.list[index02] = temp

    def sort(self, wall, pivot):
        new_wall, pointer = wall, wall

        if (pivot - wall <= 0): return

        while (pivot != pointer):
            if (self.list[pointer] >= self.list[pivot]):
                pointer += 1
            else:
                self.swap(new_wall, pointer)
                new_wall = new_wall + 1
                pointer += 1

        self.swap(new_wall, pivot)
        self.sort(wall, new_wall-1)
        self.sort(new_wall+1, pivot)
        return

print("Before:", list_to_sort)
quickSort = quickSort(list_to_sort)
quickSort.sort(0, len(list_to_sort)-1)
print("After:", quickSort.list)

Merge Sort

[edit]
def mergeSort(alist):
    print("Splitting ",alist)
    if len(alist)>1:
        mid = len(alist)//2
        lefthalf = alist[:mid]
        righthalf = alist[mid:]

        mergeSort(lefthalf)
        mergeSort(righthalf)

        i=0
        j=0
        k=0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                alist[k]=lefthalf[i]
                i=i+1
            else:
                alist[k]=righthalf[j]
                j=j+1
            k=k+1

        while i < len(lefthalf):
            alist[k]=lefthalf[i]
            i=i+1
            k=k+1

        while j < len(righthalf):
            alist[k]=righthalf[j]
            j=j+1
            k=k+1
    print("Merging ",alist)

alist = [54,26,93,17,77,31,44,55,20]
mergeSort(alist)
print(alist)

Hashtables

[edit]

Open Adressing

[edit]
hashTable = {1:[], 2:[], 3:[], 4:[], 5:[], 6:[], 7:[], 8:[], 9:[]}

def openAddressing(hashTable, value):
    key = value % len(hashTable)
    memo = key
    while(len(hashTable[key]) != 0):
        key = (key + 1) % len(hashTable)
        print(key)
    if (len(hashTable[key]) == 0):
        hashTable[key].append(value)
        return hashTable
    else:
        return hashTable

print(openAddressing(openAddressing(hashTable, 9), 8))

Trees

[edit]

AVL Tree

[edit]

Height Balanced Tree https://www.youtube.com/watch?v=YKt1kquKScY

Binary Tree

[edit]
  • Preorder Traversal

Pre-order: F, B, A, D, C, E, G, I, H

  • Inorder Traversal

In-order: A, B, C, D, E, F, G, H, I

  • Postorder Traversal

Post-order: A, C, E, D, B, H, I, G, F

  • Level Traversal

Level-order: F, B, G, A, D, I, C, E, H


from collections import namedtuple

from sys import stdout


Node = namedtuple('Node', "data, left, right")

tree = Node(1,

            Node(2,

                 Node(4,

                      Node(7, None, None),

                      None),

                 Node(5, None, None)),

            Node(3,

                 Node(6,

                      Node(8, None, None),

                      Node(9, None, None)),

                 None))


def printwithspace(i):

    stdout.write("%i " % i)


def preorder(node , visitor = printwithspace):

    if node is not None:

        visitor(node.data)

        preorder(node.left, visitor)

        preorder(node.right, visitor)

preorder(tree)

N-ary Tree

[edit]

In graph theory, a k-ary tree is a rooted tree in which each node has no more than k children. It is also sometimes known as a k-way tree, an N-ary tree, or an M-ary tree. A binary tree is the special case where k=2.

Red-Black Tree

[edit]

Rules

  1. A node is either red or black
  2. The root is black
  3. All leaves (NIL) are black
  4. Every red node must have two black child nodes, and therefore it must have a black parent
  5. Every path from a given node to any of its descendant NIL nodes contains the same number of black nodes

Trie

[edit]

A trie for keys "A", "to", "tea", "ted", "ten", "i", "in", and "inn".

Graphs

[edit]

CLRS Style

[edit]
class Vertex:
    def __init__(self, name):
        self.name = name
        self.edges = []
        self.color = "white"
        self.distance = 100000
        self.predecessor = None
        self.d = 0
        self.f = 0
        
    def createEdge(self, vertex):
        if vertex not in self.edges:
            self.edges.append(vertex)

class Graph:
    def __init__(self, graph):
        self.graph = graph
        self.time = 0

    def DFS(self):
        for u in self.graph:
            u.color = "white"
            u.predecessor = None
        time = 0
        for u in self.graph:
            if u.color == "white":
                self.dfsVisit(u)

    def dfsVisit(self, u):
        self.time = self.time + 1
        u.d = self.time
        u.color = "gray"
        for v in u.edges:
            if v.color == "white":
                v.predecessor = u
                self.dfsVisit(v)
        u.color = "black"
        self.time = self.time + 1
        u.f = self.time
            

    def BFS(self):
        s = self.graph[0]
        s.color = "gray"
        s.distance = 0
        s.predecessor = None
        q = [s]
        print(s.name)
        while len(q) != 0:
            u = q.pop(0)
            for vertex in u.edges: 
                if vertex.color=="white":
                    print(vertex.name, vertex.color)
                    vertex.color="gray"
                    vertex.distance=u.distance + 1
                    vertex.predecessor=u
                    q.append(vertex)
                    
            u.color = "black"
                
                        


a = Vertex("A")
b = Vertex("B")
c = Vertex("C")
d = Vertex("D")
a.createEdge(b)
a.createEdge(c)
b.createEdge(c)
c.createEdge(d)
d.createEdge(c)
graph = [a, b, c, d]
g = Graph(graph)
g.DFS()
for i in graph:
    print(i.d, i.f)

Strongly Connected Component

[edit]

The most important thing here to remember is that second time you do DFS on the graph, you have to visit vertices in order of their finish times.

def sccDFS(self):
        components = []
        for u in self.graph:
            u.color = "white"
            u.predecessor = None
        time = 0
        for u in self.graph:
            if u.color == "white":
                component = self.sccDfsVisit(u, [u.name])
                components.append(component)
        return components
            
    def sccDfsVisit(self, u, scc):
        result = scc
        self.time = self.time + 1
        u.d = self.time
        u.color = "gray"
        for v in u.edges:
            if v.color == "white":
                v.predecessor = u
                result = self.sccDfsVisit(v, scc + [v.name])
        u.color = "black"
        self.time = self.time + 1
        u.f = self.time
        return result

Graph as a Dictionary

[edit]
from collections import namedtuple
from sys import stdout

graph = {'A': ['B', 'C'],\
         'B': ['C', 'D'],\
         'C': ['D'],\
         'D': ['C'],\
         'E': ['F'],\
         'F': ['C']}

def find_path(graph, start, end, path=[]):

    path = path + [start]

    if start == end:
        return path
    if not start in graph:
        return None
    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph, node, end, path)
            if newpath: return newpath
    return None

print(find_path(graph, 'F', 'C', []))

def bfs(graph, start_node):
    seen = {}
    queue = []
    queue.append(start_node)
    seen[start_node] = True
    while (len(queue) != 0):
        i = queue.pop(0)
        print(i)
        for j in graph[i]:
            if j not in seen:
                queue.append(j)
                seen[j] = True
    return seen

print("BFS: ", bfs(graph, 'A'))

def dfs(graph, start_node):
    seen = {}
    stack = []
    stack.append(start_node)
    seen[start_node] = True
    while (len(stack) != 0):
        i = stack.pop(-1)
        print(i)
        for j in graph[i]:
            if j not in seen:
                stack.append(j)
                seen[j] = True
    return seen

print("DFS: ", dfs(graph, 'A'))

Graph as a Matrix

[edit]
graph_matrix = [\
    #A  B  C  D  E  F
    [0, 1, 1, 0, 0, 0],\
    [0, 0, 1, 1, 0, 0],\
    [0, 0, 0, 1, 0, 0],\
    [0, 0, 1, 0, 0, 0],\
    [0, 0, 0, 0, 0, 1],\
    [0, 0, 1, 0, 0, 0],\
]

class graphMatrix:
    def __init__(self, graph_matrix):
        self.matrix = graph_matrix
        self.seen = {0: False, 1: False, 2: False, 3: False, 4: False, 5: False}
        self.stack = []

    def dfs(self, start_node_index):
        self.stack = []
        self.seen[start_node_index] = True
        self.stack.append(start_node_index)
        while(len(self.stack) != 0):
            temp_element = self.stack.pop()
            for node in range(0, 6):
                print(node)
                if (self.matrix[temp_element][node] == 1 and self.seen[node] == False):
                    self.seen[node] = True
                    self.stack.append(node)
            print(self.seen)
            print(self.stack)
        return

graphMatrix = graphMatrix(graph_matrix)
graphMatrix.dfs(0)
print(graphMatrix.seen)

Queue

[edit]
class Queue:
    def __init__(self):
        self.items = []
        self.minimumValue = float("inf")

    def isEmpty(self):
        return (self.items == [])

    def enqueue (self, item):
        self.items.insert(0, item)
        if (item < self.minimumValue):
            self.minimumValue = item

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

Bellman-Ford Single Source Shortest Path

[edit]
def initializeSingleSource(G, s)
    for vertex in G.vertices:
        vertex.d = float("inf")
        vertex.p = None
    s.d = 0

def BellmanFord(G, w, s)
    initializeSingleSource(G, s)
    for vertex in G.vertices:
        for edge in G.edges:
            relax(u, v, w)
    for edge in G.edges:
        if edge[v].d > edge[u].d + edge.w
            return False
    return True

Dijkstra Non-Negative Edges Single Source Shortest Path

[edit]
def Dijkstra(G,w,s):
    initializeSingleSource(G,s)
    S = []
    Q = G.vertices
    while len(Q) != 0:
        u = extractMin(Q)
        S = S + [u]
        for vertex v in G.adj[u]:
            relax(u, v, w)

NP-Completeness

[edit]

Categories

[edit]

NP-hard problems do not have to be elements of the complexity class NP. As NP plays a central role in computational complexity, it is used as the basis of several classes:

NP
Class of computational problems for which a given solution can be verified as a solution in polynomial time by a deterministic Turing machine.
NP-hard
Class of problems which are at least as hard as the hardest problems in NP. Problems that are NP-hard do not have to be elements of NP; indeed, they may not even be decidable.
NP-complete
Class of problems which contains the hardest problems in NP. Each NP-complete problem has to be in NP.
NP-easy
At most as hard as NP, but not necessarily in NP, since they may not be decision problems.
NP-equivalent
Problems that are both NP-hard and NP-easy, but not necessarily in NP, since they may not be decision problems.
NP-intermediate
If P and NP are different, then there exist problems in the region of NP that fall between P and the NP-complete problems. (If P and NP are the same class, then NP-intermediate problems do not exist.)

Traveling Salesman

[edit]

Knapsack

[edit]

Sudoku

[edit]

Mathematics

[edit]

Operating Systems

[edit]

Locks

[edit]

Used when the same resource can be accessed from several places, use synchronized otherwise

import asyncio

async def coro(name, lock):
    print('coro {}: waiting for lock'.format(name))
    async with lock:
        print('coro {}: holding the lock'.format(name))
        await asyncio.sleep(1)
        print('coro {}: releasing the lock'.format(name))

loop = asyncio.get_event_loop()
lock = asyncio.Lock()
coros = asyncio.gather(coro(1, lock), coro(2, lock))
try:
    loop.run_until_complete(coros)
finally:
    loop.close()

Mutexes

[edit]

Semaphores

[edit]
  • Mutex Semaphore (Lock)
  • Counting Semaphore (lets several threads access same resource)
  • Event Semaphores (notifies all waiting threads)

Monitors

[edit]

Set of routines protected by a mutual exclusion lock that handle all the details of lock acquisition and release

Deadlock

[edit]

Conditions

  • Mutual Exclusion
  • Hold and Wait
  • No Preemption
  • Circular Wait

Databases

[edit]

Dynamic Programming

[edit]

Listing Elements in Binary Tree Fashion

[edit]
import math

class List:
    def __init__(self):
        self.array = [1, 2, 3, 4, 5, 6, 7]
    def traverse(self):
        self.traverse_helper(0, len(self.array)-1)
    def traverse_helper(self, start, end):
        array = self.array[start:end+1]
        middle = math.floor(len(array)/2)

        #base cases
        if len(array) == 0:
            return
        elif len(array) == 1:
            print(array[0])
            return
        
        #recursion
        else:
            for i in range(1):
                self.traverse_helper(start+middle, end)
                self.traverse_helper(start, start+middle-1)     

        
l = List()
l.traverse()

[edit]
import math

class BinarySearch:
    def __init__(self):
        self.array = [1, 2, 3, 4, 5, 6, 7, 8]

    def search(self, value):
        print(self.search_helper(value, 0, len(self.array)-1));

    def search_helper(self, value, start, end):
        array = self.array[start:end+1]
        middle = math.floor(len(array)/2)
        
        #base cases: *** don't forget the case where you have one element and it is not what you are looking for!
        if len(array) == 0:
            return False;
        if array[middle] == value:
            return True
        if len(array) == 1 and array[0] == value:
            return True
        elif len(array) == 1 and array[0] != value:
            return False

        #recursion
        else:
            if (value < array[middle]):
                return self.search_helper(value, start, start+middle-1) #start + middle super easy to forget! 
            elif (value > array[middle]):
                return self.search_helper(value, start+middle, end)
            else:
                return False

All Subsets of a Set

[edit]

Note to Self!

[edit]

When thinking about how to solve a problem using dynamic programming think about what solution your function is going to produce, and use those solutions as your base cases. For example, in this problem you are looking at a set with no elements, which will give you []... then you look at a set with a1 element, which will give you [[], [a1], then you look add another one (a2), which will give you [[]. [a1], [a2], [a1, a2]]. It is easy to see a pattern here. But if you look let say at only one solution with three elements and thinking "ok, I have to combine first element with another one, and it will give me..." it will not get you anywhere...

class SetBuilder:
    def __init__(self, array):
        self.array = array

    def findAllSubsets(self):
        result = self.findAllSubsetsHelper(0, [])
        print(len(result), result)
        
    def findAllSubsetsHelper(self, index, results):
        if index == len(self.array)+1:
            return results
        else:
            if len(results) == 0:
                results.append([])
            else:
                temp_results = results[:]
                for subset in temp_results:
                    new_subset = subset[:]
                    new_subset.append(self.array[index-1])
                    results.append(new_subset)
        return self.findAllSubsetsHelper(index+1, results)

sb = SetBuilder(["a", "dog", "cat"])
sb.findAllSubsets()

All Possible Permutations

[edit]
deg getPerms(str):
  print(str)
  
  if (str == None):
    return None
  
  if str == "":
    permutations.append("")
    return permutations
  
  first = str[0]
  words = getPerms(str[1:])
  for word in words:
  for j in range(len(word) + 1):
      s = insertCharAt (word, first, j)
      permutations.append(s)
  return permutations

All Legitimate Parentheses Permutations

[edit]
def addParen(list_input, left_remaining, right_remaining, string_input, count):
    if left_remaining < 0 or left_remaining > right_remaining:
        return
    if left_remaining == 0 and right_remaining == 0:
        print(string_input)
    else:

        string_input[count:count+1] = b"("
        addParen(list_input, left_remaining - 1, right_remaining, string_input, count + 1)

        string_input[count:count+1] = b")"
        addParen(list_input, left_remaining, right_remaining - 1, string_input, count + 1)
    
    test_list = [];
    num = 3
    addParen(test_list, num, num, bytearray((b""*num)), 0)
    print(test_list)

8 Queens

[edit]

Note to Self: Don't Return if You are Iterating withing a Recursive Function, and if You Want to Return a Result Array, Don't Append Arrays to It, Append Strings!

import math

def placeQueens(row, columns, results): 
    if (row == 8):
        results.append(columns)
        print(results)
    else:
        for col in range(8):
            if (checkValid(columns, row, col)):
                columns[row] = col;
                placeQueens(row + 1, columns, results)
                columns[row] = -1

def checkValid(columns, row1, column1):
    for row2 in range(row1):
        column2 = columns[row2]
        if column1 == column2:
            return False
        columnDistance = abs(column2 - column1)
        rowDistance = row1-row2
        if columnDistance == rowDistance:
            return False
    return True

placeQueens(0, [-1, -1, -1, -1, -1, -1, -1, -1], [])
    

Binary Representation

[edit]

Iterate Through Every Bit

[edit]
number = 19

num_bits = 8
bits = [(number >> bit) & 1 for bit in range(num_bits - 1, -1, -1)]

OO Design and Design Patterns

[edit]

S.O.L.I.D.

[edit]
Initial Stands for
(acronym)
Concept
S SRP [1]
Single responsibility principle
a class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class)
O OCP [2]
Open/closed principle
“software entities … should be open for extension, but closed for modification.”
L LSP [3]
Liskov substitution principle
“objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.” See also design by contract.
I ISP [4]
Interface segregation principle
“many client-specific interfaces are better than one general-purpose interface.”[5]
D DIP [6]
Dependency inversion principle
one should “Depend upon Abstractions. Do not depend upon concretions.”[5]

Singleton

[edit]
class Singleton:
    def __init__(self):
        self.firstInstance = None;

    def getInstance(self):
        if (self.firstInstance == None):
            self.firstInstance = Singleton() #lazy instantiation
        return self.firstInstance


s = Singleton()
print(s.getInstance())

Factory

[edit]
# returns on of several possible classes
# that share a common super class (create an enemy in a game)
# (When you don't know ahed of time what class object you need)
class EnemyShip:
    def __init__(self):
        self.name = ""
        self.amtDamage = 0

    def getName(self):
        print(self.name)
        return self.name

    def setName(self, newname):
        self.name = newname

class UFOEnemyShip(EnemyShip):
    def __init__(self):
        self.setName("UFO Enemy Ship")

class RocketEnemyShip(EnemyShip):
    def __init__(self):
        self.setName("Rocket Enemy Ship")

class EnemyShipFactory:
    def __init__(self):
        self.object = None
    def makeEnemyShip(self, shipType):
        if "u" in shipType or "U" in shipType:
            return UFOEnemyShip()
        elif "r" in shipType or "R" in shipType:
            return RocketEnemyShip()
        return None

ufoShipFactory = EnemyShipFactory()
test = ufoShipFactory.makeEnemyShip("u")
test.getName()

Iterator

[edit]
class SongInfo:
    def __init__(self, songName, bandName, year):
        self.songName = songName
        self.bandName = bandName
        self.year = year

    def getSongName(self):
        return self.songName

    def getBandName(self):
        return self.bandName

    def getYearReleased():
        return self.year

class songsOfThe70s:
    def __init__(self):
        self.bestSongs = []
        self.addSong("Imagine", "John Lennon", 1971)
        self.addSong("American Pie", "Don McLean", 1971)
        self.addSong("I Will Survive", "Gloria Gaynor", 1979)
    def addSong(self, songName, bandName, yearReleased):
        songInfo = SongInfo(songName, bandName, yearReleased)
        self.bestSongs.append(songInfo)
    def getBestSongs(self):
        return self.bestSongs

class songsOfThe80s:
    def __init__(self):
        self.bestSongs = {}
        self.addSong("Imagine2", "John Lennon", 1971)
        self.addSong("American Pie2", "Don McLean", 1971)
        self.addSong("I Will Survive2", "Gloria Gaynor", 1979)
    def addSong(self, songName, bandName, yearReleased):
        songInfo = SongInfo(songName, bandName, yearReleased)
        self.bestSongs[songName] = songInfo
    def getBestSongs(self):
        return self.bestSongs

class DJ:
    def __init__(self, array, hash):
        self.songs70 = array
        self.songs80 = hash

    def showSongs(self):
        #itterate through these datatypes accordingly
        

s = songsOfThe70s()
for i in s.getBestSongs():
    print(i.songName)

Observer

[edit]
# Itterator is needed when many objects need
# to receive info about a change

class Subject:
    def __init__(self, ibm, apple, google):
        self.observers = []
        self.ibm = ibm
        self.apple = apple
        self.google = google
        
    def register(self, observer):
        self.observers.append(observer)
        print("Observer " + str(len(self.observers)-1) + " was added")

    def unregister(self, observer):
        print("Observer " + str(self.observers.index(observer)) + " was removed")
        self.observers.remove(observer)

    def notifyObserver(self):
        for observer in self.observers:
            observer.update(self.ibm, self.apple, self.google)

    def setIBMPrice(self, ibm):
        self.ibm = ibm
        self.notifyObserver()

    def setApplePrice(self, apple):
        self.apple = apple
        self.notifyObserver()

    def setGooglePrice(self, google):
        self.google = google
        self.notifyObserver()

class Observer:
    def __init__(self):
        self.ibm = 0
        self.apple = 0
        self.google = 0
        
    def update(self, ibm, apple, google):
        self.ibm = ibm
        self.apple = apple
        self.google = google
        print("Updated: ", ibm, apple, google)

observer01 = Observer()
observer02 = Observer()
observer03 = Observer()
subject = Subject(100, 200, 300)
subject.register(observer01)
subject.register(observer02)
subject.register(observer03)
subject.setIBMPrice(1000)
subject.setGooglePrice(99999)

Decorator

[edit]
# Decorator is more flexible than inheritence
# Allows to modify objects dynamically

class Pizza:
    def __init__(self, name, cost):
        self.name = name
        self.cost = cost
        
    def getDescription(self):
        return self.name

    def getCost(self):
        return self.cost

class ToppingDecorator:
    def __init__(self, pizza):
        self.tempPizza = pizza

    def getDescription(self):
        return self.tempPizza.getName()

    def getCost(self):
        return self.tempPizza.getCost()

class Mozzarella(ToppingDecorator):
    def __init__(self, pizza):
        self.tempPizza = pizza
        print("Adding Dough", "Adding Mozzarella")

    def getDescription(self):
        return self.tempPizza.getDescription() + ", Mozzarella"

    def getCost(self):
        return self.tempPizza.getCost() + 10

class TomatoSauce(ToppingDecorator):
    def __init__(self, pizza):
        self.tempPizza = pizza
        print("Adding Tomato Sauce")

    def getDescription(self):
        return self.tempPizza.getDescription() + ", Tomato Sauce"

    def getCost(self):
        return self.tempPizza.getCost() + 20

pi = TomatoSauce(Mozzarella(Pizza("Cheese", 5)))
print(pi.getDescription())

Programming Questions

[edit]

Basics

[edit]

What are the types in C, Java, C++, Perl? How many bits does it take to represent the basic types?

[edit]
  • C
    • short int: 16 bits
    • unsigned short int: 16 bits
    • unsigned int: 32 bits
    • int: 32 bits
    • long int: 32 bits
    • signed char: 8 bits
    • unsigned char: 8 bits
    • float: 32 bits
    • double: 64 bits
    • long double: 128 bits
  • Java
    • byte
    • short
    • int
    • long
    • float
    • double
    • boolean
    • char
    • reference
    • literal
  • Python
    • integers
    • float
    • strings
    • tuples
    • lists
    • dictionaries

What do floating point numbers look in memory? Specifically, how many bits are there in a double and what sequence to the bits appear in?

[edit]
  • Sign Bit: 1
  • Exponent: 8/11
  • Mantissa: 23/52

What is two's complement notation?

[edit]

Way of representing negative and positive numbers in bits.

How would you implement a bit-vector class?

[edit]

?

Does the check x == x + 1 always return false for integer x?

[edit]

No, in the left associative languages it would return True

What dose a C struct look like in memory? What does a C++ object look like in memory? What does a Java object look like in memory?

[edit]

vtables and contiguous chunks of certain length

What is the difference between an interpreted and a compiled language?

[edit]

Compiled language gets translated directly into assembly code, but the interpreted languages are translated into precompiled bits of code.

What is garbage collection?

[edit]

Purge of Heap

How would you determine if call stack grows up or down relative to memory addresses?

[edit]

print address of vars in nested functions

Give an example of a memory leak in Java?

[edit]

?

What is tail recursion? How can it be removed automatically?

[edit]

Some languages recognize this and implement "proper tail calls" or "tail call elimination": if they see a recursive call in tail position, they actually compile it into a jump that reuses the current stack frame instead of calling the function normally.

Is the natural recursive program for computing n! tail recursive?

[edit]

Yes

Is Python 10x Faster than C?

[edit]

No. Interpreted high level languages are slower because there a lot of stuff on top of assembly.

What does an executable look like as a sequence of bytes?

[edit]

"Assembly" instructions.

Libraries

[edit]

Give an example of a function that is in the C standard library

[edit]
  • printf()
  • scanf()
  • cos(), sin()....

Testing

[edit]

What was you last bug? What was your hardest bug?

[edit]

My last bug: Lorenz Attractor implementation. Hardest bug: patient data won't be displayed in a web app because of the device internal id is not unique...

How would you debug a distributed program?

[edit]

Make a designated book-keeper of states of variables (like a master node)

Program Works sometimes, but fails other times on the same input? Why?

[edit]

This could be due to program using probabilistic functions or because of hardware issues, or possibly interference from other processes etc.

How would you determine where the program spends most of its time?

[edit]

Use a profiler

Best Practices

[edit]

Give an example of how inheritence violates encapsulation

[edit]

Programming Language Implementation

[edit]

Give an example of a language which cannot be parsed by any computer

[edit]

English because it is ambiguous!

What problems does dynamic linkage solve? What problems does it introduce?

[edit]

It prevents you from recompiling the whole program if the only thing you changed is a small function

What is a functional language?

[edit]

Programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.

What is a virtual function?

[edit]

Function that is redefined in derived classes.

What is automatic garbage collection and how is it implemented?

[edit]

reference counters (each allocated region knows how many references there are to it and is freed when 0), sweep algorithms (traversal of a directed graph)

What is a type-sage language?

[edit]

"Well typed programs cannot go wrong." Robin Milner 1978. Meaningless programs won't run (C and C++ are not type safe, Java and C# are)

What is the difference between a lexer and parser?

[edit]
  • Lexer: lexical analysis (characters to tokens)
  • Parser: semantics (tokens into statements)

Operating Systems

[edit]

What is a system call?

[edit]

Request of a service from an operating system's kernel by a program.

How is a system call different from a library call?

[edit]

system calls - kernel; library calls - application;

What is a device driver?

[edit]

Program that provides interface between a device and application/operating system.

What is livelock? What is deadlock? Examples

[edit]

A livelock is similar to a deadlock, except that the states of the processes involved in the livelock constantly change with regard to one another, none progressing. Livelock is a special case of resource starvation; the general definition only states that a specific process is not progressing.

A real-world example of livelock occurs when two people meet in a narrow corridor, and each tries to be polite by moving aside to let the other pass, but they end up swaying from side to side without making any progress because they both repeatedly move the same way at the same time.

Livelock is a risk with some algorithms that detect and recover from deadlock. If more than one process takes action, the deadlock detection algorithm can be repeatedly triggered. This can be avoided by ensuring that only one process (chosen randomly or by priority) takes action.

What is a race condition? What can you do to prevent races?

[edit]

Race condition is when to threads try to modify same memory location. One has to either make code thread safe by mutual exclusion or not use threads at all.

Read from memory, disk, SSD

[edit]

Read 1 MB sequentially from disk 20,000,000 ns 20 ms 80x memory, 20X SSD

Computer Architecture

[edit]

What is pipelining? Describe a 5-stage pipeline

[edit]

Way of processor to execute instructions (Similar to the car pipline

What is a multi-issue processor

[edit]

Some machines now try to go beyond pipelining to execute more than one instruction at a clock cycle, producing an effective CPI < 1. This is possible if we duplicate some of the functional parts of the processor (e.g., have two ALUs or a register file with 4 read ports and 2 write ports),

What is the difference between a superscalar and VLIW processor? Where is each appropriate?

[edit]

?

What is a multicore machine?

[edit]

CPU Core (processing unit) and L1 Cache

What is the significance of the privileged bit?

[edit]

Kernel Mode/ User mode

Systems

[edit]

How does a web browser work? Autcompletion?

[edit]

Parsers for HTML and DOM construction

How does internet work? Specifically describe the roles of the TCP/IP protocol, routers, and DNS

[edit]

Routers connect local networks to other networks. DNS stores information about IPs associated with domain names. TCP/IP protocol is stateless. Has headers etc...

  1. ^ "Single Responsibility Principle" (PDF).
  2. ^ "Open/Closed Principle" (PDF).
  3. ^ "Liskov Substitution Principle" (PDF).
  4. ^ "Interface Segregation Principle" (PDF).
  5. ^ a b “Design Principles and Design Patterns”, Robert C. Martin (“Uncle Bob”), objectmentor.com. Last verified 2009-01-14.
  6. ^ "Dependency Inversion Principle" (PDF).