initial and final commit

This commit is contained in:
steinkirch 2013-09-10 04:14:02 -04:00
parent 4061fa6df1
commit 227a0efc0e
272 changed files with 11976 additions and 4 deletions

View File

@ -1,4 +0,0 @@
python_and_alg
==============
This repository contains a comprehensive study of Algorithms and Python, including an "ebook" that I wrote. In the folder /src/examples_in_my_book/, I made available all the examples and cases I used in my ebook. In the folder /futher_examples/ you can find all the solutions for the book Cracking the Code, and many examples from the websites Project Euler and Topcoder.

Binary file not shown.

View File

@ -0,0 +1,51 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
def find_N_largest_items_seq(seq, N):
''' find the N largest items in a sequence '''
return heapq.nlargest(N,seq)
def find_N_smallest_items_seq(seq, N):
''' find the N smallest items in a sequence '''
return heapq.nsmallest(N, seq)
def find_smallest_items_seq_heap(seq):
''' find the smallest items in a sequence using heapify first'''
''' heap[0] is always the smallest item '''
''' pops the smallest item, O(logN) '''
heapq.heapify(seq)
return heapq.heappop(seq)
def find_smallest_items_seq(seq):
''' if it is only one item, min() is faster '''
return min(seq)
def find_N_smallest_items_seq_sorted(seq, N):
''' N ~ len(seq), better sort instead'''
return sorted(seq)[:N]
def find_N_largest_items_seq_sorted(seq, N):
''' N ~ len(seq), better sort instead'''
return sorted(seq)[len(seq)-N:]
def test_find_N_largest_smallest_items_seq(module_name='this module'):
seq = [1, 3, 2, 8, 6, 10, 9]
N = 3
assert(find_N_largest_items_seq(seq, N) == [10, 9, 8])
assert(find_N_largest_items_seq_sorted(seq, N) == [8, 9, 10])
assert(find_N_smallest_items_seq(seq, N) == [1,2,3])
assert(find_N_smallest_items_seq_sorted(seq, N) == [1,2,3])
assert(find_smallest_items_seq(seq) == 1)
assert(find_smallest_items_seq_heap(seq) == 1)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_N_largest_smallest_items_seq()

View File

@ -0,0 +1,49 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Heapify(object):
def __init__(self, data=None):
self.data = data or []
for i in range(len(data)//2, -1, -1):
self.__max_heapify__(i)
def __repr__(self):
return '{}'.format(self.data)
def parent(self, i):
return i >> 1
def left_child(self, i):
return (i << 1) + 1
def right_child(self, i):
return (i << 1) + 2 # +2 instead of +1 because it's 0-indexed.
def __max_heapify__(self, i):
largest = i
left = self.left_child(i)
right = self.right_child(i)
n = len(self.data)
largest = (left < n and self.data[left] > self.data[i]) and left or i
largest = (right < n and self.data[right] > self.data[largest]) and right or largest
if i is not largest:
self.data[i], self.data[largest] = self.data[largest], self.data[i]
self.__max_heapify__(largest)
def extract_max(self):
n = len(self.data)
max_element = self.data[0]
self.data[0] = self.data[n - 1]
self.data = self.data[:n - 1]
self.__max_heapify__(0)
return max_element
def test_Heapify():
l1 = [3, 2, 5, 1, 7, 8, 2]
h = Heapify(l1)
assert(h.extract_max() == 8)
if __name__ == '__main__':
test_Heapify()

View File

@ -0,0 +1,50 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Heapify(object):
def __init__(self, data=None):
self.data = data or []
for i in range(len(data)//2, -1, -1):
self.__max_heapify__(i)
def __repr__(self):
return '{}'.format(self.data)
def parent(self, i):
return i >> 1
def left_child(self, i):
return (i << 1) + 1
def right_child(self, i):
return (i << 1) + 2 # +2 instead of +1 because it's 0-indexed.
def __max_heapify__(self, i):
largest = i
left = self.left_child(i)
right = self.right_child(i)
n = len(self.data)
largest = (left < n and self.data[left] > self.data[i]) and left or i
largest = (right < n and self.data[right] > self.data[largest]) and right or largest
if i is not largest:
self.data[i], self.data[largest] = self.data[largest], self.data[i]
self.__max_heapify__(largest)
def extract_max(self):
n = len(self.data)
max_element = self.data[0]
self.data[0] = self.data[n - 1]
self.data = self.data[:n - 1]
self.__max_heapify__(0)
return max_element
def test_Heapify():
l1 = [3, 2, 5, 1, 7, 8, 2]
h = Heapify(l1)
assert(h.extract_max() == 8)
print ("Tests Passed!")
if __name__ == '__main__':
test_Heapify()

View File

@ -0,0 +1,29 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
def merge_sorted_seq(seq1, seq2):
''' merge two sorted sequences with little ovehead. the result
will be sorted, which is different of doing just +'''
result = []
for c in heapq.merge(seq1, seq2):
result.append(c)
return result
def test_merge_sorted_seq(module_name='this module'):
seq1 = [1, 2, 3, 8, 9, 10]
seq2 = [2, 3, 4, 5, 6, 7, 9]
seq3 = seq1 + seq2
assert(merge_sorted_seqseq1, seq2) == sorted(seq3))
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_merge_sorted_seq()

View File

@ -0,0 +1,41 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
class PriorityQueue(object):
''' implements a priority queue class '''
def __init__(self):
self._queue = []
self._index = 0 # comparying same priority level
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item))
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]
class Item:
def __init__(self, name):
self.name = name
def __repr__(self):
return "Item({!r})".format(self.name)
def test_PriorityQueue():
''' push and pop are all O(logN) '''
q = PriorityQueue()
q.push(Item('test1'), 1)
q.push(Item('test2'), 4)
q.push(Item('test3'), 3)
assert(str(q.pop()) == "Item('test2')")
print('Tests passed!'.center(20,'*'))
if __name__ == '__main__':
test_PriorityQueue()

View File

@ -0,0 +1,41 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import heapq
class PriorityQueue(object):
''' implements a priority queue class '''
def __init__(self):
self._queue = []
self._index = 0 # index property order items with same priority level, good for comparisons
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item)) # notice the tuple
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]
class Item:
def __init__(self, name):
self.name = name
def __repr__(self):
return "Item({!r})".format(self.name)
def test_PriorityQueue():
''' push and pop are all O(logN) '''
q = PriorityQueue()
q.push(Item('test1'), 1)
q.push(Item('test2'), 4)
q.push(Item('test3'), 3)
assert(str(q.pop()) == "Item('test2')")
print('Tests passed!'.center(20,'*'))
if __name__ == '__main__':
test_PriorityQueue()

View File

@ -0,0 +1,44 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''The structure of an unordered list is a collection of items where each item holds a relative position with respect to the others '''
class Node:
''' The basic building block for the linked list implementation is the node.
Each node object must hold at least two pieces of information:
First, the node must contain the list item itself (data field),
second each node must hold a reference to the next node '''
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
def test_Node(module_name='this module'):
temp = Node(40)
assert(temp.getData() == 40)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_Node()

View File

@ -0,0 +1,71 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node(object):
def __init__(self,data=None,next=None):
self.data = data
self.next = next
def setnext(self,next):
self.next = next
def __str__(self):
return "%s" % self.data
class LinkedListStack(object):
''' linked list from stack '''
def __init__(self, max=0):
self.max = max
self.head = None
self.z = None
self.size = 0
def push(self, data):
if self.size == 0:
self.head = Node(data=data)
self.size += 1
else:
head = self.head
temp = Node(data = data)
self.head = temp
self.head = temp
temp.setnext(head)
def pop(self):
temp = self.head.next
self.head = temp
def isEmpty(self):
return self.size == 0
def __str__(self):
d = ""
if self.isEmpty(): return ""
else:
temp = self.head
d += "%s\n" % temp
while temp.next != None:
temp = temp.next
d += "%s\n" % temp
return d
def test_ll_from_stack():
ll = LinkedListStack(max = 20)
ll.push("1")
ll.push("2")
ll.push("3")
ll.push("4")
print(ll)
ll.pop()
print(ll)
if __name__ == '__main__':
test_ll_from_stack()

View File

@ -0,0 +1,65 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from node import Node
class UnorderedList(object):
def __init__(self):
self.head = None
def add(self, item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self, item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self, item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
def test_UnorderedList(module_name='this module'):
llist = UnorderedList()
llist.add(31)
llist.add(22)
llist.add(10)
assert(llist.search(22) == True)
llist.remove(22)
assert(llist.search(22) == False)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_UnorderedList()

View File

@ -0,0 +1,65 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from node import Node
class UnorderedList(object):
def __init__(self):
self.head = None
def add(self, item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self,item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self,item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
def test_UnorderedList(module_name='this module'):
llist = UnorderedList()
llist.add(31)
llist.add(22)
llist.add(10)
assert(llist.search(22) == True)
llist.remove(22)
assert(llist.search(22) == False)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_UnorderedList()

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
def getData(self):
return self.value
def getNext(self):
return self.next
def setData(self, newdata):
self.value = newdata
def setNext(self, newnext):
self.next = newnext

View File

@ -0,0 +1,39 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''The structure of an unordered list is a collection of items where each item holds a relative position with respect to the others '''
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
def test_Node(module_name='this module'):
temp = Node(40)
assert(temp.getData() == 40)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_Node()

