print(x, end=' ')
instead of print(x) to escape the default line-changing-output.
print(str.ljust(size)) left-alignment with given size, samely, str.rjust(size) works just fine
1 # Can you talk about the differences between the following commands? 2 print('{}{}'.format(str1,str2)) 3 print('{1}{0}'.format(str1,str2)) 4 print('{sz1}{sz2}'.format(sz1=str1,sz2=str2)) 5 6 # using !a !s !r to cast conversion before print 7 print('{}'.format('eels')) #eels 8 print('{!r}'.format('eels')) #'eels' 9 10 # formatted output/floats, retain 3 digits after decimal point 11 import math 12 print('{0:.3f}'.format(math.pi)) 13 14 # % operator same as C/C++ usage is an older formatting 15 print('%5.3f' % math.pi)
File reading & writing:
It seems that python do not support read&write file in one opened file, means flags like 'rw' returns an error, anyone whose test result differs from what I get please contact me ! note My python version is 3.5.1 64 bit. From python's official document I get little about this infomation, either. If no flag specified, default open mode is 'r'.
1 # Open a file and assign it to f 2 f=open('file','w+') 3 f.write('somestring\n') 4 f.close() 5 with open('file','r+') as f: 6 f.read() 7 f.seek(0) 8 f.readline() 9 f.seek(0,0)# 0 = SEEK_SET, 1 = SEEK_CURRENT, 2 = SEEK_END 10 11 f.closed
read() returns all contents out of the file, make sure the memory is large enough.
The with syntax automatically close the file f when running out of the seg of the code.
Saving structured data with json:
json stands for JavaScript Object Notation. The process taking python data hierarchies and convert to string representations called serialization. Reconstructing the data from string representation is called deserialization. The string containing the data may store in a file or sent over net.
If you have an object 'x', view its JSON string representation with code:
1 x = [1,'simple','test'] 2 import json 3 json.dumps(x) 4 with open('file','w') as f: 5 json.dump(x,f) 6 with open('file','r') as f: 7 y = json.load(f)
This method can handle serialization of lists and dictionaries, but if to handle arbitrary class, use defined decoding method to serialize.
1 import json 2 def as_complex(dct) 3 if '__complex__' in dct: 4 return complex(dct['real'], dct['image']) 5 return dct 6 7 json.loads('{"__complex__": true, "real": 1, "image": 2}', 8 object_hook=as_complex) 9 # output (1 + 2j) 10 11 import decimal 12 json.loads('1.1', parse_float=decimal.Decimal) 13 # output Decimal('1.1')
Use separators to eliminate space:
1 import json 2 json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'),sort_keys=True) 3 # output '[1,2,3,{'4':5,'6':7}]'
1 #to test what I think 2 print(json.dumps({'4': 5, '6': 7}, sort_keys=True,indent=4,separators=('~','n'))) 3 #output, here "indent" will append /n to every element 4 #{ 5 # "4"n5~ 6 # "6"n7 7 #}
If repeated keys exist in an object, loading the specfic object will ignore the older version of the key and keep the newer/last key & value.
1 weird_json = '{"x": 1, "x": 2, "x": 3}' 2 json.loads(weird_json) 3 # {'x': 3}
Some JSON deserializer may set limits on:
- size of accepted JSON texts
- maximum level of nesting JSON objects & arrays
- number precision level
- content and maximum length of JSON strings
Defining Errors in Python by inherit class Exception:
1 class Error(Exception): 2 pass 3 4 class InputError(Error): 5 def __init__(self,expression,message): 6 self.expression = expression 7 self.message = message 8 9 class TransitionError(Error): 10 def __init__(self,previous,next,message): 11 self.previous = previous 12 self.next = next 13 self.message = message
raise certain Error as an instance:
1 raise InputError("Error1","line 11")
Unlike Java, naming the instance of error shall be like:
1 except InputError as err 2 # Now get the error Info 3 print(err.expression, err.message)
Remember that Exceptions not caught in the try-except part will be thrown out before/after (it is uncertain) the finally part as errors. So we need to catch every Error the program would throw.
Some Objects like files will have pre-defined clean-up actions such as the with-syntax, are indicated in their doc.
In Python, 3 important kinds of methods are instance method, class method and static method. In class method and instance method, the first parameter represents the class or instance that is being mentioned.
1 #!/usr/bin/python3 2 class A(obj): 3 # instance method 4 def foo(self): 5 print(self) 6 pass 7 # static method 8 @staticmethod 9 def foo2(): 10 pass 11 # class method 12 @classmethod 13 def foo3(cls): 14 print(cls)
Note the @ decorator is meaningful, not like @ in Java, it's a syntactic sugar.
1 @staticmethod 2 def foo2(): 3 pass 4 5 # is equal to 6 def foo2(): 7 pass 8 foo2 = staticmethod(foo2) 9 10 # the name after the decorator @ is a defined method name
Difference between the 3 kinds of methods:
- calling instance methods will pass the instance to the method as its first parameter
- calling class methods will pass the class to the method as its first parameter
- calling static methods will pass no parameter specific to class/instance to the method
Iterators:
1 for element in [1, 2, 3]: 2 print(element) 3 for element in (1, 2, 3): 4 print(element) 5 for key in {'one':1, 'two':2}: 6 print(key) 7 for char in "123": 8 print(char) 9 for line in open("myfile.txt"): 10 print(line, end='')
Generator Exps:
1 xv=[10,20,30] 2 yv=[7,5,3] 3 sum(x*y for x,y in zip(xv,yv)) # dot product 4 max((x,y) for x,y in zip(xv,yv)) # maximum of x, comparably maximal y of pair (x,y)
os.getcwd(), os.chdir('subpath'), os.system('mkdir newfolder')
shutil.copy(src,dest), shutil.move(src,dest)
regular exps:
re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat') # 'cat in the hat', means searching for two identical words and replace them with one
# same as ''cat in the the hat'.replace('the the', 'the')
math.cos(digi),math.log(digi,base)
random.choice(list), random.sample(list, count), random.random() # float
random.randrange(upperlimit)
statistics.mean(list), statistics.median(list), statistics.variance(list)
Check SciPy project for more numerical computation modules.
Internet Access:
1 from urllib.request import urlopen 2 with urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') as response: 3 for line in response: 4 line = line.decode('utf-8') # Decoding the binary data to text. 5 if 'EST' in line or 'EDT' in line: # look for Eastern Time 6 print(line) 7 8 # works fine with ASCII coded page 9 with urlopen('http://www.baidu.com') as res: 10 for line in res: 11 line = line.decode('utf-8') 12 if 'GMT' in line: 13 f.write(line)
1 server = smtplib.SMTP('http') 2 server.sendmail('from','to',"'content'") 3 server.quit()
Date & Time Module intros:
1 from datetime import date 2 now = date.today() 3 now.strftime("%B...") 4 5 birthday = date(2016,5,2) 6 age = now - birthday
Python Strings & Bytes:
2 kinds of words: strings are used process words locally, bytes are used to transfer or store. If needed to use a word for processing, decode it to ascii or unicode, if needed to transfer/store, encode it to utf-8.
strings: 'abc', '\u0061\u0062\u0063', u'\u0061\u0062\u0063'
bytes: b'abc', b'\xe4\xb8\xad'
cast conversion: b->s : b'abc'.decode(/'ascii'); s->b: 'abc'.encode('utf-8')
Data Compression:
First note that only bytes have this method, not strings like 'abc' rather b'abc' fits.
import zlib
s=b'some string to be compressed'
t = zlib.compress(s)
zlib.decompress(t)
zlib.crc32(s)
other compress modules: gzip, bz2, lzma, zipfile, tarfile
Performance Measurement:
1 #! /usr/bin/python3 2 from timeit import Timer 3 Timer('some work').timeit()
profile, pstats modules intros.
Quality Control:
doctest.testmod() # automatically test documentations ###sometest###
1 def average(values): 2 """Computes the arithmetic mean of a list of numbers. 3 4 >>> print(average([20, 30, 70])) 5 40.0 6 """ 7 return sum(values) / len(values) 8 9 import doctest 10 doctest.testmod() 11 12 """ 13 这里也可以写 14 """ 15 def multiply(a,b): 16 """ 17 >>> multiply(2,3) 18 6 19 >>> multiply('baka~',3) 20 'baka~baka~baka~' 21 """ 22 return a*b 23 24 if __name__ == '__main__': 25 import doctest 26 doctest.testmod(verbose=True)
unittest module is more comprehensive in that it is maintained in a separate file.
1 #! /usr/bin/python3 2 # testunit.py 3 # run in cmd by calling python testunit.py 4 import unittest 5 6 class MyNewTest(unittest.TestCase): 7 def setUp(self): 8 self.a = 1 9 def testPass(self): 10 self.a = self.a + 1 11 self.assertEqual(self.a, 2) 12 def testFail(self): 13 self.a = self.a + 1 14 self.assertEqual(self.a, 3) 15 def test3(self): 16 self.assertEqual(self.a, 1) 17 if __name__ == '__main__': 18 unittest.main()
Many other modules can be found, including xml, email, json, csv, sqlite3, gettext, locale, codecs.
Standard Lib - Part II:
reprlib:
use reprlib.repr to display a large or deeply nested containers with dots.
pprint: (pretty print which adds line breaks automatically)
1 import pprint 2 t = [[['black', 'cyan'], 'white', ['green', 'red']], [['magenta', 'yellow'], 'blue']]] 3 pprint.pprint(t, width = 30)
textwrap: (deletes any \n in string & add \n every width, replace \r with ' ', replace \t with \n)
1 import textwrap 2 doc = """ 3 some doc texts 4 """ 5 print(textwrap.fill(doc, width=40))
locale:
1 import locale 2 locale.setlocale(locale.LC_ALL,'English_United States.1252') 3 conv = locale.localeconv() # get a mapping of conventions 4 x = 1234567.8 5 locale.format("%d", x, grouping = True) 6 locale.format_string("%s%.*f", (conv['currency_symbol'], conv['frac_digits'], x), grouping = True)
Multi-threading:
1 #! /usr/bin/python3 2 import threading, zipfile 3 class AsyncZip(threading.Thread): 4 def __init__(self,infile,outfile): 5 threading.Thread.__init__(self) # mark the instance as new thread 6 self.infile = infile 7 self.outfile = outfile 8 def run(self): 9 f = zipfile.ZipFile(self.outfile,'w',zipfile.ZIP_DEFLATED) # file, write, compress method 10 f.write(self.infile) 11 f.close() 12 print('Finished background zip of:', self.infile) 13 14 bg = AsyncZip('mydata.txt','myarchive.zip') # create instance and init its values 15 bg.start() # start the thread from method run() 16 print('The main continues to run in foreground.') 17 18 bg.join() # wait for thread bg to finish 19 print('Main program waited until bg was done.') 20 21 i = threading.Thead.__init__ 22 i(bg) # prepares bg to be started again 23 bg.start() # run again 24 25 # compare to this (which works in a different way): 26 bg.__init__('mydata.txt','myarchive.zip') 27 bg.start()
Methods have return values, also classes have return values in python.
1 # in method 2 def m(value): 3 return value**2 4 5 # in class 6 class c: 7 def __init__(self,value): 8 self.value = value # define & init member value 9 def __repr__(self): 10 return self.value**2 11 12 >>> m(10) 13 100 14 >>> c(10) 15 100
Weak Refs:
used in cascaded items. Delete once, all related fileds are also deleted if assigned as weak references.
1 import weakref, gc 2 class A: 3 def __init__(self, value): 4 self.value = value 5 def __repr__(self): 6 return str(self.value) 7 8 a = A(10) # create a reference 9 d = weakref.WeakValueDictionary() 10 d['primary'] = a # does not create a reference 11 d['primary'] # fetch the object if it is still alive 12 13 del a # remove the one reference 14 gc.collect() # run garbage collection right away 15 16 d['primary'] # entry was automatically removed
array.array
collections.deque
bisect: # used to manipulate sorted lists; also known s.sort([reverse=True])
1 import bisect 2 scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')] 3 bisect.insort(scores, (300, 'ruby')) 4 scores 5 # get [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
... Only C/C++ have comma expression, java/python do not support it.
... from somelib import *
heapq:
1 # heapq 2 from heapq import heapify, heappop, heappush 3 data=[1,3,5,7,9,2,4,6,8,0] 4 heapify(data) # data is sorted in heap 5 heappop(data) # from left to right, small to big pop 6 heappush(data,-5) # add new entry in the right place, keeping the order
decimal:
1 # This Decimal lib is not a C/C++ like decimal, it's more of a Java BigDecimal, can be used in financial applications 2 # its precision can be adjusted by getcontext().prec by value 3 from decimal import * 4 Decimal('1')/Decimal(7) 5 # and more, like ln, exp, to_eng_string