1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | # SI 413 Fall 2012 # Lab 11 # Python introduction ''' This Python program will serve as a basic introduction to the language. It has some basic changes for you to make too. Note that this is a Python 3 program. You have to run it using the "python3" command. First things first, you notice that single-line comments in Python start with a # symbol, like above. What we're in here is actually a multi-line string, which is started and ended with 3 single or double quotes. But multi-line strings like this one that aren't actually used anywhere can also serve as comments. Like this! ''' ##### DEFINITIONS ##### ''' Variable declarations and redeclarations look exactly the same! And there are no declared types, of course. (Everything here is just an int.) You will notice that statements do NOT end in a semicolon or anything else! A single line = a single statement. ''' x = 10 x *= 2 y = x + 3 # Use the print statement to... print things. print("----- DEFINITIONS -----") print(x) print(x,y) print() # Print with no arguments does an empty line. ''' Function definitions use the "def" keyword. The standard Python syntax is that a colon marks the beginning of a block (on the next line). One truly innovative syntactic idea in Python is that WHITESPACE MATTERS! Every line in a block must be indented the same amount of whitespace. If your text editor automatically converts spaces to tabs, use caution, because they are not the same to the Python interpreter. Although the whitespace for indentation can be any amount (as long as it is consistent), the official standard is to use 4 spaces (NO TABS!) for each indentation level. ''' def fun(x): return x + x*3 print(fun(12)) print(fun(fun(y))) print() ''' Python has lexical scope and functions are first-class. We can define functions within functions, return functions from functions, and there is even lambda for anonymous functions! ''' def make_counter(): count = 0 def increment(): nonlocal count count += 1 return count return increment C = make_counter() print(C(), C(), C(), C()) ''' Notice something odd in the function above? The "nonlocal" keyword indicates that the name "count" should not be a local variable to increment(), but rather should use the pre-existing local variable from make_counter(). The reason we have to do things like this is that Python doesn't distinguish syntactically between variable declaration and re-assignment. By default, the first use of a variable within a scope makes a declaration. The "nonlocal" overrides this behavior. There is a similar keyword "global" that can be used to indicate variables should have global scope instead of local. ''' fun_alt = lambda y: y + y*3 print(fun(7), fun_alt(7)) print() ##### DATA TYPES ##### print('----- DATA TYPES -----') ''' Python includes a number of built-in data types such as int, float, list, tuple, and dict. To learn about their built-in operations, you can type something like "help(int)" inside the interpreter to get the full documentation. You can also covert between many of the built-in types; to do so, just use the name of the type as a function. Let's start with numbers. ''' print(float(20)) print(int(13.5)) # Most arithmetic operators work like you're used to. print(1+2*3-4) # The division operator / always does EXACT division # To do integer division (quotient), use // print(4/3, 4//3) # Exponentiation is built-in using the ** operator. print(3**2) # The "mod" operator is what you're used to, but there is also a special # global function divmod that produces the quotient and remainder # at the same time. print(28//5, 28%5) print(divmod(28,5)) print() ''' Booleans are pretty straightforward. True and False are the literals, and you can do "and", "or", and "not". ''' print(True, False, 3<5, True and True or not False) print() ''' Lists are an extremely important data type. You create lists with square brackets, and can manipulate them in all sorts of wonderful ways. (Run help(list) to see more!) ''' L=[] print(L, len(L)) #len is an extremely useful global function! L=[1,2,3,4] L.append(5) print(L, len(L)) L.sort() print(L) L = [5,3,1] print(sorted(L), L) # sorted just returns a sorted copy, whereas sort modifies the original. L.extend(['types','can','be','mixed']) L[1] = 'CHANGED!' print(L) print(['lists','can'] + ['be','added']) # Besides the usual access like L[1], you can also use negative numbers # to access from the back of the array. print("First element is", L[0]) print("Last element is", L[-1]) # And you can get ranges using the "slice" notation with a colon. print("First 2 elements are", L[:2]) print("Last 2 elements are", L[-2:]) print("Middle 2 elements are", L[2:4]) print() ''' Tuples are like lists, except that they are immutable. They can be quickly defined using parentheses. This can be slightly awkward since parentheses are also used to override precedence. To make a one-element tuple, you have to throw in an extra comma. ''' T = (1,2,3) print(T, len(T)) # len works for just about anything. print(T + (4,5) + (6,)) # Notice the extra parens below. # sorted always returns a list, even if its input is something else. print( sorted((9,8,7)) ) print() ''' Dictionaries are your basic hash map. You create them with curly brackets. You can use the square brackets on a dictionary to insert or retrieve elements. ''' D = { 'key': 'value', 'another key': 'another value', 5: ['types','can','mix'] } print(len({}), len(D)) print(D['key'], D[5]) D[20] = 7 D.pop('another key') print(D) # The "in" operator can be used to see if a key is there. print(20 in D) print(5 in D) print('value' in D) print() ##### CONTROL STRUCTURES #### print('----- CONTROL STRUCTURES -----') ''' if and if/else statements are fairly normal. You will notice the special keyword 'elif' to do an else-if case. ''' if 1 < 4: print('1 is less than 4') if False: print('Not here!') else: print('Here instead!') if 1 == 2: print('no') elif 2 == 2: print('yes') else: print('no') print() ''' while loops are just like you would expect. Like if's, no parens are needed around the conditional. ''' L=['a'] while len(L) < 5: L = L + L print(len(L), L) print() ''' for loops are a little different. The only kind of for loop in Python is a for-each loop to loop over all the items in some kind of "iterable" collection. ''' for a in [5,3,1]: print("For loop fun", a) # "range" makes a range to loop over. # This is how you do a typical for loop for i in range(5, 10): print(i,end=' ') # this makes it end with space not newline # Of course you can convert a range to a list. # And the third argument to range changes the "increment" value. print(list(range(10))) print(list(range(5, 10, 2))) print(list(range(10, 5, -1))) # You can loop over JUST ABOUT ANYTHING YOU WANT # remove the l's from hello noels='' for x in "hello": if x != 'l': noels = noels+x print(noels) for k in {1:2, 3:4}: print('The key is', k) print() ##### LIST COMPREHENSIONS ##### print('----- LIST COMPREHENSIONS -----') ''' List comprehensions are an awesome and special feature of Python that lets you make a list a fill it up with the contents of anything that is iterable. It is a very powerful and convenient syntax. The basic idea is to write [(some expression) for (name) in (iterable)]. Let's see some examples! ''' print([x for x in range(4)]) print(['really ' + s for s in ('I', 'like', 'Python')]) # zip is a useful utility to iterate over the tuples choosing one from # each input list. L1 = [4,5,6] L2 = [7,8,9] print([a*b for a,b in zip(L1,L2)]) # There is also a "map" function in Python to do something similar print(list(map(len,['help','me','rhonda']))) # You can add conditionals to the list comprehension for awesomeness! # (This makes a list with all multiples of 3.) print([x for x in range(20) if x % 3 == 0]) print() ##### GENERATORS ##### print('----- GENERATORS -----') ''' You can make your very own "iterable" type of thing with a generator function. The idea is that you replace a "return" statements with "yield" statements, and then your function will keep going to yield more and more things. Get excited for this one! ''' def longwords(): with open('/usr/share/dict/words', 'r') as English: # By the way, that's how you open a file for reading. for word in English: # By the way, that's how you loop over the lines in a file. word = word.strip() # This strips trailing whitespace. if len(word) > 18 and "'" not in word: yield word # Now we can loop over this FUNCTION like it's any other iterable thing for w in longwords(): print(w) # You can also get things out of an iterable manually, without a forloop. gen = longwords() print("The first long word is", next(gen)) print("The second long word is", next(gen)) print() |