View File

@ -0,0 +1,97 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from Node import Node
class OrderedList:
""" The structure of an ordered list is a collection of items where each item
holds a relative position that is based upon some underlying characteristic of
the item. The ordering is typically either ascending or descending and we assume
that list items have a meaningful comparison operation that is already defined.
Many of the ordered list operations are the same as those of the unordered list.
"""
def __init__(self):
self.head = None
def add(self,item):
''' this method is different from linked list '''
current = self.head
previous = None
stop = False
while current != None and not stop:
if current.getData() > item:
stop = True
else:
previous = current
current = current.getNext()
temp = Node(item)
if previous == None:
temp.setNext(self.head)
self.head = temp
else:
temp.setNext(current)
previous.setNext(temp)
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self,item):
''' this method is different from linked list '''
current = self.head
found = False
stop = False
while current != None and not found and not stop:
if current.getData() == item:
found = True
else:
if current.getData() > item:
stop = True
else:
current = current.getNext()
return found
def remove(self,item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
def test_OrderedList(module_name='this module'):
olist = OrderedList()
olist.add(31)
olist.add(22)
olist.add(10)
assert(olist.search(22) == True)
olist.remove(22)
assert(olist.search(22) == False)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_OrderedList()

View File

@ -0,0 +1,46 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Deque(object):
''' a class for a double ended queue '''
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def add_front(self, item):
self.items.append(item)
def add_rear(self, item):
self.items.insert(0, item)
def remove_front(self):
return self.items.pop()
def remove_rear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
def __repr__(self):
return '{}'.format(self.items)
def main():
dq = Deque()
dq.add_front(1)
dq.add_front(2)
dq.add_front(3)
dq.add_rear(40)
dq.add_rear(50)
print(dq.size())
print(dq)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,46 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Deque(object):
''' a class for a double ended queue '''
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def add_front(self, item):
self.items.append(item)
def add_rear(self, item):
self.items.insert(0, item)
def remove_front(self):
return self.items.pop()
def remove_rear(self):
return self.items.pop(0)
def size(self):
return len(self.items)
def __repr__(self):
return '{}'.format(self.items)
def main():
dq = Deque()
dq.add_front(1)
dq.add_front(2)
dq.add_front(3)
dq.add_rear(40)
dq.add_rear(50)
assert(dq.size() == 5)
assert(dq == [50, 40, 1, 2, 3])
if __name__ == '__main__':
main()

View File

@ -0,0 +1,61 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
class LinkedQueue(object):
''' Queue acts as a container for nodes (objects) that are inserted and removed according FIFO'''
def __init__(self):
self.front = None
self.back = None
def isEmpty(self):
return bool(self.front)
def dequeue(self):
if self.front:
value = self.front.value
self.front = self.front.next
return value
raise Exception('Queue is empty, cannot dequeue.')
def enqueue(self, value):
node = Node(value)
if self.front:
self.back.next = node
self.back = node
else:
self.front = node
self.back = node
return True
def size(self):
node = self.front
num_nodes = 1
while node.next:
num_nodes += 1
node = node.next
return num_nodes
def peek(self):
return self.front.value
def main():
queue = LinkedQueue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,61 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
class LinkedQueue(object):
''' Queue acts as a container for nodes (objects) that are inserted and removed according FIFO'''
def __init__(self):
self.front = None
self.back = None
def isEmpty(self):
return bool(self.front)
def dequeue(self):
if self.front:
value = self.front.value
self.front = self.front.next
return value
raise Exception('Queue is empty, cannot dequeue.')
def enqueue(self, value):
node = Node(value)
if self.front:
self.back.next = node
self.back = node
else:
self.front = node
self.back = node
return True
def size(self):
node = self.front
num_nodes = 1
while node.next:
num_nodes += 1
node = node.next
return num_nodes
def peek(self):
return self.front.value[-1]
def main():
queue = LinkedQueue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,34 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import sys
import string
import collections
def palindrome_checker_with_deque(str1):
d = collections.deque()
eq = True
strip = string.whitespace + string.punctuation + "\"'"
for s in str1.lower():
if s not in strip: d.append(s)
while len(d) > 1 and eq:
first = d.pop()
last = d.popleft()
if first != last:
eq = False
return eq
def test_palindrome_checker_with_deque():
str1 = 'Madam Im Adam'
str2 = 'Buffy is a Slayer'
assert(palindrome_checker_with_deque(str1) == True)
assert(palindrome_checker_with_deque(str2) == False)
print('Tests passed!')
if __name__ == '__main__':
test_palindrome_checker_with_deque()

View File

@ -0,0 +1,39 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Queue(object):
''' a class for a queue '''
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def peek(self):
return self.items[-1]
def main():
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,39 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Queue(object):
''' a class for a queue '''
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def size(self):
return self.items[-1]
def main():
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,48 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Queue(object):
''' an example of a queue implemented from 2 stacks '''
def __init__(self):
self.in_stack = []
self.out_stack = []
def enqueue(self, item):
return self.in_stack.append(item)
def dequeue(self):
if self.out_stack:
return self.out_stack.pop()
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
if not self.out_stack:
return "Queue empty!"
return self.out_stack.pop()
def size(self):
return len(self.in_stack) + len(self.out_stack)
def peek(self):
if self.out_stack:
return self.out_stack[-1]
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
return self.out_stack[-1]
def main():
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.peek())
print(queue.dequeue())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,48 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Queue(object):
''' an example of a queue implemented from 2 stacks '''
def __init__(self):
self.in_stack = []
self.out_stack = []
def enqueue(self, item):
return self.in_stack.append(item)
def dequeue(self):
if self.out_stack:
return self.out_stack.pop()
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
if not self.out_stack:
return "Queue empty!"
return self.out_stack.pop()
def size(self):
return len(self.in_stack) + len(self.out_stack)
def peek(self):
if self.out_stack:
return self.out_stack[-1]
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
return self.out_stack[-1]
def main():
queue = Queue()
queue.add(1)
queue.add(2)
queue.add(3)
print(queue.size())
print(queue.peek())
print(queue.remove())
print(queue.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,47 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node:
def __init__(self, value):
self.value = value
self.next = None
class Queue:
''' Queue acts as a container for nodes (objects) that are inserted and removed according FIFO'''
def __init__(self):
self.first = None
self.last = None
def dequeue(self):
if self.front:
value = self.first.value
self.first = self.first.next
return value
raise Exception('Queue is empty, cannot dequeue.')
def enqueue(self, value):
node = Node(value)
if self.first:
self.last.next = node
self.last = node
else:
self.first = node
self.last = node
return True
def isEmpty(self):
return bool(self.first)
def size(self):
node = self.first
num_nodes = 0
while node.next:
num_nodes += 1
node = node.next
return num_nodes

View File

@ -0,0 +1,27 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def rotating_array(seq, N):
''' rotate an array from right to left for a given number'''
myqueue = []
for i in range(N):
myqueue.append(seq.pop())
myqueue.reverse()
return myqueue + seq
def test_rotating_array(module_name='this module'):
seq = [1, 2, 3, 4, 5, 6, 7]
N = 4
assert(rotating_array(seq, N) == [4, 5, 6, 7, 1, 2, 3])
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_rotating_array()

View File

@ -0,0 +1,40 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from stack import Stack
def balance_par_str_with_stack(symbolString):
''' use a stack to balance the parenteses of a string '''
s = Stack()
balanced = True
index = 0
while index < len(symbolString) and balanced:
symbol = symbolString[index]
if symbol == "(":
s.push(symbol)
else:
if s.isEmpty():
balanced = False
else:
s.pop()
index = index + 1
if balanced and s.isEmpty():
return True
else:
return False
def test_balance_par_str_with_stack(module_name='this module'):
print(balance_par_str_with_stack('((()))'))
print(balance_par_str_with_stack('(()'))
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_balance_par_str_with_stack()

View File

@ -0,0 +1,28 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from stack import Stack
def dec2bin_with_stack(decnum):
'''transform a decimal number to a binary number with a stack '''
s = Stack()
str_aux = ''
while decnum > 0:
dig = decnum % 2
decnum = decnum//2
s.push(dig)
while not s.isEmpty():
str_aux += str(s.pop())
return str_aux
def test_dec2bin_with_stack(module_name='this module'):
decnum = 9
assert(dec2bin_with_stack(decnum) == '1001')
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_dec2bin_with_stack()

View File

@ -0,0 +1,52 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node:
def __init__(self, value=None):
self.value = value
self.next = None
class StackwithNodes:
''' Define a Stack with nodes'''
def __init__(self):
self.top = None
def isEmpty(self):
return bool(self.top)
def pop(self):
node = self.top
self.top = node.next
return node.value
def push(self, value):
node = Node(value)
node.next = self.top
self.top = node
def size(self):
node = self.top
if node not None: num_nodes = 1
else: return 0
while node.next:
num_nodes += 1
node = node.next
return num_nodes
def peek(self):
return self.top.value
def main():
stack = StackwithNodes()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.size())
print(stack.peek())
print(stack.pop())
print(stack.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,51 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Node:
def __init__(self, value=None):
self.value = value
self.next = None
class StackwithNodes:
''' Define a Stack with nodes'''
def __init__(self):
self.top = None
def isEmpty(self):
return bool(self.top)
def pop(self):
node = self.top
self.top = node.next
return node.value
def push(self, value):
node = Node(value)
node.next = self.top
self.top = node
def size(self):
node = self.top
num_nodes = 1
while node.next:
num_nodes += 1
node = node.next
return num_nodes
def peek(self):
return self.top.value
def main():
stack = StackwithNodes()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.size())
print(stack.peek())
print(stack.pop())
print(stack.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,30 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import sys
import stack
def reverse_string_with_stack(str1):
''' Uses a stack to reverse a string '''
s = stack.Stack()
revStr = ''
for c in str1:
s.push(c)
while not s.isEmpty():
revStr += s.pop()
return revStr
def test_reverse_string_with_stack():
str1 = 'Buffy is a Slayer!'
assert(reverse_string_with_stack(str1) == '!reyalS a si yffuB')
print('Tests passed!')
if __name__ == '__main__':
test_reverse_string_with_stack()

View File

@ -0,0 +1,30 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import sys
import stack
def reverse_string_with_stack(str1):
''' Uses a stack to reverse a string '''
s = stack.Stack()
revStr = ''
for c in str1:
s.push(c)
while not s.isEmpty():
revStr += s.pop()
return revStr
def test_reverse_string_with_stack():
str1 = 'Buffy is a Slayer!'
assert(reverse_string_with_stack(str1) == '!reyalS a si yffuB')
print('Tests passed!')
if __name__ == '__main__':
test_reverse_string_with_stack()

View File

@ -0,0 +1,47 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class SetOfStacks(list):
def __init__(self, capacity=4):
self.stacks = []
self.last_stack = []
self.capacity = capacity
self.stacks.append(self.last_stack)
def __repr__(self):
return str(self.stacks)
def push(self, value):
last_stack = self.last_stack
if len(last_stack) is self.capacity:
last_stack = []
self.last_stack = last_stack
self.stacks.append(last_stack)
last_stack.append(value)
def pop(self):
last_stack = self.last_stack
value = last_stack.pop()
if len(last_stack) is 0:
self.stacks.pop()
self.last_stack = self.stacks[-1]
return value
def main():
stack = SetOfStacks()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
stack.push(6)
print(stack)
stack.pop()
stack.pop()
stack.pop()
print(stack)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,48 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class SetOfStacks(list):
def __init__(self, capacity=4):
self.stacks = []
self.last_stack = []
self.capacity = capacity
self.stacks.append(self.last_stack)
def __repr__(self):
return str(self.stacks)
def push(self, value):
last_stack = self.last_stack
if len(last_stack) is self.capacity:
last_stack = []
self.last_stack = last_stack
self.stacks.append(last_stack)
last_stack.append(value)
def pop(self):
last_stack = self.last_stack
value = last_stack.pop()
if len(last_stack) is 0:
self.stacks.pop()
self.last_stack = self.stacks[-1]
return value
def main():
stack = SetOfStacks()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
stack.push(6)
print(stack)
stack.pop()
stack.pop()
stack.pop()
print(stack)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,40 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Stack(object):
''' define the stack class '''
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, items):
self.items.append(items)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[-1]
def size(self):
return len(self.items)
def main():
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.size())
print(stack.peek())
print(stack.pop())
print(stack.peek())
if __name__ == '__main__':
main()

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Stack(object):
''' define the stack class '''
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, items):
self.items.append(items)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[-1]
def size(self):
return len(self.items)

