· 9 years ago · May 08, 2017, 10:36 AM
1# PEP 8
2
3'''
4 - Long expressions' continuation should begin with 4 spaces of indent
5 - Functions and classes separated by 2 spaces
6 - One space before and after assignment
7'''
8## Naming stuff:
9
10''' functions, variables, and attributes: '''
11lower_underscore
12
13''' protected: '''
14_leading_underscore
15
16''' private: '''
17__double_leading_underscore
18
19''' classes and exceptions: '''
20CapitalizedWord
21
22''' module-level constants: '''
23ALL_CAPS
24
25
26## Misc
27
28
29# TYPES, OPERATORS, AND VARIABLES
30
31 # You can use either ' ' or " " for strings, just stick with one
32'string'
33"string"
34
35 # Concatenate strings:
36'Hello ' ' world' # >>> 'Hello world'
37
38'Alice' * 5 # >>> AliceAliceAliceAliceAlice
39
40 # Get length of a string:
41len(string)
42
43 # Variables are created as you give them value.
44
45 # input function always returns a string so you have to convert it later
46name = input("What's your name? ")
47
48 # Print a string:
49print("Hello there " + name)
50
51 # Or use placeholders
52print("Hello there {0} from {1}".format(name, "New York")
53
54 # Change the separator and strip the newline character
55print("cat", "dog", "mouse", sep="_", end='') # >>> cat_dog_mouse
56
57 # Formatted strings: {placeholder: format_specifier}
58 # The general format of the specifier:
59 # [[fill[allign]][sign][0][width][.precision][type]
60'{0:#^10}'.format('Anna') # => ###Anna###
61 # Allignment > - right, < - left, ^ - center
62
63 # Logical:
64and or not
65
66 # Relational and arythmetic operators are like in C, with the exception of
672 ** 3 # >>> 8
68
69 # Comparision operators can be chained
70>>> 1 < 5 < 7 # => True
71
72 # * and + operators create shallow copies:
73a = [3,4,5]
74b = 4*a # => b = [[3,4,5], [3,4,5]]
75a[0] = -7 # => b = [[-7, 4, 5], [-7, 4, 5]]
76
77 # Swap two values in-place
78x, y = y, x
79
80# CONTAINERS
81## Lists:
82l = []
83l.append(2)
84
85 # Length:
86len(list)
87
88l = 'abcdefg'
89 # Get last item of the list:
90l[-1]
91
92 # Get first 5 items of the list:
93l[:5] # => abcde
94
95 # Get last 5:
96l[-5:]
97
98 # Copy a to to b
99b = a[:]
100
101 # Point bo to the same list
102b = a
103
104 # is checks if two variables point to the same object, == checks if those
105 # objects have the same value.
106a = [1, 2, 3, 4]
107b = [1, 2, 4, 5]
108a == b # >>> True
109a is b # >>> False
110
111 # Check if value is in the list
112animals = ["cat", "dog", "mouse"]
113>>> 'cat' in animals
114True
115
116>>> 'elephant' in animals
117False
118
119 # Also:
120vowels = ['aeiouyAEIOUY']
121>>> 'A' in vowels
122True
123
124 # Tuples are immutable:
125animals = ("cat", "dog", "mouse")
126>>> animals[i] = "elephant" # => ERROR
127
128 # Convert tuple, or string to a list:
129>>> list('hello')
130['h', 'e', 'l', 'l', 'o']
131
132 # All sequences can be unpacked into a sequence of variables
133l = [1, 2, 3]
134a,b,c = l # => a = 1, b = 2, c = 3
135
136letters = 'abc'
137x,y,z = letters
138
139 # Check if list is empty:
140if not l:
141 # Do something
142
143
144## Dictionaries
145
146 # Dictionaries map the key to the values. They are not ordered however,
147 # so you can't slice them:
148colors = {"red": "#FF0000", "green": "#00FF00", "blue": "#0000FF"}
149
150>>> colors["red"] # => #FF0000
151
152 # It's often better to use the get method, because it doesn't raise the
153 # exception when the key is not in the dict (it gives None)
154>>> colors.get('green') # => #00FF00
155>>> colors.get('yellow') # => None
156
157
158 # These methods returns iterables
159colors.values() # => #FF0000, #00FF00, #0000FF
160colors.keys() # => red, blue, green
161colors.items() # => ('red', '##FF0000') ...
162
163 # You can iterate over them like:
164for v in colors.values():
165 print(v)
166
167 # Or use them to check if sth is in the dictionary:
168>>> "green" in colors.keys()
169True
170
171 # Use list comprehensions to derive one list from another:
172a = [1, 2, 3, 4, 5]
173squares = [x**2 for x in a] # => [1, 4, 9, 16, 25]
174
175 # Filter results you don't want:
176even_squares = [x**2 for x in a if x % 2 == 0] # => [4, 16]
177
178 # Nested:
179a = [-1, 1, 2, 3]
180b = 'abc'
181c = [(x, y) for x in a for y in b if x > 0]
182
183 # It's a little more clear with indentation:
184c = [(x, y) for x in a
185 for y in b
186 if x > 0]
187
188 # Generator expressions is similiar to list comprehension, but it doesn't
189 # produce a list immediately, instead it returns a generator object that
190 # produces the values on demand during iteration:
191a = [1,2,3,4]
192b = (x*10 for x in a)
193b.__next__() # => 10
194b.__next__() # => 20
195
196 # Generator expressions are better performence-wise, for example when
197 # parsing some text files you don't have to read the entire file at once.
198 # Use generator expressions when you only need to iterate over something
199 # once, and when the sequence is very large or infinite, otherwise use
200 # list comprehensions
201
202
203
204## Sets
205
206 # Set is an unordered collection with no duplicates
207some_set = {1, 2, 3, 4, 1, 2} # => {1, 2, 3, 4}
208
209 # They use {} to initialize them, but empty set is created like this:
210s = set()
211
212 # Add one element to the set:
213s.add('cat')
214
215 # Add multiple elements:
216s.update(['dog', 'mouse'])
217
218#CONTROL FLOW
219
220 # If is the same as everywhere
221if a > 10:
222 print("Will print this if a > 10 is true")
223elif a > 2:
224 print("Will print this if a > 2 is true and the if clause isn't")
225else:
226 print("Print this in all the other cases")
227
228 # while loop looks like this, and you can use break and continue in loops
229while True:
230 koniec = input()
231 if koniec == "koniec":
232 break
233
234 # for loop iterate over lists:
235for animal in ["Dog", "Elephant", "Cat", "Mouse"]:
236 print(animal)
237
238 # We can use range() function to generate a list of the numbers
239for i in range(0, 10, 2):
240 print(i)
241 # >>> 0, 2, 4, 6, 8
242
243 # If you want to loop over something like a list of strings, but also
244 # need to get the index, use enumerate function
245colors = ['blue', 'red', 'green', 'yellow']
246for i, color in enumerate(colors):
247 print('{}: {}'.format(i+1, color)
248
249 # enumerate creates a list of tuples with a string and a number, this
250 # instruction unpacks the tuples into i & color
251
252 # You can apply a second parameter to specify where it'll start counting:
253for i, color in enumerate(colors, 1)
254
255 # Use zip to iteratore over multiple iterarators (?) at the same time:
256countries = ['United Kingdom', 'Poland', 'Czech Republic']
257capitals = ['London', 'Warsaw', 'Prague']
258
259for country, capital in zip(countries, capitals):
260 print(country, capital)
261
262 # Zip creates a list of tuples [(countries[0], capitals[0]), ...]
263
264# FUNCTIONS
265
266 # Declare simple functions with def
267def print_hello():
268 print("HELLO")
269
270 # Inwoke them like this:
271print_hello()
272
273 # Functions can obviously take arguments and return values
274def add(a, b):
275 return int(a) + int(b)
276
277 # To access global variable inside a function use global keyword:
278a = 10
279
280def change_a():
281 global a
282 a = 5
283
284 # If you don't do this, local variable with the same name is created
285def doesnt_change_a():
286 a = 5
287
288doesnt_change_a()
289print(a) # => 10
290
291 # Generator is a function that produces a sequence as a result
292def count(n):
293 print('Counting to {}'.format(n))
294 for i in range(1, n+1):
295 yield i
296 return
297
298 # yield is like return, except that it doesn't quit the function
299 # The following doesn't execute, instead it returns a generator object
300c = count(10)
301
302 '''
303 If the last argument in a function definition begins with **, all
304 additional keyword arguments are placed in a dictionary and passed to
305 function (useful for configuration options etc.)
306 - args i a tuple of positional arguments
307 - kwargs is a dictionary of keyword args '''
308def spam(*args, **kwargs):
309 pass
310
311
312# CLASSES AND OOP
313
314class Dog:
315 ''' Class definition and methods should start with docstrings
316 describing what they do '''
317 # Class variable shared by all instances
318 counter = 0
319
320 def __init__(self, name):
321 # Instance variable
322 self.name = name
323 Dog.counter += 1
324
325 # Local variable, can't be accessed from other methods
326 var = 3
327
328 # A static method is an ordinary function that just happen to live in
329 # the namespace of the class
330class Foo():
331 @staticmethod
332 def add(x,y):
333 return x+y
334x = Foo.add(3,4) # => x = 7
335
336 # properties are used like attributes, except they're read-only
337class Circle:
338 def __init__(self, radius):
339 self.radius = radius
340
341 @property
342 def area(self):
343 return 3.14*self.radius**2
344
345a = Circle(4)
346a.area # => 50.24
347
348''' Instance methods should use self as the name of the first parameter '''
349def __init__(self):
350 pass
351
352''' Class methods should use cls: (do we use cls like this?) '''
353def __init__(cls):
354 pass
355
356# EXCEPTIONS
357
358 # Catch all exceptions except for those related to program quit
359try:
360 # do something
361except Exception as e:
362 pass
363
364# DECORATORS
365
366 # Decorator is a function(for simplicity's sake) that takes a function
367 # object as an argument and returns a function object as a return value
368
369 # Decorators are used to add features to original function, in other words
370 # they are used to create a function that does roughly the same stuff as
371 # the original function but with some additional stuff
372
373 # EXAMPLES:
374
375 # Our decorator:
376def p_decorator(original_func):
377 def new_func(name):
378 return '<p>{0}</p>'.format(original_func(name))
379 return new_func
380
381 # The function we'll decorate
382def get_text(name):
383 return 'So your name is {0}'.format(name)
384
385 # We could use this like this:
386my_get_text = p_decorator(get_text)
387print(my_get_text("Albert")) # => <p>So your name is Albert</p>
388
389 # Or even like this:
390get_text = p_decorator(get_text)
391
392 # But Python provides some syntatic sugar, so we apply the decoration before
393 # the definition of the function we want to decorate:
394@p_decorator
395def get_text(name):
396 return 'So your name is {0}'.format(name)
397
398 # And now we just use
399print(get_text("Andżej"))
400 # and there's no way to use the original function without the decoration
401
402
403 # Decorators can take arguments:
404def add_tag(tag_name):
405 def tag_decorate(func):
406 def wrapper(name):
407 return '<{0}>{1}</{0}>'.format(tag_name, func(name))
408 return wrapper
409 return tag_decorate
410
411 # And decorations can be stacked:
412
413@add_tag('div')
414@add_tag('p')
415def get_text(name):
416 return 'So your name is {0}'.format(name)
417
418print(get_text('Antoni')) # => <div><p>So your name is antoni</p></div>
419
420 # BEST EXAMPLE:
421def verbose(original_function):
422 def new_function(*args, **kwargs):
423 print("Entering", original_function.__name__)
424 original_function(*args, **kwargs)
425 print("Exiting", original_function.__name__)
426 return new_function
427
428# WORKING WITH FILES
429
430 # The builtin function open() opens a file and returns a file object
431 # open(filename [,mode [, bufsize]])
432f = open('foo', 'r')
433
434 '''
435 File modes:
436 - r - read, text mode
437 - w - write, text mode
438 - a - append, text mode
439 - r+ - read and write
440 - w+ - read and write, but file is first truncated
441 - rb - read, binary mode
442 - wb - write, binary mode
443 - ab - append, binary mode
444 '''
445
446 # Read some data and return it as a string
447f.read(size)
448
449 # Read a line
450f.readline()
451
452 # To read lines from a file you can also loop over the file object:
453for line in f:
454 print(line, end='')
455
456 # Writes the conents of a string to the file and returns the number of
457 # characters written.
458f.write('This is a test\n') # => 15
459
460 # Redirect the output of print funcion to a file:
461print('The values are', x, y, z, file = f)
462
463 # Good practice: use with keyword when dealing with file object. It makes
464 # sure that the file is properly closed.
465with open('file', 'r') as f:
466 read_data = f.read()
467
468# MODULES
469
470 # Best style of importing:
471import random # random.randint()
472import random as rn # rn.randint()
473
474 # After that you can use stuff from random like this:
475random.randint(1,10)
476
477 # You can also just import one function like:
478from random import randint
479
480 # And use it like:
481randint(1, 10)
482
483 # Imports all the definitions in a module except for those starting with _
484 # (Avoid this)
485from random import *
486
487 # Check if file is being executed directly or imported as a module:
488if __name__ == '__main__':
489 # yep
490else:
491 # it must've been a module
492
493 # Get the file path of imported module
494print(random)
495
496## SYS MODULE
497
498import sys
499
500 # Get the number of arguments
501len(sys.argv)
502
503 # The first arg is always the name of the file:
504sys.argv[0]
505
506 # ~ need to get back to this
507 # For more advanced command-line handling use optparse
508import optparse
509
510## OS MODULE
511
512 # Walking down the path and adding files from subdirs to one list:
513import os
514
515def get_filepaths(directory):
516 file_paths = []
517 for (root, directories, files) in os.walk(directory):
518 for filename in files:
519 filepath = os.path.join(root, filename)
520 file_paths.append(filepath)
521 return file_paths
522## TIME
523
524import datetime
525
526a = datetime.datetime.now()
527a.strftime("%d-%m-%Y %H:%M") # => '13.04.2017 15:59'
528
529## REGULAR EXPRESSIONS
530
531 # They're in re module
532import re
533
534 # Match the sequence:
535s = "Hey, my email is ahmm@gmail.com, and what's yours?"
536re.search('\S@\S', s) # => ahmm@gmail.com
537
538 # Extract a match with ():
539match = re.search('(\w+)@(\w+.\w+)')
540
541match.group(0) # => ahmm@gmail.com
542match.group(1) # => ahmm
543match.group(2) # => gmail.com
544
545 # Gives a lists of all occurences of regex:
546s = "This thing costs $100.00, the other thing costs $50.00, and that one
547 is $36.50"
548re.findall('\$[0-9.]+', s) # => ['$100.00', '$50.00', '$36.50']
549
550 # Compile the pattern beforehand:
551pattern = re.compile(r'\w+@\w+.\w+')
552
553 # + and * are greedy by default:
554s = 'The-one-whose-name-cannot-be-spoken'
555re.findall('.+-', s) # => ['The-one-whose-name-cannot-be-']
556
557 # Non-greedy:
558re.findall('.+?-', s) # => ['The-', 'one-', 'whose-', 'name-', cannot-', 'be-']
559
560 # SPECIAL CHARACTERS:
561 . # match any character, except for newline
562 ^ # start of string
563 $ # end of string
564 * # match the preceding RE 0 or more times
565 + # match the preceding RE 1 or more times
566 ? # match the preceding RE 0 or 1 times
567 {m} # match exactly m copies
568 {m, n} # m to n
569 [] # set, examples:
570 [AEIOU], [A-Za-z], [0-9.]
571 [^5] # match anything but 5
572 A | B # match either A or B
573 () # extract everything between parantheses
574
575 # CHARACTER CLASSES:
576 \d # any digit [0-9]
577 \D # non digit [^0-9]
578 \s # any whitespace
579 \S # any non whitespace
580 \w # alhpanumeric [a-zA-Z0-9_]
581 \W # non-alphanumeric
582
583# EXTENSIONS
584## Markdown
585pip install flask-markdown
586
587import markdown
588
589content = """# This is a header
590** and this should be bold**"""
591mkd = markdown.markdown(content)