Python: Difference between revisions
Line 571: | Line 571: | ||
print(line, end='') | print(line, end='') | ||
line = reader.readline() | line = reader.readline() | ||
</syntaxhighlight> | |||
= Packages = | |||
== Packages == | |||
Python finds packages by looking at sys.path. You can see this by doing | |||
<syntaxhighlight lang="python"> | |||
import sys | |||
sys.path | |||
# For entry 0 | |||
sys.path[0] | |||
# To add you can | |||
sys.path.append('/mypath'); | |||
</syntaxhighlight> | |||
Another approach is to add your path to PYTHONPATH | |||
<syntaxhighlight lang="bash"> | |||
export PYTHONPATH=$PYTHONPATH:/mypath | |||
</syntaxhighlight> | |||
== Make a Package == | |||
<syntaxhighlight lang="bash"> | |||
mkdir -p /mypath/reader | |||
touch /mypath/reader/__init__.py | |||
</syntaxhighlight> | |||
For a simple reader class the contents of __init__.py may be (absolute) | |||
<syntaxhighlight lang="python"> | |||
from reader.reader import Reader | |||
</syntaxhighlight> | |||
For a simple reader class the contents of __init__.py may be (relative) | |||
<syntaxhighlight lang="python"> | |||
from .reader import Reader | |||
</syntaxhighlight> | |||
== Controlling whats imported == | |||
You can do this by specifying the __all__ content. Looks like a def file in windows dlls. e.g. | |||
<syntaxhighlight lang="python"> | |||
from reader.compressed.bzipped import opener as bz2_opener | |||
from reader.compressed.gzipped import opener as gzip_opener | |||
__all__ = ['bz2_opener', 'gzip_opener'] | |||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 04:48, 17 July 2020
Intro
Python 2 and 3 differences
print "fred" // OK Python 2
print("fred") // Not OK Python 2
Whitespace
Uses full colon and four spaces instead of brackets e.g.
for i in range(5):
x = i * 10
print(x)
Rules
- Prefer four spaces
- Never mix spaces and tabs
- Be consistent on consecutive lines
- Only deviate to improve readability
Help
help(object) gives help. e.g. for the module math
help(math)
Scalar Types, Operators and Control
Types
- int (42)
- float (4.2)
- NoneType (None)
- bool ( True, False) 0 = False !=0 = True
Operators
- == value equality
- != value inequality
- < less-than
- > greater-than
- <= less-than or equal
- >= greater-than or equal
Control
if statementes
if True:
print("Its true")
h = 42
if h > 50:
print("Greater than 50")
elif h < 20:
print("Less than 20")
else:
print("Other")
while loops
while c != 0:
print(c)
c -= 1 // c = c-1
print("Its true")
while True:
response = input()
if int(response) % 7 == 0:
break
for loops
cities = ["London", "Paris", "Berlin"]
for city in cities:
print(city)
Data types
str
Double and single quotes are supported. Strings are immutable. Multiline
"""This is
a multiline
string"""
m = "This string\nspans multiple\nlines"
Raw Strings like c# @
path = r'C:\users\merlin\Documents'
Format string
m = "The age of {0} is {1}".format('Jim', 32)
print(m) // The age of Jim is 32
# Or without numbers
m = "The age of {} is {}".format('Jim', 32)
# f-strings are like c#
value = 3000
m = f"The value is {value}"
bytes
These work like strings, well ascii strings as and can be created like below
b'some bytpes'
print(b[0]) // 115
decoding to bytes
norsk = "some norsk characters"
data = norsk.encode('utf8')
norwegian = data.decode('utf8')
lists
General
List are a sequence of lists
m = [1,14,5]
// Can be different types
m = ['apple', 7, false]
// Add are mutable
b = []
b.append(1.666)
b.append(1.4444)
print(b) // [1.666, 1.4444]
// Constructor
print(list("characters")) // ['c','h','a','r','a','c','t','e','r','s']
Negative indexing
You can use negative indexing - errrr
s = [3,186,4431,74400, 1048443]
print(s[-1]) // 1048443
print(s[-2]) // 74400
Slicing
Subscript of lists can be achieved with the following
s = [3,186,4431,74400, 1048443]
print(s[1:3]) // 186, 4431
print(s[1:-1]) // 186, 4431, 74400
List Comprehension Syntax
Generally this is
[expr(item) for item in iterable]
words = "Why sometimes I have believed"
print([len(word) for word in words]) // [3,9, 1, 4, 8]
Dict
General
Dict are value pairs
m = {'1': 'Apple', '2': 'Orange'}
print(m['1']) // Apple
# Replaces
m['1'] = 'Banana']
print(m['1']) // Banana
# Update will add if it does not exist or replace
m.update(2:'Applie')
Dict Comprehensions
Like lists above
{expr(key:) expr(value) for item in iterable}
country_to_capital = { 'UK': 'London',
'Brazil': 'Brasilia',
'Sweden': 'Stockholm' }
capital_to_country = { capital: country for country, capital in country_to_capital.items()}
print(capital_to_country) // {'Brasilia': Brazil, 'London': 'UK', 'Stockholm': 'Sweden'}
Set
Set are values like a dictionary with no key and must be unique
k = {91,109}
k.add(54)
# Error if not found
k.remove(91)
# No Error if not found
k.discard(91)
With sets we can compare. e.g.
blue_eyes = {'Olivia','Harry', 'Lily', 'Jack','Amelia'}
blond_hair = {'Harry', 'Jack','Amelia', 'Mia','Joshua'}
# Combined
print(blue_eyes.union(blond_hair)) // {'harry','Jack','Amelia','Joshua','Mia','Olivia','Lily'}
# In both
print(blue_eyes.intersection(blond_hair)) // {'harry','Jack','Amelia'}
# Not in this
print(blond_hair.difference(blue_eyes)) // {'Mia','Joshua'}
# Not in other
print(blond_hair.symmetric_difference(blue_eyes)) // {'Mia','Joshua','Olivia','Lily'}
Tuples
Tuples look like lists but have round brackets.
t = ('Apple', 3.5, False)
# to make a single you need to use the trailing comma or it thinks it is a single type e.g.
t = ('Apple',)
# to index one with pairs use second index e.g
t = ((220,284),(220,285),(220,284),(220,281))
print(t[0][1])
Unpacking like javascript works and swapping
def minmax(items):
return min(items), max(items)
lower, upper = minmax([83, 33, 84,32, 85, 31, 86])
print(lower) // 31
print(upper) // 86
a = 'Apple'
b = 'Pear'
a, b = b, a
print(a) // Pear
print(b) // Apple
Ranges
Range supports arguments stop, start, stop or start, stop, step. e.g.
# 0-5
range(5)
# 10-20
range(10,20)
# 10-20 step 2
range(10,20,2)
Iteration
Iterators
Here is how to iterate
s = [1,2,3,4]
myIterator = iter(s)
item1 = next(myIterator)
print(item1) // 1
item2 = next(myIterator)
print(item2) // 2
Generators
Generator functions
This is just like javascript redux stuff
def gen123():
yield 1
yield 5
yield 3
myIterator = gen123()
print(next(myIterator)) // 1
print(next(myIterator)) // 5
print(next(myIterator)) // 3
print(next(myIterator)) // Exception
# Or
for v in gen123():
print(v)
...
1
5
3
Generator Expressions
Syntax can be defined as
(expr(item) for item : iterable)
million_squares = (x*x for x in range(1,1000001))
# Generate and output last 10
list(million_squares)[-10:]
# Again will yield nothing
list(million_squares)
Iteration tools
islice
from itertools import count, islice
thousand_primes = islice( (x for x in count() if is_prime(x), 1000)
# thousand_primes is a special islice object which is iterable
# converting to a list
list(thousand_primes)[-10:]
[7841,7853, ..... 7919]
# so to sum first thousand primes
sum(islice( (x for x in count() if is_prime(x), 1000))
3682913
zip
Combine groups together e.g.
sunday = [10,20,30]
monday = [101,201,301]
for item in zip(sunday, monday)
print(item)
...
(10,101)
(20,201)
(30,301)
Exceptions
General
def convert(s):
try:
number = ''
for token in s:
number += DIGIT_MAP[token]
x = int(number)
# Can be on one line
# except (KeyError, TypeError):
except TypeError:
x = -2
raise # rethrow
except KeyError:
x = -1
raise # rethrow
return x
Modularity
Functions
General
These are created as below
def foo(arg1, arg2):
return arg1 * arg2
Defaults
def foo(arg1, arg2=9):
return arg1 * arg2
Be aware that the def assignment is only run once. Therefore These are created as below
def add_spam(menu=[]):
menu.append('spam')
add_spam() // ['spam']
add_spam() // ['spam','spam']
Advice is to make default arguments not mutable. i.e. not strings and not ints
def add_spam(menu=None):
if(menu==None)
menu = []
menu.append('spam')
return menu
add_spam() // ['spam']
add_spam() // ['spam']
Importing defs
Best to be selective
from words import (fetch_words, print_words)
// could be BAD BAD!!
from words import *
Passing arguments
import sys
if __name__ == '__main__':
main(sys.argv[1])
Comments
def fetch_words(url):
"""Fetch a list of words from a URL.
Args:
url: The URL of UTF-8 text document.
Return:
A list of strings containing the words from
the document.
"""
story = urlopen(url)
story_words = []
for line in story:
line_words = line.decode('utf8').split()
for word in line_words:
story_words.append(word)
story.close()
return story_words
Scope of Objects
Types of Scope
- Local - Inside current function
- Enclosing - Inside enclosing function
- Global - At the top level of the module
- Built-in - In the special builtins module
Overriding Scope
Not using global creates a new count and it shadows the global count.
count = 0
def show_count():
print(count)
def set_count(c)
global count = c
set_count(5)
show_count()
Objects and Types
Named references to objects
Assigning variables is the same as references. Use id() to prove this.
s = [1,2,3]
r = s
s[0] = 500
print(r)
[500,2,3]
p = [4,5,6]
q = [4,5,6]
print(p == q) // True
print(p is q) // False
Passing Arguments are like references
Passing arguments is like passing references
m = [9,15,24]
def modify(k):
k.append(39)
print("k = ", k)
modify(m)
k = [9,15,24, 39]
print(m)
[9,15,24, 39]
Passing Arguments are like references II
Or are they. g is reassigned not mutated
f = [14, 23, 37]
def replace(g):
g = [17,28, 45]
print("g = ", g)
replace(f)
g = [17,28, 45]
print(f)
[14,23,37]
Classes
General
class Fight:
def __init__(self, registration, model, num_rows)
self._registration = registration
self._model = model
self._num_rows = num_rows
def registration(self):
return self._registration
def model(self):
return self._model
def num_rows(self):
return self._num_rows
Access
There is no public, protected or private in Python
Inheritance
This is achieved using brackets on the name
class MyBaseClass:
def registration(self):
return self._registration
def model(self):
return self._model
def num_rows(self):
return self._num_rows
class Fight(MyBaseClass):
def __init__(self, registration, model, num_rows)
self._registration = registration
self._model = model
self._num_rows = num_rows
File IO
The with is used like using in c#
Reading
with open('dog_breeds.txt', 'r') as reader:
# Read and print the entire file line by line
line = reader.readline()
while line != '': # The EOF char is an empty string
print(line, end='')
line = reader.readline()
Packages
Packages
Python finds packages by looking at sys.path. You can see this by doing
import sys
sys.path
# For entry 0
sys.path[0]
# To add you can
sys.path.append('/mypath');
Another approach is to add your path to PYTHONPATH
export PYTHONPATH=$PYTHONPATH:/mypath
Make a Package
mkdir -p /mypath/reader
touch /mypath/reader/__init__.py
For a simple reader class the contents of __init__.py may be (absolute)
from reader.reader import Reader
For a simple reader class the contents of __init__.py may be (relative)
from .reader import Reader
Controlling whats imported
You can do this by specifying the __all__ content. Looks like a def file in windows dlls. e.g.
from reader.compressed.bzipped import opener as bz2_opener
from reader.compressed.gzipped import opener as gzip_opener
__all__ = ['bz2_opener', 'gzip_opener']