View File

@ -0,0 +1,55 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class Stack(list):
def push(self, value):
if len(self) > 0:
last = self[-1]
minimum = self._find_minimum(value, last)
else:
minimum = value
self.minimum = minimum
self.append(NodeWithMin(value, minimum))
def _find_minimum(self, value, last_value):
if value < last_value.minimum:
return value
return last_value.minimum
def min(self):
return self.minimum
class NodeWithMin(object):
def __init__(self, value, minimum):
self.value = value
self.minimum = minimum
def __repr__(self):
return str(self.value)
def min(self):
return self.minimum
def main():
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
node = stack.pop()
print(node.minimum)
stack.push(0)
stack.push(4)
node = stack.pop()
print(node.min())
print(stack.min())
print(stack)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,54 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from linked_stack import StackwithNodes
from node import Node
class StackWithMins(Stack):
mins = StackwithNodes()
def push(self, item):
node = Node(item)
node.next = self.top
self.top = node
if self.mins.top is not None:
if self.mins.top.data > item:
self.mins.push(item)
else:
self.mins.push(item)
def pop(self):
if self.top is not None:
if self.peek() == self.mins.peek():
self.mins.pop()
node = self.top
self.top = self.top.next
return node
return None
def min(self):
return self.mins.peek()
def test_():
stack = StackWithMins()
stack.push(9)
stack.push(5)
stack.push(7)
stack.push(4)
stack.push(3)
stack.push(6)
stack.push(5)
stack.push(2)
stack.push(1)
stack.print_stack()
stack.mins.print_stack()
if __name__ == '__main__':
test_()

View File

@ -0,0 +1,16 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import random
def benchmark(func):
import time
def wrapper(*args, **kwargs):
t = time.clock()
res = func(*args, **kwargs)
print("\t%s" % func.__name__, time.clock()-t)
return res
return wrapper

View File

