diff --git a/python.html.markdown b/python.html.markdown index 908a0638..ced01910 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -16,7 +16,9 @@ Note: This article applies to Python 2.7 specifically, but should be applicable to Python 2.x. Look for another tour of Python 3 soon! ```python + # Single line comments start with a hash. + """ Multiline strings can be written using three "'s, and are often used as comments @@ -27,60 +29,60 @@ to Python 2.x. Look for another tour of Python 3 soon! #################################################### # You have numbers -3 #=> 3 +3 # => 3 # Math is what you would expect -1 + 1 #=> 2 -8 - 1 #=> 7 -10 * 2 #=> 20 -35 / 5 #=> 7 +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7 # Division is a bit tricky. It is integer division and floors the results # automatically. -5 / 2 #=> 2 +5 / 2 # => 2 # To fix division we need to learn about floats. 2.0 # This is a float -11.0 / 4.0 #=> 2.75 ahhh...much better +11.0 / 4.0 # => 2.75 ahhh...much better # Enforce precedence with parentheses -(1 + 3) * 2 #=> 8 +(1 + 3) * 2 # => 8 # Boolean values are primitives True False # negate with not -not True #=> False -not False #=> True +not True # => False +not False # => True # Equality is == -1 == 1 #=> True -2 == 1 #=> False +1 == 1 # => True +2 == 1 # => False # Inequality is != -1 != 1 #=> False -2 != 1 #=> True +1 != 1 # => False +2 != 1 # => True # More comparisons -1 < 10 #=> True -1 > 10 #=> False -2 <= 2 #=> True -2 >= 2 #=> True +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True # Comparisons can be chained! -1 < 2 < 3 #=> True -2 < 3 < 2 #=> False +1 < 2 < 3 # => True +2 < 3 < 2 # => False # Strings are created with " or ' "This is a string." 'This is also a string.' # Strings can be added too! -"Hello " + "world!" #=> "Hello world!" +"Hello " + "world!" # => "Hello world!" # A string can be treated like a list of characters -"This is a string"[0] #=> 'T' +"This is a string"[0] # => 'T' # % can be used to format strings, like this: "%s can be %s" % ("strings", "interpolated") @@ -92,12 +94,12 @@ not False #=> True "{name} wants to eat {food}".format(name="Bob", food="lasagna") # None is an object -None #=> None +None # => None # Don't use the equality "==" symbol to compare objects to None # Use "is" instead -"etc" is None #=> False -None is None #=> True +"etc" is None # => False +None is None # => True # The 'is' operator tests for object identity. This isn't # very useful when dealing with primitive values, but is @@ -105,8 +107,8 @@ None is None #=> True # None, 0, and empty strings/lists all evaluate to False. # All other values are True -bool(0) #=> False -bool("") #=> False +bool(0) # => False +bool("") # => False #################################################### @@ -121,14 +123,14 @@ print "I'm also Python!" # No need to declare variables before assigning to them. some_var = 5 # Convention is to use lower_case_with_underscores -some_var #=> 5 +some_var # => 5 # Accessing a previously unassigned variable is an exception. # See Control Flow to learn more about exception handling. some_other_var # Raises a name error # if can be used as an expression -"yahoo!" if 3 > 2 else 2 #=> "yahoo!" +"yahoo!" if 3 > 2 else 2 # => "yahoo!" # Lists store sequences li = [] @@ -136,63 +138,63 @@ li = [] other_li = [4, 5, 6] # Add stuff to the end of a list with append -li.append(1) #li is now [1] -li.append(2) #li is now [1, 2] -li.append(4) #li is now [1, 2, 4] -li.append(3) #li is now [1, 2, 4, 3] +li.append(1) # li is now [1] +li.append(2) # li is now [1, 2] +li.append(4) # li is now [1, 2, 4] +li.append(3) # li is now [1, 2, 4, 3] # Remove from the end with pop -li.pop() #=> 3 and li is now [1, 2, 4] +li.pop() # => 3 and li is now [1, 2, 4] # Let's put it back li.append(3) # li is now [1, 2, 4, 3] again. # Access a list like you would any array -li[0] #=> 1 +li[0] # => 1 # Look at the last element -li[-1] #=> 3 +li[-1] # => 3 # Looking out of bounds is an IndexError -li[4] # Raises an IndexError +li[4] # Raises an IndexError # You can look at ranges with slice syntax. # (It's a closed/open range for you mathy types.) -li[1:3] #=> [2, 4] +li[1:3] # => [2, 4] # Omit the beginning -li[2:] #=> [4, 3] +li[2:] # => [4, 3] # Omit the end -li[:3] #=> [1, 2, 4] +li[:3] # => [1, 2, 4] # Select every second entry -li[::2] #=>[1,4] +li[::2] # =>[1, 4] # Revert the list -li[::-1] #=> [3, 4, 2, 1] +li[::-1] # => [3, 4, 2, 1] # Use any combination of these to make advanced slices # li[start:end:step] # Remove arbitrary elements from a list with "del" -del li[2] # li is now [1, 2, 3] +del li[2] # li is now [1, 2, 3] # You can add lists -li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li and other_li is left alone +li + other_li # => [1, 2, 3, 4, 5, 6] - Note: li and other_li is left alone # Concatenate lists with "extend()" -li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] +li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] # Check for existence in a list with "in" -1 in li #=> True +1 in li # => True # Examine the length with "len()" -len(li) #=> 6 +len(li) # => 6 # Tuples are like lists but are immutable. tup = (1, 2, 3) -tup[0] #=> 1 +tup[0] # => 1 tup[0] = 3 # Raises a TypeError # You can do all those list thingies on tuples too -len(tup) #=> 3 -tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6) -tup[:2] #=> (1, 2) -2 in tup #=> True +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True # You can unpack tuples (or lists) into variables a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 @@ -208,60 +210,60 @@ empty_dict = {} filled_dict = {"one": 1, "two": 2, "three": 3} # Look up values with [] -filled_dict["one"] #=> 1 +filled_dict["one"] # => 1 # Get all keys as a list with "keys()" -filled_dict.keys() #=> ["three", "two", "one"] +filled_dict.keys() # => ["three", "two", "one"] # Note - Dictionary key ordering is not guaranteed. # Your results might not match this exactly. # Get all values as a list with "values()" -filled_dict.values() #=> [3, 2, 1] +filled_dict.values() # => [3, 2, 1] # Note - Same as above regarding key ordering. # Check for existence of keys in a dictionary with "in" -"one" in filled_dict #=> True -1 in filled_dict #=> False +"one" in filled_dict # => True +1 in filled_dict # => False # Looking up a non-existing key is a KeyError -filled_dict["four"] # KeyError +filled_dict["four"] # KeyError # Use "get()" method to avoid the KeyError -filled_dict.get("one") #=> 1 -filled_dict.get("four") #=> None +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None # The get method supports a default argument when the value is missing -filled_dict.get("one", 4) #=> 1 -filled_dict.get("four", 4) #=> 4 +filled_dict.get("one", 4) # => 1 +filled_dict.get("four", 4) # => 4 # "setdefault()" inserts into a dictionary only if the given key isn't present -filled_dict.setdefault("five", 5) #filled_dict["five"] is set to 5 -filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5 +filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5 +filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5 # Sets store ... well sets empty_set = set() # Initialize a "set()" with a bunch of values -some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4]) +some_set = set([1, 2, 2, 3, 4]) # some_set is now set([1, 2, 3, 4]) # Since Python 2.7, {} can be used to declare a set -filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} # Add more items to a set -filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} +filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} # Do set intersection with & other_set = {3, 4, 5, 6} -filled_set & other_set #=> {3, 4, 5} +filled_set & other_set # => {3, 4, 5} # Do set union with | -filled_set | other_set #=> {1, 2, 3, 4, 5, 6} +filled_set | other_set # => {1, 2, 3, 4, 5, 6} # Do set difference with - -{1,2,3,4} - {2,3,5} #=> {1, 4} +{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} # Check for existence in a set with in -2 in filled_set #=> True -10 in filled_set #=> False +2 in filled_set # => True +10 in filled_set # => False #################################################### @@ -337,17 +339,18 @@ def add(x, y): return x + y # Return values with a return statement # Calling functions with parameters -add(5, 6) #=> prints out "x is 5 and y is 6" and returns 11 +add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 # Another way to call functions is with keyword arguments add(y=6, x=5) # Keyword arguments can arrive in any order. + # You can define functions that take a variable number of # positional arguments def varargs(*args): return args -varargs(1, 2, 3) #=> (1,2,3) +varargs(1, 2, 3) # => (1, 2, 3) # You can define functions that take a variable number of @@ -356,7 +359,8 @@ def keyword_args(**kwargs): return kwargs # Let's call it to see what happens -keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"} +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} + # You can do both at once, if you like def all_the_args(*args, **kwargs): @@ -372,9 +376,10 @@ all_the_args(1, 2, a=3, b=4) prints: # Use * to expand tuples and use ** to expand kwargs. args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} -all_the_args(*args) # equivalent to foo(1, 2, 3, 4) -all_the_args(**kwargs) # equivalent to foo(a=3, b=4) -all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4) +all_the_args(*args) # equivalent to foo(1, 2, 3, 4) +all_the_args(**kwargs) # equivalent to foo(a=3, b=4) +all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4) + # Python has first class functions def create_adder(x): @@ -383,23 +388,24 @@ def create_adder(x): return adder add_10 = create_adder(10) -add_10(3) #=> 13 +add_10(3) # => 13 # There are also anonymous functions -(lambda x: x > 2)(3) #=> True +(lambda x: x > 2)(3) # => True # There are built-in higher order functions -map(add_10, [1,2,3]) #=> [11, 12, 13] -filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] +map(add_10, [1, 2, 3]) # => [11, 12, 13] +filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] # We can use list comprehensions for nice maps and filters -[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] -[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] #################################################### ## 5. Classes #################################################### + # We subclass from object to get a class. class Human(object): @@ -413,7 +419,7 @@ class Human(object): # An instance method. All methods take "self" as the first argument def say(self, msg): - return "%s: %s" % (self.name, msg) + return "%s: %s" % (self.name, msg) # A class method is shared among all instances # They are called with the calling class as the first argument @@ -432,18 +438,18 @@ i = Human(name="Ian") print(i.say("hi")) # prints out "Ian: hi" j = Human("Joel") -print(j.say("hello")) #prints out "Joel: hello" +print(j.say("hello")) # prints out "Joel: hello" # Call our class method -i.get_species() #=> "H. sapiens" +i.get_species() # => "H. sapiens" # Change the shared attribute Human.species = "H. neanderthalensis" -i.get_species() #=> "H. neanderthalensis" -j.get_species() #=> "H. neanderthalensis" +i.get_species() # => "H. neanderthalensis" +j.get_species() # => "H. neanderthalensis" # Call the static method -Human.grunt() #=> "*grunt*" +Human.grunt() # => "*grunt*" #################################################### @@ -452,12 +458,12 @@ Human.grunt() #=> "*grunt*" # You can import modules import math -print(math.sqrt(16) )#=> 4 +print(math.sqrt(16)) # => 4 # You can get specific functions from a module from math import ceil, floor -print(ceil(3.7)) #=> 4.0 -print(floor(3.7)) #=> 3.0 +print(ceil(3.7)) # => 4.0 +print(floor(3.7)) # => 3.0 # You can import all functions from a module. # Warning: this is not recommended @@ -465,7 +471,7 @@ from math import * # You can shorten module names import math as m -math.sqrt(16) == m.sqrt(16) #=> True +math.sqrt(16) == m.sqrt(16) # => True # Python modules are just ordinary python files. You # can write your own, and import them. The name of the @@ -486,10 +492,12 @@ def double_numbers(iterable): for i in iterable: yield i + i -# generator creates the value on the fly -# instead of generating and returning all values at once it creates one in each iteration -# this means values bigger than 15 wont be processed in double_numbers -# note range is a generator too, creating a list 1-900000000 would take lot of time to be made +# A generator creates values on the fly. +# Instead of generating and returning all values at once it creates one in each +# iteration. This means values bigger than 15 wont be processed in +# double_numbers. +# Note range is a generator too. Creating a list 1-900000000 would take lot of +# time to be made _range = range(1, 900000000) # will double all numbers until a result >=30 found for i in double_numbers(_range): @@ -500,7 +508,8 @@ for i in double_numbers(_range): # Decorators # in this example beg wraps say -# Beg will call say. If say_please is True then it will change the returned message +# Beg will call say. If say_please is True then it will change the returned +# message from functools import wraps @@ -523,8 +532,6 @@ def say(say_please=False): print(say()) # Can you buy me a beer? print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( - - ``` ## Ready For More?