forked from akkana/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython-cheatsheet.py
More file actions
executable file
·348 lines (297 loc) · 9.87 KB
/
python-cheatsheet.py
File metadata and controls
executable file
·348 lines (297 loc) · 9.87 KB
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
345
346
347
348
#!/usr/bin/env python
# This is a file of reminders of various neat Python features
# that I always forget how to use.
# On #python as of early 2017, recommended beginning Python books include
# http://greenteapress.com/wp/think-python-2e/
# https://automatetheboringstuff.com/
# (the oft-recommended "Learn Python the Hard Way" is not well favored).
# I can't vouch for these books myself.
########################################################
# What's available in objects and modules?
########################################################
# Show methods in an object
dir(obj)
# Does a function exist in a module?
hasattr(os, 'get_terminal_size'):
# You can also get with a default:
getattr(os, 'get_terminal_size', "Doesn't exist")
# Is something a particular type? (But of course duck-typing is better.)
if type(s) is str:
print("It's a string")
# More deprecated:
if type(s) == types.StringType:
print "It's a string"
########################################################
# Stringy stuff
########################################################
# Decode vs. Encode:
# "string of bytes".decode('utf-8') --> unicode
# u"unicode string".encode('utf-8') --> bytes
# Either of these can take
# errors='replace', 'ignore', 'backslashreplace', 'xmlcharrefreplace'
>>> u = u'piñon'
>>> u
u'pi\xf1on'
# For Python3 skip to the end of this file.
# Split a long string over multiple lines in the source file
url1 = ( "http://www.crummy.com/software/BeautifulSoup/"
"bs3/documentation.html" )
# Note no commas in the parenthesized one:
# parentheses without a comma inside are just grouping, not a tuple.
(42) # is type int
(42,) # is a tuple with len 1
# You can also use a backslash and no parentheses:
url2 = "http://www.crummy.com/software/BeautifulSoup/" \
"bs3/documentation.html"
#
# Fuzzy string match.
# SequenceMatcher's first argument is a function that returns true for
# characters considered to be "junk". For instance, if blanks are junk,
# lambda x: x == " "
# To consider nothing as junk, pass None.
#
from difflib import SequenceMatcher
best_ratio = -1
best_match = None
for b in string_list:
r = SequenceMatcher(None, matchname, b).ratio()
if r > best_ratio:
best_match = b
best_ratio = r
########################################################
# iterator, list and dictionary helpers
########################################################
# Pairwise loops with zip():
names = ["Eiffel Tower", "Empire State", "Sears Tower"]
heights = [324, 381, 442]
for name, height in zip(names, heights):
print "%s: %s meters" % (name, height)
# Or make a dictionary from a zip():
tall_buildings = dict(zip(names, heights))
print max(tall_buildings.values())
#
# Read a file of name=value pairs and return a dictionary.
#
# https://mail.python.org/pipermail/baypiggies/2015-October/009556.html
def file2dict(filename):
with open(filename) as af:
return dict(line.strip().split('=',1) for line in af)
#
# Walk a directory tree
#
def walkfiles(rootdir):
for root, dirs, files in os.walk(rootdir):
for f in files:
print os.path.join(root, f)
########################################################
# Dates and times
########################################################
#
# Parse a date in RFC 2822 format.
#
# email.utils.parsedate returns a tuple.
t = time.mktime(email.utils.parsedate("Thu, 11 Aug 2016 14:46:50 GMT")))
(y, m, d, h, m, s, weekday, yearday, isdst) = t
# the last three items of the tuple aren't very useful: typically 0, 1, -1.
# -1 means "unknown" for the dst flag.
secs_since_epoch = time.mktime(t)
t2 = time.mktime_tz(email.utils.parsedate("Thu, 11 Aug 2016 14:46:50 GMT")))
(y, m, d, h, m, s, weekday, yearday, isdst, offset_from_utc) = t2
secs_since_epoch = email.utils.mktime_tz(t2)
#
# Parse a date in unknown format into a datetime.datetime object
#
import dateutil.parser
d = dateutil.parser.parse("2012-08-16 14:25:05.265739")
d = dateutil.parser.parse("10/31/2016 14:25")
d = dateutil.parser.parse("6/15/2016 14:25 MDT")
# Also see the Arrow library, a Datetime replacement
# that offers super-general date parsing like "an hour ago".
#
# Add N months to a date: same day of month but next month.
#
import datetime
from dateutil.relativedelta import relativedelta
today = datetime.date.today()
three_months_from_now = today + relativedelta(months=3)
# Note that relativedelta can also take a month= as well as a months=.
# month gives you the current dayofmonth in a specific month number;
# months gives you how many months relative to the current one.
# For differences of just days or weeks, datetime.timedelta works.
#
# Another way using calendar but not dateutils:
#
import datetime
import calendar
today = datetime.date.today()
days_this_month = calendar.monthrange(today.year, today.month)[1]
one_month_from_now = today + datetime.timedelta(days=days_this_month)
########################################################
# Lambda foo
########################################################
#
# map + lambda example
#
def helloall(names):
return '\n'.join(map(lambda name: "Hello, " + name, names))
#
# filter + lambda example
#
def only_even(numbers):
return filter(lambda x: x%2 == 0, numbers)
#
# Simple map used for rounding.
# int() truncates, round() rounds but doesn't return an int.
#
def roundall(numbers):
return map(int, map(round, numbers))
#
# sorting + lambda examples.
#
# The cmp function is obsolete.
# Instead, use a key function,
# which is called on each element of the list prior to sorting.
# https://wiki.python.org/moin/HowTo/Sorting
#
def sort_by_last_letter(words):
# sorted() returns a new sorted list.
print sorted(words, key = lambda a: a[-1])
# list.sort() modifies the list in place
words.sort(key = lambda a: a[-1])
print words
#
# Reduce example
#
# https://mail.python.org/pipermail/baypiggies/2015-September/009548.html
# Note: There's also collections.Counter.
def letter_frequency(data):
def count(total, item):
total[item] = total.get(item, 0) + 1
return total
return reduce(count, data, {})
if __name__ == "__main__":
import os
print "This is file: ", __file__
print "which is really:", os.path.realpath(__file__)
#
# Enum values in PyGTK. I'm forever running up against dialogs that
# return some random undocumented negative number from run(),
# and there's no way to find out which gtk.RESPONSE_FOO
# the negative number corresponds to.
#
def enumval(e):
for i in range(-1000, 1000):
if e == i:
return i
return None
# This is also a useful hint for how to look up an arbitrary string
# in the environment.
# list from http://www.pygtk.org/pygtk2reference/gtk-constants.html#gtk-response-type-constants
for s in ("NONE", "REJECT", "ACCEPT", "DELETE_EVENT", "OK", "CANCEL", "CLOSE", "YES", "NO", "APPLY", "HELP"):
print s, eval("enumval(gtk.RESPONSE_" + s + ")")
# As of Dec 2016, this gives:
# NONE -1
# REJECT -2
# ACCEPT -3
# DELETE_EVENT -4
# OK -5
# CANCEL -6
# CLOSE -7
# YES -8
# NO -9
# APPLY -10
# HELP -11
######################################################
# Decorators -- attempt at a useful example.
######################################################
#
# Timer decorator without arguments:
#
import time
def timing_function(fn):
"""
Returns the time a function takes to execute.
"""
def wrapper():
t1 = time.time()
fn()
t2 = time.time()
return "It took: %s" % str(t2 - t1)
return wrapper
@timing_function
def sumit():
bignum = 100000
tot = 0
for num in (range(0, bignum)):
tot += num
print("Sum (0-%d) = %d" % (bignum, tot))
output = sumit()
print("output = '%s'" % str(output))
#
# But adding an argument is counterintuitive.
# If you give sumit an argument, sumit(bignum),
# that's taken as being an argument for wrapper(), not for fn().
# If you want sumit() to take an argument, you have to do it this way:
#
def timing_function(fn):
"""
Returns the time a function takes to execute.
"""
def wrapper(outer_arg): # outer_arg is the arg passed to sumit
def wrapped(*args):
t1 = time.time()
fn(outer_arg)
t2 = time.time()
return "%d: It took: %s" % (outer_arg, str(t2 - t1))
return wrapped(fn) # This is what gets returned when you call sumit(x)
return wrapper
@timing_function
def sumit(bignum):
tot = 0
for num in (range(0, bignum)):
tot += num
print("Sum (0-%d) = %d" % (bignum, tot))
output = sumit(100000)
print("output = '%s'" % str(output))
#
# What if you want the decorator to also take arguments?
#
def repeat_timing_function(numreps):
def wrap(fn):
def wrapped_f(*args):
# args are the args to the outside function (=bignum)
# arg1, arg2, arg3 are the decorator arguments (=numreps)
t1 = time.time()
for i in range(numreps):
fn(*args)
t2 = time.time()
return "%d: It took: %s" % (args[0], str(t2 - t1))
return wrapped_f
return wrap
@repeat_timing_function(5)
def summit(bignum):
tot = 0
for num in (range(0, bignum)):
tot += num
print("Sum (0-%d) = %d" % (bignum, tot))
output = summit(100000)
print("output = '%s'" % str(output))
################################################################
# Python3 differences
################################################################
# Migrate python2 to python3 in place (omit -n to leave a .bak):
$ 2to3 -wn file_or_directory
# All strings in python3 are automatically unicode,
# and you can just pass encoding as a second argument when you
# coerce between str and byte, no need to remember encode/decode.
# Encode/decode in PYTHON3:
>>> str(b'string of bytes')
'string of bytes'
>>> str(b'string of bytes', 'utf-8')
'string of bytes'
>>> bytes('piñon', 'utf-8')
b'pi\xc3\xb1on'
>>> str(b'pi\xc3\xb1on')
"b'pi\\xc3\\xb1on'"
>>> str(b'pi\xc3\xb1on', 'utf-8')
'piñon'