@ -0,0 +1,42 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from functools import wraps
from do_benchmark import benchmark
def memo(func):
''' an example of dynamic programming using a memoizing decorator '''
cache = {}
@wraps(func)
def wrap(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrap
@memo
def find_fibonacci_seq_rec(n):
''' implements the nth fibonacci value in a recursive exponential runtime '''
if n < 2: return n
return find_fibonacci_seq_rec(n - 1) + find_fibonacci_seq_rec(n - 2)
def test_memo():
n = 50
# find_fibonacci_seq_rec = memo(find_fibonacci_seq_rec)
# @benchmark
print(find_fibonacci_seq_rec(n))
if __name__ == '__main__':
test_memo()

View File

@ -0,0 +1,86 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from itertools import combinations
from bisect import bisect
from memo import memo
from do_benchmark import benchmark
def naive_longest_inc_subseq(seq):
''' naive (exponential) solution to the longest increasing subsequence problem '''
for length in range(len(seq), 0, -1):
for sub in combinations(seq, length):
if list(sub) == sorted(sub):
return len(sub)
def longest_inc_subseq1(seq):
''' an iterative algorithm for the longest increasing subsequence problem '''
end = []
for val in seq:
idx = bisect(end, val)
if idx == len(end): end.append(val)
else: end[idx] = val
return len(end)
def longest_inc_subseq2(seq):
''' another iterative algorithm for the longest increasing subsequence problem '''
L = [1] * len(seq)
for cur, val in enumerate(seq):
for pre in range(cur):
if seq[pre] <= val:
L[cur] = max(L[cur], 1 + L[pre])
return max(L)
def memoized_longest_inc_subseq(seq):
''' a memoized recursive solution to find the longest increasing subsequence problem '''
@memo
def L(cur):
res = 1
for pre in range(cur):
if seq[pre] <= seq[cur]:
res = max(res, 1 + L(pre))
return res
return max(L(i) for i in range(len(seq)))
@benchmark
def test_naive_longest_inc_subseq():
print(naive_longest_inc_subseq(s1))
benchmark
def test_longest_inc_subseq1():
print(longest_inc_subseq1(s1))
@benchmark
def test_longest_inc_subseq2():
print(longest_inc_subseq2(s1))
@benchmark
def test_memoized_longest_inc_subseq():
print(memoized_longest_inc_subseq(s1))
if __name__ == '__main__':
from random import randrange
s1 = [randrange(100) for i in range(25)]
print(s1)
test_naive_longest_inc_subseq()
test_longest_inc_subseq1()
test_longest_inc_subseq2()
test_memoized_longest_inc_subseq()

View File

@ -0,0 +1,33 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from collections import Counter
def Counter_example():
''' show some examples for Counter '''
''' it is a dictionary that maps the items to the number of occurences '''
seq1 = [1, 2, 3, 5, 1, 2, 5, 5, 2, 5, 1, 4]
seq_counts = Counter(seq1)
print(seq_counts)
''' we can increment manually or use the update() method '''
seq2 = [1, 2, 3]
seq_counts.update(seq2)
print(seq_counts)
seq3 = [1, 4, 3]
for key in seq3:
seq_counts[key] += 1
print(seq_counts)
''' also, we can use set operations such as a-b or a+b '''
seq_counts_2 = Counter(seq3)
print(seq_counts_2)
print(seq_counts + seq_counts_2)
print(seq_counts - seq_counts_2)
if __name__ == '__main__':
Counter_example()

View File

@ -0,0 +1,31 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from collections import OrderedDict
def OrderedDict_example():
''' show some examples for OrderedDict '''
''' keep the order of insertion.
maintains a doubly linked list, so size is more than twice than normal dict'''
pairs = [('a', 1), ('b',2), ('c',3)]
d1 = {}
for key, value in pairs:
if key not in d1:
d1[key] = []
d1[key].append(value)
for key in d1:
print(key, d1[key])
d2 = OrderedDict(pairs)
for key in d2:
print(key, d2[key])
if __name__ == '__main__':
OrderedDict_example()

View File

@ -0,0 +1,21 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import collections
import string
import sys
def count_unique_word():
words = collections.defaultdict(int)
strip = string.whitespace + string.punctuation + string.digits + "\"'"
for filename in sys.argv[1:]:
with open(filename) as file:
for line in file:
for word in line.lower().split():
word = word.strip(strip)
if len(word) > 2:
words[word] = +1
for word in sorted(words):
print("'{0}' occurs {1} times.".format(word, words[word]))

View File

@ -0,0 +1,27 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from collections import defaultdict
def defaultdict_example():
''' show some examples for defaultdicts '''
pairs = {('a', 1), ('b',2), ('c',3)}
d1 = {}
for key, value in pairs:
if key not in d1:
d1[key] = []
d1[key].append(value)
print(d1)
d2 = defaultdict(list)
for key, value in pairs:
d2[key].append(value)
print(d2)
if __name__ == '__main__':
defaultdict_example()

View File

@ -0,0 +1,32 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import string
def delete_unique_word(str1):
''' find and delete all the duplicate characters in a string '''
# create ordered dict
table_c = { key : 0 for key in string.ascii_lowercase}
# fill the table with the chars in the string
for i in str1:
table_c[i] += 1
# scan the table to find times chars > 1
for key, value in table_c.items():
if value > 1:
str1 = str1.replace(key, "")
return str1
def test_delete_unique_word():
str1 = "google"
assert(delete_unique_word(str1) == 'le')
print('Tests passed!')
if __name__ == '__main__':
test_delete_unique_word()

View File

@ -0,0 +1,34 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def hash_func(astring, tablesize):
sum = 0
for pos in range(len(astring)):
sum = sum + ord(astring[pos])
return sum%tablesize
def find_anagram_hash_function(word1, word2):
''' verify if words are anagrams by comparying hash functions'''
tablesize = 11
return hash_func(word1, tablesize) == hash_func(word2, tablesize)
def test_find_anagram_hash_function(module_name='this module'):
word1 = 'buffy'
word2 = 'bffyu'
word3 = 'bffya'
assert(find_anagram_hash_function(word1, word2) == True)
assert(find_anagram_hash_function(word1, word3) == False)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_anagram_hash_function()

View File

@ -0,0 +1,33 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from collections import Counter, defaultdict
def find_dice_probabilities(S, n_faces=6):
''' given 2 dice, determine number of ways to sum S if all dice are rolled '''
if S > 2*n_faces or S < 2: return None
cdict = Counter()
ddict = defaultdict(list)
for dice1 in range(1, n_faces+1):
for dice2 in range(1, n_faces+1):
t = [dice1, dice2]
cdict[dice1+dice2] += 1
ddict[dice1+dice2].append( t)
return [cdict[S], ddict[S]]
def test_find_dice_probabilities(module_name='this module'):
n_faces = 6
S = 5
results = find_dice_probabilities(S, n_faces)
print(results)
assert(results[0] == len(results[1]))
if __name__ == '__main__':
test_find_dice_probabilities()

View File

@ -0,0 +1,31 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from collections import Counter
def find_top_N_recurring_words(seq, N):
''' find the top N recurring words in a file:
1) use a hash table to find counts
2) sort the list on base of the maximum counts
3) return the last N words '''
dcounter = Counter()
for word in seq.split():
dcounter[word] += 1
return dcounter.most_common(N)
def test_find_top_N_recurring_words(module_name='this module'):
seq = 'buffy angel monster xander a willow gg buffy the monster super buffy angel'
N = 3
assert(find_top_N_recurring_words(seq, N) == [('buffy', 3), ('monster', 2), ('angel', 2)])
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_top_N_recurring_words()

View File

@ -0,0 +1,51 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''To use timeit you create a Timer object whose parameters are two Python statements. The first parameter is a Python statement that you want to time; the second parameter is a statement that will run once to set up the test. The timeit module will then time how long it takes to execute the statement some number of times. By default timeit will try to run the statement one million times. When its done it returns the time as a floating point value representing the total number of seconds. However, since it executes the statement a million times you can read the result as the number of microseconds to execute the test one time. You can also pass timeit a named parameter called number that allows you to specify how many times the test statement is executed. The following session shows how long it takes to run each of our test functions 1000 times. '''
import timeit
import random
for i in range(10000,1000001,20000):
''' this experiment confirm that the contains operator for lists is O(n) and for dict is O(1) '''
t = timeit.Timer("random.randrange(%d) in x"%i, "from __main__ import random,x")
x = list(range(i))
lst_time = t.timeit(number=1000)
x = {j:None for j in range(i)}
d_time = t.timeit(number=1000)
print("%d,%10.3f,%10.3f" % (i, lst_time, d_time))
""" There rersults are:
10000, 0.192, 0.002
30000, 0.600, 0.002
50000, 1.000, 0.002
70000, 1.348, 0.002
90000, 1.755, 0.002
110000, 2.194, 0.002
130000, 2.635, 0.002
150000, 2.951, 0.002
170000, 3.405, 0.002
190000, 3.743, 0.002
210000, 4.142, 0.002
230000, 4.577, 0.002
250000, 4.797, 0.002
270000, 5.371, 0.002
290000, 5.690, 0.002
310000, 5.977, 0.002
so we can see the linear tile for lists, and constant for dict!
Big-O Efficiency of Python Dictionary Operations
Operation Big-O Efficiency
copy O(n)
get item O(1)
set item O(1)
delete item O(1)
contains (in) O(1)
iteration O(n)
"""

View File

@ -0,0 +1,38 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def usual_dict(dict_data):
newdata = {}
for k, v in dict_data:
if k in newdata:
newdata[k].append(v)
else:
newdata[k] = [v]
return newdata
def setdefault_dict(dict_data):
newdata = {}
for k, v in dict_data:
newdata.setdefault(k, []).append(v)
return newdata
def test_setdef(module_name='this module'):
dict_data = (('key1', 'value1'),
('key1', 'value2'),
('key2', 'value3'),
('key2', 'value4'),
('key2', 'value5'),)
print(usual_dict(dict_data))
print(setdefault_dict(dict_data))
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_setdef()

View File

@ -0,0 +1,45 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import string
def verify_two_strings_are_anagrams(str1, str2):
""" find whether two words are anagrams. Since sets do not count occurency, and sorting is O(nlogn)
we will use hash tables. We scan the first string and add all the character occurences. Then we
scan the second tring and decrease all the caracther occurences. If all the counts are zero, it is
an anagram"""
# create the hash table
ana_table = {key:0 for key in string.ascii_lowercase}
# scan first string
for i in str1:
ana_table[i] += 1
# scan second string
for i in str2:
ana_table[i] -= 1
# verify whether all the entries are 0
if len(set(ana_table.values())) < 2: return True
else: return False
def test_verify_two_strings_are_anagrams():
str1 = 'marina'
str2 = 'aniram'
assert(verify_two_strings_are_anagrams(str1, str2) == True)
str1 = 'google'
str2 = 'gouglo'
assert(verify_two_strings_are_anagrams(str1, str2) == False)
print('Tests passed!')
if __name__ == '__main__':
test_verify_two_strings_are_anagrams()

View File

@ -0,0 +1,47 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_closest_num_seq_unsorted(seq):
''' Find the Closest two Numbers in a Sequence. If we do this without sorting
first, the runtime will be O(n^2) '''
dd = float("inf")
for x in seq:
for y in seq:
if x == y: continue
d = abs(x - y)
if d < dd:
xx, yy, dd = x, y, d
return xx, yy
def find_closest_num_seq_sorted(seq):
''' However, if we sort first, we can achieve it with runtime O(n log n): '''
seq.sort()
print(seq)
dd = float("inf")
for i in range(len(seq) - 1):
x, y = seq[i], seq[i+1]
if x == y: continue
d = abs(x-y)
if d < dd:
xx, yy, dd = x, y, d
return xx, yy
def test_find_closest_num_seq(module_name='this module'):
import random
seq = [random.randrange(100) for i in range(20)]
print(seq)
print(find_closest_num_seq_sorted(seq))
print(find_closest_num_seq_unsorted(seq))
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_closest_num_seq()

View File

@ -0,0 +1,44 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_duplicate_num_array(l1):
""" an array contains n numbers ranging from 0 to n-1. there are some numbers duplicated, but it is
not clear how many. this code find a duplicate number in the array. """
""" A naive solution is to sort the input array, costing O(nlogn). Another solution is the utilization of a hash set. When the number is scanned, it is either in or not. It costs O(n) auxiliary memory to accomodate a hash set. A third solution, that only costs O(1) is consider that indexes in an array with length n are in the range n-1. If there were no duplication in the n numbers from 0 to n-1, we could rearange them sorted, so that each i has its ith number. Since there are duplicates, some locations are occupied by multiple numbers, other are vacant. So every number is scanned one by one, if it the number is not in the right i, it is compared to that from i, and the duplicate can be found, or we swap. Continue until a duplicate is found."""
for i in range(len(l1)):
if l1[i] == i: continue
elif l1[i] < 0 or l1[i] > len(l1)-1:
return None
elif l1[i] == l1[l1[i]]:
return True
else:
aux = l1[l1[i]]
l1[l1[i]] = l1[i]
l1[i] = aux
else:
return False
def test_find_duplicate_num_array():
a = [1,3,5,2,4,0]
b = [1,3,5,2,1,0,4]
c = [0,0]
assert(find_duplicate_num_array(b) == True)
assert(find_duplicate_num_array(a) == False)
assert(find_duplicate_num_array(c) == True)
print('Tests passed!')
if __name__ == '__main__':
test_find_duplicate_num_array()

View File

@ -0,0 +1,30 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_long_con_inc(seq):
''' find the longest continuous increasing subsequence'''
one_seq = []
result = []
for i in range(0, len(seq)-1):
pivot = seq[i]
if pivot <= seq[i+1]:
one_seq.append(pivot)
else:
one_seq.append(pivot)
if len(one_seq) > len(result):
result = one_seq
one_seq = []
return result
def test_find_long_con_inc(module_name='this module'):
seq = [1, -2, 3, 5, 1, -1, 4, -1, 6]
long_con_inc = [-2,3,5]
assert(find_long_con_inc(seq) == long_con_inc )
if __name__ == '__main__':
test_find_long_con_inc()

View File

@ -0,0 +1,31 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_long_con_inc(seq):
''' find the longest continuous increasing subsequence'''
one_seq = []
result = []
for i in range(0, len(seq)-1):
pivot = seq[i]
if pivot <= seq[i+1]:
one_seq.append(pivot)
else:
one_seq.append(pivot)
if len(one_seq) > len(result):
result = one_seq
one_seq = []
return result
def test_find_long_con_inc(module_name='this module'):
seq = [1, -2, 3, 5, 1, -1, 4, -1, 6]
long_con_inc = [-2,3,5]
assert(find_long_con_inc(seq) == long_con_inc )
if __name__ == '__main__':
test_find_long_con_inc()

View File

@ -0,0 +1,58 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_majority_in_seq(seq):
''' find value which occurrence is greater than the total occurrence of all other elements '''
times = 1
result = seq[0]
for i in range(len(seq)):
if times == 0:
result = seq[i]
times = 1
elif seq[i] == result:
times +=1
else:
times -=1
if times == 0: return None
else:
count = 0
for i, c in enumerate(seq):
if c == result:
count += 1
return result, count
def test_find_majority_in_seq():
seq = [1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 6]
seq2 = [1, 2, 3]
assert(find_majority_in_seq(seq) == (4, 4))
assert(find_majority_in_seq(seq2) == None)
print('Tests passed!')
if __name__ == '__main__':
test_find_majority_in_seq()
"""
>>> A = [1, 2, 3, 2, 2, 4, 2, 5, 2]
>>> find_majority(A)
(2, 5)
>>> A = [1]
>>> find_majority(A)
(1, 1)
>>> A = [1, 2, 3, 2, 5, 6, 7]
>>> find_majority(A)
No Majority Element.
"""

View File

@ -0,0 +1,44 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_max_profit_On(seq):
''' find the most profit from a seq with O(n) '''
max_profit = 0
min_value = seq[0]
for i in range(1, len(seq)):
profit_here = seq[i]- min_value
if profit_here > max_profit:
max_profit = profit_here
else:
if min_value > seq[i]:
min_value = seq[i]
return max_profit
def find_max_profit_On2(seq):
''' find the most profit from a seq with O(n2) '''
max_profit = 0
for i in range(len(seq)-1):
for j in range (i, len(seq)-1):
if seq[j] - seq[i] > max_profit:
max_profit = seq[j] - seq[i]
return max_profit
def test_find_max_profit():
seq = [9,11,5,7,16,1]
assert(find_max_profit_On(seq) == 11)
assert(find_max_profit_On2(seq) == 11)
seq = [1,15,2,3,4,3]
assert(find_max_profit_On(seq) == 14)
assert(find_max_profit_On2(seq) == 14)
print('Tests passed!')
if __name__ == '__main__':
test_find_max_profit()

View File

@ -0,0 +1,44 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_max_subarray1(l1):
''' calculate the greatest sum of subarrays from an array.
An array with n elements has n(n+1)/2 subarrays so force brute cost O(n^2).
What we can do is to check when a sum becomes a negative number or zero, and then discard, since
this will not "add" anything to the new event... When the sum decreases, it gets the previous sum. '''
sum_new, result = 0, 0
for c in l1:
result = max(result, sum_new)
sum_new += c
if sum_new <= 0: sum_new = 0
return result
def find_max_subarray2(l1):
''' find the contiguous subarray which has the largest sum (Kadane's algorithm in O(n))
with extra O(n) space '''
sum_old = [l1[0]]
for c in l1:
sum_old.append(max(c, sum_old [-1] + c))
return max(sum_old)
def test_find_max_subarray():
l1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
l2 = [-1, 3, -5, 4, 6, -1, 2, -7, 13, -3]
assert(find_max_subarray1(l1)) == 6)
assert(find_max_subarray1(l2)) == 17)
assert(find_max_subarray2(l1) == 6)
assert(find_max_subarray2(l2) == 17)
print('Tests passed!')
if __name__ == '__main__':
test_find_max_subarray()

View File

@ -0,0 +1,44 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_max_subarray1(l1):
''' calculate the greatest sum of subarrays from an array.
An array with n elements has n(n+1)/2 subarrays so force brute cost O(n^2).
What we can do is to check when a sum becomes a negative number or zero, and then discard, since
this will not "add" anything to the new event... When the sum decreases, it gets the previous sum. '''
sum_new, result = 0, 0
for c in l1:
result = max(result, sum_new)
sum_new += c
if sum_new <= 0: sum_new = 0
return result
def find_max_subarray2(l1):
''' find the contiguous subarray which has the largest sum (Kadane's algorithm in O(n))
with extra O(n) space '''
sum_old = [l1[0]]
for c in l1:
sum_old.append(max(c, sum_old [-1] + c))
return max(sum_old)
def test_find_max_subarray():
l1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
l2 = [-1, 3, -5, 4, 6, -1, 2, -7, 13, -3]
assert(find_max_subarray1(l1)) == 6)
assert(find_max_subarray1(l2)) == 17)
assert(find_max_subarray2(l1) == 6)
assert(find_max_subarray2(l2) == 17)
print('Tests passed!')
if __name__ == '__main__':
test_find_max_subarray()

View File

@ -0,0 +1,33 @@
def find_product_without_division(seq):
'''Given an array of numbers, replace each number with the product of all the numbers in the array except the number itself *without* using division '''
forw = []
bacw = []
for i in range(len(seq)):
prod_f = 1
prod_b = 1
for next in range(i+1, len(seq)):
prod_f *= seq[next]
for before in range(0, i):
prod_b *= seq[before]
forw.append(prod_f)
bacw.append(prod_b)
print(bacw)
print(forw)
for i in range(len(seq)):
seq[i] = forw[i]*bacw[i]
return seq
def test_find_product_without_division():
seq = [2,3,4]
result = [12, 8, 6]
print(find_product_without_division(seq))
if __name__ == '__main__':
test_find_product_without_division()

View File

@ -0,0 +1,55 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import math
def find_two_missing_numbers(l1):
""" Two numbers out of n numbers from 1 to n are missing. The remaining n-2 numbers are in the
array but not sorted. Find the missing numbers The sum1 is the sum of all the elements in n. The
sum2 is the sum of all the elements in n-2. sum1 - sum2 = num1 + num2 = s. The prod1 is the prod of
all the elements in n. The prod2 is the prod of all the elements in n-2. prod1/prod2 = num1*num2 =
p. Runtime is O(n), because it scan 3 times. Space is O(1)
- In case of finding one integer, Let the missing number be M. We know that the sum of first N
natural numbers is N*(N+1)/2. Traverse through the array once and calculate the sum. This is the
sum of first N natural numbers M or S=N*(N+1)/2 M. Therefore M = N*(N+1)/2 S.
"""
n_min_2 = len(l1)
n = n_min_2 + 2
sum1, sum2, prod1, prod2 = 0,0,1,1
sum2 = sum(l1[:])
sum1 = sum(range(1,n+1))
s = sum1 - sum2
for i in range(1, n-1):
prod1 = prod1*i
prod2 = prod2*l1[i-1]
prod1 = prod1*n*(n-1)
p = prod1/prod2
num1 = (s + math.sqrt(s*s - 4*p))/2
num2 = (s - math.sqrt(s*s - 4*p))/2
return num1, num2
def test_find_two_missing_numbers():
l1 = [1, 3, 5]
result = find_two_missing_numbers(l1)
assert(result[0] == 2.0 or result[0] == 4.0)
print('Tests passed!')
if __name__ == '__main__':
test_find_two_missing_numbers()

View File

@ -0,0 +1,27 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def greatest_sum_sub_array(l1):
sum_new = 0
results = []
for i, c in enumerate(l1):
sum_old = sum_new
sum_new = sum_old + c
if sum_new <= 0 or sum_new < sum_old:
sum_new = 0
results.append(sum_old)
continue
results.append(sum_new)
results.sort()
return results.pop()
def test_greatest_sum_sub_array():
l1 = [1, -4, 20, -4, 5, 15, 3]
assert(greatest_sum_sub_array(l1) == 23)
print('Tests passed!')
if __name__ == '__main__':
test_greatest_sum_sub_array()

View File

@ -0,0 +1,47 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_closest_num_seq_unsorted(seq):
''' Find the Closest two Numbers in a Sequence. If we do this without sorting
first, the runtime will be O(n^2) '''
dd = float("inf")
for x in seq:
for y in seq:
if x == y: continue
d = abs(x - y)
if d < dd:
xx, yy, dd = x, y, d
return xx, yy
def find_closest_num_seq_sorted(seq):
''' However, if we sort first, we can achieve it with runtime O(n log n): '''
seq.sort()
print(seq)
dd = float("inf")
for i in range(len(seq) - 1):
x, y = seq[i], seq[i+1]
if x == y: continue
d = abs(x-y)
if d < dd:
xx, yy, dd = x, y, d
return xx, yy
def test_find_closest_num_seq(module_name='this module'):
import random
seq = [random.randrange(100) for i in range(20)]
print(seq)
print(find_closest_num_seq_sorted(seq))
print(find_closest_num_seq_unsorted(seq))
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_closest_num_seq()

View File

@ -0,0 +1,38 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def merge_two_sorted_arrays(a1, a2):
""" merge two sorted arrays, keeping the final sorted """
if len(a1) >= len(a2):
biga = a1
smalla = a2
else:
biga = a2
smalla = a1
final = []
count = 0
for i in range(len(biga)):
if count < len(smalla) and smalla[count] < biga[i]:
final.append(smalla[count])
count+=1
final.append(biga[i])
return final
def test_merge_two_sorted_arrays():
a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a2 = [3, 6, 7]
assert(merge_two_sorted_arrays(a1, a2) == [0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10])
print('Tests passed!')
if __name__ == '__main__':
test_merge_two_sorted_arrays()

View File

@ -0,0 +1,39 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def print_all_seq_with_cont_num(s):
''' print all sequences with cont. numbers (2 at least) whose sum is a given s '''
if s < 3: return s
small = 1
big = 2
sum_here = big + small
result = []
while small < (1+s)/2:
sum_here = sum(range(small, big))
if sum_here < s:
big += 1
elif sum_here > s:
small +=1
else:
result.append(list(range(small, big)))
big += 1
return result
def test_print_all_seq_with_cont_num():
s = 15
sum_set_for_s = [[1,2,3,4,5], [4,5,6], [7,8]]
assert(print_all_seq_with_cont_num(s) == sum_set_for_s)
s = 1
assert(print_all_seq_with_cont_num(s)== 1)
s = 0
assert(print_all_seq_with_cont_num(s) == 0)
print('Tests passed!')
if __name__ == '__main__':
test_print_all_seq_with_cont_num()

View File

@ -0,0 +1,37 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def removing_duplicates_seq(seq):
''' if the values are hashable, we can use set and generators to remove duplicates
in a sequence '''
seen = set()
for item in seq:
if item not in seen:
yield item
seen.add(item)
def removing_duplicates_seq_not_hash(seq, key= None):
''' if the item is not hashable, such as dictionaries '''
seen = set()
for item in seq:
val = item if key is None else key[item]
if item not in seen:
yield item
seen.add(val)
def test_removing_duplicates_seq():
seq = [1, 2, 2, 2, 3, 3, 4, 4, 4]
dict = {'a':1, 'b':2, 'a':2, 'a':1}
assert(list(removing_duplicates_seq(seq)) == [1,2,3,4])
assert(list(removing_duplicates_seq_not_hash(dict)) == ['a', 'b'])
print('Tests passed!'.center(20, '*'))
if __name__ == '__main__':
test_removing_duplicates_seq()

View File

@ -0,0 +1,67 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
'''To use timeit you create a Timer object whose parameters are two Python statements. The first parameter is a Python statement that you want to time; the second parameter is a statement that will run once to set up the test. The timeit module will then time how long it takes to execute the statement some number of times. By default timeit will try to run the statement one million times. When its done it returns the time as a floating point value representing the total number of seconds. However, since it executes the statement a million times you can read the result as the number of microseconds to execute the test one time. You can also pass timeit a named parameter called number that allows you to specify how many times the test statement is executed. The following session shows how long it takes to run each of our test functions 1000 times. '''
def test1():
l = []
for i in range(1000):
l = l + [i]
def test2():
l = []
for i in range(1000):
l.append(i)
def test3():
l = [i for i in range(1000)]
def test4():
l = list(range(1000))
if __name__ == '__main__':
import timeit
t1 = timeit.Timer("test1()", "from __main__ import test1")
print("concat ",t1.timeit(number=1000), "milliseconds")
t2 = timeit.Timer("test2()", "from __main__ import test2")
print("append ",t2.timeit(number=1000), "milliseconds")
t3 = timeit.Timer("test3()", "from __main__ import test3")
print("comprehension ",t3.timeit(number=1000), "milliseconds")
t4 = timeit.Timer("test4()", "from __main__ import test4")
print("list range ",t4.timeit(number=1000), "milliseconds")
""" The results are:
('concat ', 2.366791009902954, 'milliseconds')
('append ', 0.16743111610412598, 'milliseconds')
('comprehension ', 0.06446194648742676, 'milliseconds')
('list range ', 0.021029949188232422, 'milliseconds')
So we see the following pattern for lists:
Operation Big-O Efficiency
index [] O(1)
index assignment O(1)
append O(1)
pop() O(1)
pop(i) O(n)
insert(i,item) O(n)
del operator O(n)
iteration O(n)
contains (in) O(n)
get slice [x:y] O(k)
del slice O(n)
set slice O(n+k)
reverse O(n)
concatenate O(k)
sort O(n log n)
multiply O(nk)
"""

View File

@ -0,0 +1,36 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def sum_two_numbers_sequence(seq, s):
""" given an increasing sorted array and an integer s, find if there is a pair of two numbers in the array whose sum is s. It takes O(n). """
l1 = seq[:]
l2 = seq[:]
l2.reverse()
n1 = l1.pop()
n2 = l2.pop()
while l2 and l1:
sum_here = n1 + n2
if sum_here > s:
n1 = l1.pop()
elif sum_here < s:
n2 = l2.pop()
else:
return True
return False
def test_sum_two_numbers_sequence():
l1 = [1,2,3,4,5,6,7,8]
s = 7
assert(sum_two_numbers_sequence(l1, s) == True)
print('Tests passed!')
if __name__ == '__main__':
test_sum_two_numbers_sequence()

View File

@ -0,0 +1,28 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import os
import sys
import shutil
def change_file_ext():
""" read a file and an extension from the command line and produces a copy with its extension changed"""
if len(sys.argv) < 2:
print("Usage: change_ext.py filename.old_ext 'new_ext'")
sys.exit()
name = os.path.splitext(sys.argv[1])[0] + "." + sys.argv[2]
print (name)
try:
shutil.copyfile(sys.argv[1], name)
except OSError as err:
print (err)
if __name__ == '__main__':
change_file_ext()

View File

@ -0,0 +1,33 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import pickle
def export_pickle(data, filename='test.dat', compress=False):
""" simple example of how to use pickle to export files """
fh = None
try:
if compress:
fh = gzip.open(filename, "wb") # write binary
else:
fh = open(filename, "wb") # compact binary pickle format
pickle.dump(data, fh, pickle.HIGHEST_PROTOCOL)
except(EnvironmentError, pickle.PickingError) as err:
print("{0}: export error: {1}".format(os.path.basename(sys.argv[0], err)))
return False
finally:
if fh is not None:
fh.close()
def test_export_pickle():
mydict = {'a': 1, 'b': 2, 'c': 3}
export_pickle(mydict)
if __name__ == '__main__':
test_export_pickle()

View File

@ -0,0 +1,18 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def fib_generator():
a, b = 0, 1
while True:
yield b
a, b = b, a+b
if __name__ == '__main__':
fib = fib_generator()
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))

View File

@ -0,0 +1,26 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import sys
def grep_word_from_files():
''' using iterator enumerate to create a grep command '''
word = sys.argv[1]
for filename in sys.argv[2:]:
with open(filename) as file:
for lino, line in enumerate(file, start=1):
if word in line:
print("{0}:{1}:{2:.40}".format(filename, lino, line.rstrip()))
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Usage: grep_word_from_files.py word infile1 [infile2...]")
sys.exit()
else:
grep_word_from_files()

View File

@ -0,0 +1,31 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import pickle
def import_pickle(filename):
""" an example of using pickle for importing data from files """
fh = None
try:
fh = open(filename, "rb")
mydict2 = pickle.load(fh)
return mydict2
except (EnvironmentError) as err:
print ("{0}: import error: {0}".format(os.path.basename(sys.arg[0]), err))
return false
finally:
if fh is not None:
fh.close()
def test_import_pickle():
pkl_file = 'test.dat'
mydict = import_pickle(pkl_file)
print(mydict)
if __name__ == '__main__':
test_import_pickle()

View File

@ -0,0 +1,18 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import sys
def main():
''' print command line arguments '''
for arg in sys.argv[1:]:
print arg
if __name__ == "__main__":
main()

View File

@ -0,0 +1,53 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import os
import sys
def read_data(filename):
lines = []
fh = None
try:
fh = open(filename)
for line in fh:
if line.strip():
lines.append(line)
except (IOError, OSError) as err:
print(err)
finally:
if fh is not None:
fh.close()
return lines
def write_data(lines, filename):
fh = None
try:
fh = open(filename, "w")
for line in lines:
fh.write(line)
except (EnvironmentError) as err:
print(err)
finally:
if fh is not None:
fh.close()
def remove_blank_lines():
""" read a list of filenames on the command line and for each one produces another file with the same content but with no blank lines """
if len(sys.argv) < 2:
print ("Usage: noblank.py infile1 [infile2...]")
for filename in sys.argv[1:]:
lines = read_data(filename)
if lines:
write_data(lines, filename)
if __name__ == '__main__':
remove_blank_lines()

View File

@ -0,0 +1,23 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import time
def sumOfN2(n):
''' a simple example of how to time a function '''
start = time.time()
theSum = 0
for i in range(1,n+1):
theSum = theSum + i
end = time.time()
return theSum,end-start
if __name__ == '__main__':
n = 5
print("Sum is %d and required %10.7f seconds"%sumOfN2(n))
n = 200
print("Sum is %d and required %10.7f seconds"%sumOfN2(n))

View File

@ -0,0 +1,27 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def convert_dec_to_any_base_rec(number, base):
''' convert an integer to a string in any base'''
convertString = '012345679ABCDEF'
if number < base: return convertString[number]
else:
return convert_dec_to_any_base_rec(number//base, base) + convertString[number%base]
def test_convert_dec_to_any_base_rec(module_name='this module'):
number = 9
base = 2
assert(convert_dec_to_any_base_rec(number, base) == '1001')
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_convert_dec_to_any_base_rec()

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def convert_from_decimal(number, base):
''' convert any decimal number to another base. '''
multiplier, result = 1, 0
while number > 0:
result += number%base*multiplier
multiplier *= 10
number = number//base
return result
def test_convert_from_decimal():
number, base = 9, 2
assert(convert_from_decimal(number, base) == 1001)
print('Tests passed!')
if __name__ == '__main__':
test_convert_from_decimal()

View File

@ -0,0 +1,24 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def convert_from_decimal_larger_bases(number, base):
''' convert any decimal number to a number in a base up to 20'''
strings = "0123456789ABCDEFGHIJ"
result = ""
while number > 0:
digit = number%base
result = strings[digit] + result
number = number//base
return result
def test_convert_from_decimal_larger_bases():
number, base = 31, 16
assert(convert_from_decimal_larger_bases(number, base) == '1F')
print('Tests passed!')
if __name__ == '__main__':
test_convert_from_decimal_larger_bases()

View File

@ -0,0 +1,25 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def convert_to_decimal(number, base):
''' convert any number in another base to the decimal base'''
multiplier, result = 1, 0
while number > 0:
result += number%10*multiplier
multiplier *= base
number = number//10
return result
def test_convert_to_decimal():
number, base = 1001, 2
assert(convert_to_decimal(number, base) == 9)
print('Tests passed!')
if __name__ == '__main__':
test_convert_to_decimal()

View File

@ -0,0 +1,44 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import math
def find_fibonacci_seq_rec(n):
''' implements the nth fibonacci value in a recursive exponential runtime '''
if n < 2: return n
return find_fibonacci_seq_rec(n - 1) + find_fibonacci_seq_rec(n - 2)
def find_fibonacci_seq_iter(n):
''' return the nth fibonacci value in a iterative O(n^2) runtime '''
if n < 2: return n
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
def find_fibonacci_seq_form(n):
''' return the nth fibonacci value implemented by the formula, nearly constant-time algorithm,
but, it has a poor precise (after 72 it starts to become wrong) '''
sq5 = math.sqrt(5)
phi = (1 + sq5) / 2
return int(math.floor(phi ** n / sq5))
def test_find_fib():
n = 10
assert(find_fibonacci_seq_rec(n) == 55)
assert(find_fibonacci_seq_iter(n) == 55)
assert(find_fibonacci_seq_form(n) == 55)
print('Tests passed!')
if __name__ == '__main__':
test_find_fib()

View File

@ -0,0 +1,28 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def finding_gcd(a, b):
''' implements the greatest common divider algorithm '''
while(b != 0):
result = b
a, b = b, a % b
return result
def test_finding_gcd():
number1 = 21
number2 = 12
assert(finding_gcd(number1, number2) == 3)
print('Tests passed!')
if __name__ == '__main__':
test_finding_gcd()

View File

@ -0,0 +1,59 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import math
import random
def finding_prime(number):
''' find whether a number is prime in a simple way'''
num = abs(number)
if num < 4 : return True
for x in range(2, num):
if num % x == 0:
return False
return True
def finding_prime_sqrt(number):
''' find whether a number is prime as soon as it rejects all candidates up to sqrt(n) '''
num = abs(number)
if num < 4 : return True
for x in range(2, int(math.sqrt(num)) + 1):
if number % x == 0:
return False
return True
def finding_prime_fermat(number):
''' find whether a number is prime with Fermat's theorem, using probabilistic tests '''
if number <= 102:
for a in range(2, number):
if pow(a, number- 1, number) != 1:
return False
return True
else:
for i in range(100):
a = random.randint(2, number - 1)
if pow(a, number - 1, number) != 1:
return False
return True
def test_finding_prime():
number1 = 17
number2 = 20
assert(finding_prime(number1) == True)
assert(finding_prime(number2) == False)
assert(finding_prime_sqrt(number1) == True)
assert(finding_prime_sqrt(number2) == False)
assert(finding_prime_fermat(number1) == True)
assert(finding_prime_fermat(number2) == False)
print('Tests passed!')
if __name__ == '__main__':
test_finding_prime()

View File

@ -0,0 +1,35 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import math
import random
import sys
from finding_prime import finding_prime_sqrt
def generate_prime(number=3):
''' return a n-bit prime '''
while 1:
p = random.randint(pow(2, number-2), pow(2, number-1)-1)
p = 2 * p + 1
if finding_prime_sqrt(p):
return p
if __name__ == '__main__':
if len(sys.argv) < 2:
print ("Usage: generate_prime.py number")
sys.exit()
else:
number = int(sys.argv[1])
print(generate_prime(number))

View File

@ -0,0 +1,40 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
def find_elem_matrix_bool(m1, value):
''' Search an Entry in a Matrix where the Rows and columns are Sorted
In this 2D matrix, every row is increasingly sorted from left to right,
and every column is increasingly sorted from top to bottom.
The runtime is O(m+n). '''
found = False
row = 0
col = len(m1[0]) - 1
while row < len(m1) and col >= 0:
if m1[row][col] == value:
found = True
break
elif m1[row][col] > value:
col-=1
else:
row+=1
return found
def test_find_elem_matrix_bool(module_name='this module'):
m1 = [[1,2,8,9], [2,4,9,12], [4,7,10,13], [6,8,11,15]]
assert(find_elem_matrix_bool(m1,8) == True)
assert(find_elem_matrix_bool(m1,3) == False)
m2 = [[0]]
assert(find_elem_matrix_bool(m2,0) == True)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_find_elem_matrix_bool()

View File

@ -0,0 +1,45 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
from fractions import Fraction
def rounding_floats(number1, places):
''' some operations with float()'''
return round(number1, places)
def float_to_fractions(number):
return Fraction(*number.as_integer_ratio())
def get_denominator(number1, number2):
a = Fraction(number1, number2)
return a.denominator
def get_numerator(number1, number2):
a = Fraction(number1, number2)
return a.numerator
def test_testing_floats(module_name='this module'):
number1 = 1.25
number2 = 1
number3 = -1
number4 = 5/4
number6 = 6
assert(rounding_floats(number1, number2) == 1.2)
assert(rounding_floats(number1*10, number3) == 10)
assert(float_to_fractions(number1) == number4)
assert(get_denominator(number2, number6) == number6)
assert(get_numerator(number2, number6) == number2)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_testing_floats()

View File

@ -0,0 +1,32 @@
#!/usr/bin/python
# mari von steinkirch @2013
# steinkirch at gmail
import numpy as np
def testing_numpy():
''' tests many features of numpy '''
ax = np.array([1,2,3])
ay = np.array([3,4,5])
print(ax)
print(ax*2)
print(ax+10)
print(np.sqrt(ax))
print(np.cos(ax))
print(ax-ay)
print(np.where(ax<2, ax, 10))
m = np.matrix([ax, ay, ax])
print(m)
print(m.T)
grid1 = np.zeros(shape=(10,10), dtype=float)
grid2 = np.ones(shape=(10,10), dtype=float)
print(grid1)
print(grid2)
print(grid1[1]+10)
print(grid2[:,2]*2)
if __name__ == '__main__':
testing_numpy()

View File

@ -0,0 +1,32 @@
#!/usr/bin/python
# mari von steinkirch @2013
# steinkirch at gmail
import numpy
import time
def trad_version():
t1 = time.time()
X = range(10000000)
Y = range(10000000)
Z = []
for i in range(len(X)):
Z.append(X[i] + Y[i])
return time.time() - t1
def numpy_version():
t1 = time.time()
X = numpy.arange(10000000)
Y = numpy.arange(10000000)
Z = X + Y
return time.time() - t1
if __name__ == '__main__':
print(trad_version())
print(numpy_version())
'''
3.23564291
0.0714290142059
'''

View File

@ -0,0 +1,27 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
import random
def testing_random():
''' testing the module random'''
values = [1, 2, 3, 4]
print(random.choice(values))
print(random.choice(values))
print(random.choice(values))
print(random.sample(values, 2))
print(random.sample(values, 3))
''' shuffle in place '''
random.shuffle(values)
print(values)
''' create random integers '''
print(random.randint(0,10))
print(random.randint(0,10))
if __name__ == '__main__':
testing_random()

View File

@ -0,0 +1,81 @@
#!/usr/bin/python3
# mari von steinkirch @2013
# steinkirch at gmail
class HashTable:
''' HashTable class that implements the Map abstract data type with 2 lists'''
def __init__(self):
self.size = 11
self.slots = [None] * self.size
self.data = [None] * self.size
def put(self,key,data):
hashvalue = self.hashfunction(key,len(self.slots))
if self.slots[hashvalue] == None:
self.slots[hashvalue] = key
self.data[hashvalue] = data
else:
if self.slots[hashvalue] == key:
self.data[hashvalue] = data
else:
nextslot = self.rehash(hashvalue,len(self.slots))
while self.slots[nextslot] != None and \
self.slots[nextslot] != key:
nextslot = self.rehash(nextslot,len(self.slots))
if self.slots[nextslot] == None:
self.slots[nextslot]=key
self.data[nextslot]=data
else:
self.data[nextslot] = data
def hashfunction(self,key,size):
return key%size
def rehash(self,oldhash,size):
return (oldhash+1)%size
def get(self,key):
startslot = self.hashfunction(key,len(self.slots))
data = None
stop = False
found = False
position = startslot
while self.slots[position] != None and \
not found and not stop:
if self.slots[position] == key:
found = True
data = self.data[position]
else:
position=self.rehash(position,len(self.slots))
if position == startslot:
stop = True
return data
def __getitem__(self,key):
return self.get(key)
def __setitem__(self,key,data):
self.put(key,data)
def test_HashTable(module_name='this module'):
H = HashTable()
H[54]="buffy"
H[26]="xander"
H[17]="giles"
print(H.slots)
print(H.data)
s = 'Tests in {name} have {con}!'
print(s.format(name=module_name, con='passed'))
if __name__ == '__main__':
test_HashTable()

Some files were not shown because too many files have changed in this diff Show More