print type(1) print type(int) def f(): pass print type(f) class Person(object): def __init__(self, name): self.name = name def WhatIsYourName(self): return self.name p1 = Person('John') p1.WhatIsYourName() class Employee(Person): def __init__(self, name, organization): self.name = name self.employer = organization def WhereDoYouWork(self): return self.employer p2 = Employee('Joshua', 'KAUST') print '%s works at %s' % (p2.WhatIsYourName(), p2.WhereDoYouWork()) class PhD(Employee): title = 'PhD' # this will be a class-wise field! def __init__(self, name, organization, major): super(PhD, self).__init__(name, organization) # or you can write Employee.__init__(self, name, organization) self.major = major def WhatIsYourMajor(self): return self.major p3 = PhD('Chris','KAUST','EE') print '%s is a %s in %s at %s' % (p3.name, p3.title, p3.WhatIsYourMajor(), p3.employer) #%load solutions/oop_ex.py # Check the type of class dict type(dict) # List all the methods, fields and properties dict class has dir(dict) # An example of 'magic' method with two underscores dict.__getitem__? class Graph(dict): """Graph class, extends dict""" def __init__(self, edges): """Initialize graph with a list of 2-tuples. Each tuple is a directed edge.""" for u, v in edges: try: self[u].append(v) except KeyError, e: self[u] = [v] # instead of try-except you can use: self[u] = self.get(u,[]) + [v] def __str__(self): """Returns a Graph representation. Called by 'print' for any object we would like to print.""" representation = '\n'.join(["%i -> [%s]" % (u, ','.join([str(v) for v in V])) for u, V in self.iteritems()]) return representation g = Graph([(1,2), (2,3), (1,3)]) print g d = {100: "Hi", 7:"Week", 24:"Work", 2009:"KAUST"} print d #%load solutions/sorted_dict.py dir(len) # Check the help for the __call__ method len.__call__? # Apply function example def apply(data, func): """Loop through the data and apply the provided function.""" return [func(d) for d in data] apply([1, -1, 2, 10, 100, -404], str) # Bind function example def bind(func, **kwargs): def bfunc(*args): return func(*args, **kwargs) return bfunc sorted([1, -1, 2, 10, 100, -404]) sorted? rev_sorted = bind(sorted, reverse=True) rev_sorted([1, -1, 2, 10, 100, -404]) def Fib(n): """Return the n-th Fibonacci number.""" assert type(n) is int and n >= 0, "ERROR (Fib): index should be positive and integer!" return Fib(n-1) + Fib(n-2) if n > 1 else 1 if n is 1 else 0 [Fib(i) for i in range(15)] import collections def memoize(func): """A caching decorator. Checks and returns a cached value before applying the function itself.""" cache = {} def cachedFunc(*args): if args not in cache: print "Cache miss!" cache[args] = func(*args) return cache[args] return cachedFunc @memoize def Fib(n): """Return the n-th Fibonacci number.""" assert type(n) is int and n >= 0, "ERROR (Fib): index should be positive and integer!" return Fib(n-1) + Fib(n-2) if n > 1 else 1 if n is 1 else 0 [Fib(i) for i in range(16)] #%load solutions/fib_trace.py import MyModule from MyModule import * # or from MyModule import (MyFunctionName, MyClassName) sound/ Top-level package __init__.py Initialize the sound package formats/ Subpackage for file format conversions __init__.py wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py ... effects/ Subpackage for sound effects __init__.py echo.py surround.py reverse.py ... filters/ Subpackage for filters __init__.py equalizer.py vocoder.py karaoke.py ... import sound.effects.echo as echo %%file mymodule.py """ Example of a python module. Contains a variable called my_variable, a function called my_function, and a class called MyClass. """ my_variable = 0 def my_function(): """ Example function """ return my_variable class MyClass: """ Example class. """ def __init__(self): self.variable = my_variable def set_variable(self, new_value): """ Set self.variable to a new value """ self.variable = new_value def get_variable(self): return self.variable import mymodule help(mymodule) mymodule.my_variable mymodule.my_function my_class = mymodule.MyClass() my_class.set_variable(10) my_class.get_variable() # The function for showing size of objects (source: http://deeplearning.net/software/theano/tutorial/python-memory-management.html) import sys def show_sizeof(x, level=0): print "\t" * level, x.__class__, sys.getsizeof(x), x if hasattr(x, '__iter__'): if hasattr(x, 'items'): for xx in x.items(): show_sizeof(xx, level + 1) else: for xx in x: show_sizeof(xx, level + 1) sys.getsizeof? # Lets check sizes of different objects (sizes are indicated for 64-bit Python) show_sizeof(None) # 16 bytes for None show_sizeof(1) # 24 bytes for 64-bit int - 3 time the size of int64_t in C show_sizeof(2**500) # 92 bytes for 64-bit Python's long with unconstrained length show_sizeof(0.5) # 24 bytes for 64-bit double show_sizeof("") # 37 bytes for empty string show_sizeof(u"") # 50 for empty unicode string show_sizeof("Test") # 41 for not empty string (+1 byte per character) show_sizeof(u"Test") # 58 for not empty unicode string (+2 bytes per character) show_sizeof([]) # 72 bytes show_sizeof([1, "test", 0.5]) # 96 bytes. The capacity of this list is 6; +4 bytes per each link in a list. %%file memory-profile-me.py import copy import memory_profiler @profile def function(): x = range(1000000) # allocate a big list y = copy.deepcopy(x) del x return y if __name__=="__main__": function() %run -m memory_profiler memory-profile-me.py # Basic for-loop comprehension a = [1,2,3,4,5,6,7] b = [x**2 for x in a] print b # For-loop if-else comprehension c = [x**2 for x in a if x > 4] print c # Multiple for-loop if-else comprehension llist = [[1,2,3],(4,5,6),(7,8,9)] c = [x**2 for sublist in llist for x in sublist if x % 2 == 0] print c # In Python you can actually use infinite lsits and dicts (without running out of memory!) a = [1,2,3] a.append(a) print a a[3][3][3][3][3] # Quick swap a = 1 b = 2 print a,b a, b = b, a print a, b # Nice math-like comparison notation x = 5 print 3 < x < 8 print x < 10 < 5*x < 99 print 2 > x < 7 # List flattening techniques a = [[1,2,3],[4,5,6],[7,8,9]] print sum(a,[]) # this works only with nested lists (or objects with __add__ method defined) print [x for b in a for x in b] # works with any nested iterables # Pairing elements of two lists first, second = [1,2,3,4,5], [6,7,8,9,10] print first print second paired = zip(first,second) print paired # Unpairing the elements back into two lists (NOTE: Lists turn into tuples. This is due to zip implementation.) a, b = zip(*paired) print a print b # Providing function arguments via structures def func(a, b, c, kw1 = '', kw2 = 0): print a print b print c print kw1 print kw2 args = (1, 2, 3) kwargs = {'kw1':'Hello', 'kw2':100} func(*args,**kwargs) # Enumeration of the elements l = ["spam", "ham", "eggs"] print list(enumerate(l)) print list(enumerate(l,5))