This commit is contained in:
adii1823 2021-10-28 17:37:54 +05:30
parent 8b802c5c62
commit ee641c189f
49 changed files with 601 additions and 0 deletions

View File

@ -0,0 +1,8 @@
# arguments.combined.py
def func(a, b, c, d, e, f):
print(a, b, c, d, e, f)
func(1, *(2, 3), f=6, *(4, 5))
func(*(1, 2), e=5, *(3, 4), f=6)
func(1, **{'b': 2, 'c': 3}, d=4, **{'e': 5, 'f': 6})
func(c=3, *(1, 2), **{'d': 4}, e=5, **{'f': 6})

View File

@ -0,0 +1,5 @@
# arguments.keyword.py
def func(a, b, c):
print(a, b, c)
func(a=1, c=2, b=3) # prints: 1 3 2

View File

@ -0,0 +1,13 @@
# arguments.multiple.value.py
def func(a, b, c):
print(a, b, c)
func(2, 3, a=1)
"""
$ python arguments.multiple.value.py
Traceback (most recent call last):
File "arguments.multiple.value.py", line 5, in <module>
func(2, 3, a=1)
TypeError: func() got multiple values for argument 'a'
"""

View File

@ -0,0 +1,15 @@
# arguments.positional.keyword.py
def func(a, b, c):
print(a, b, c)
func(42, b=1, c=2)
func(b=1, c=2, 42) # positional argument after keyword arguments
"""
$ python arguments.positional.keyword.py
File "arguments.positional.keyword.py", line 7
func(b=1, c=2, 42) # positional argument after keyword arguments
^
SyntaxError: positional argument follows keyword argument
"""

View File

@ -0,0 +1,5 @@
# arguments.positional.py
def func(a, b, c):
print(a, b, c)
func(1, 2, 3) # prints: 1 2 3

View File

@ -0,0 +1,6 @@
# arguments.unpack.dict.py
def func(a, b, c):
print(a, b, c)
values = {'b': 1, 'c': 2, 'a': 42}
func(**values) # equivalent to func(b=1, c=2, a=42)

View File

@ -0,0 +1,6 @@
# arguments.unpack.iterable.py
def func(a, b, c):
print(a, b, c)
values = (1, 3, -7)
func(*values) # equivalent to: func(1, 3, -7)

View File

@ -0,0 +1,22 @@
# data.science.example.py
def do_report(data_source):
# fetch and prepare data
data = fetch_data(data_source)
parsed_data = parse_data(data)
filtered_data = filter_data(parsed_data)
polished_data = polish_data(filtered_data)
# run algorithms on data
final_data = analyse(polished_data)
# create and return report
report = Report(final_data)
return report
if __name__ == "__main__":
print(
"Please don't call the `do_report` function. "
"It's just and example."
)

24
ch04/docstrings.py Normal file
View File

@ -0,0 +1,24 @@
# docstrings.py
def square(n):
"""Return the square of a number n. """
return n ** 2
def get_username(userid):
"""Return the username of a user given their id. """
return db.get(user_id=userid).username
def connect(host, port, user, password):
"""Connect to a database.
Connect to a PostgreSQL database directly, using the given
parameters.
:param host: The host IP.
:param port: The desired port.
:param user: The connection username.
:param password: The connection password.
:return: The connection object.
"""
# body of the function here...
return connection

6
ch04/filter.lambda.py Normal file
View File

@ -0,0 +1,6 @@
# filter.lambda.py
def get_multiples_of_five(n):
return list(filter(lambda k: not k % 5, range(n)))
print(get_multiples_of_five(50))

10
ch04/filter.regular.py Normal file
View File

@ -0,0 +1,10 @@
# filter.regular.py
def is_multiple_of_five(n):
return not n % 5
def get_multiples_of_five(n):
return list(filter(is_multiple_of_five, range(n)))
print(get_multiples_of_five(50))

16
ch04/func.attributes.py Normal file
View File

@ -0,0 +1,16 @@
# func.attributes.py
def multiplication(a, b=1):
"""Return a multiplied by b. """
return a * b
if __name__ == "__main__":
special_attributes = [
"__doc__", "__name__", "__qualname__", "__module__",
"__defaults__", "__code__", "__globals__", "__dict__",
"__closure__", "__annotations__", "__kwdefaults__",
]
for attribute in special_attributes:
print(attribute, '->', getattr(multiplication, attribute))

5
ch04/func_from.py Normal file
View File

@ -0,0 +1,5 @@
# func_from.py
from lib.funcdef import square, cube
print(square(10))
print(cube(10))

6
ch04/func_import.py Normal file
View File

@ -0,0 +1,6 @@
# func_import.py
import lib.funcdef
print(lib.funcdef.square(10))
print(lib.funcdef.cube(10))

11
ch04/imports.py Normal file
View File

@ -0,0 +1,11 @@
# imports.py
from datetime import datetime, timezone # two imports on the same line
from unittest.mock import patch # single import
import pytest # third party library
from core.models import ( # multiline import
Exam,
Exercise,
Solution,
)

View File

@ -0,0 +1,6 @@
# key.points.argument.passing.py
x = 3
def func(y):
print(y)
func(x) # prints: 3

View File

@ -0,0 +1,7 @@
# key.points.assignment.py
x = 3
def func(x):
x = 7 # defining a local x, not changing the global one
func(x)
print(x) # prints: 3

View File

@ -0,0 +1,8 @@
# key.points.mutable.assignment.py
x = [1, 2, 3]
def func(x):
x[1] = 42 # this changes the original `x` argument!
x = 'something else' # this points x to a new string object
func(x)
print(x) # still prints: [1, 42, 3]

View File

@ -0,0 +1,7 @@
# key.points.mutable.py
x = [1, 2, 3]
def func(x):
x[1] = 42 # this affects the `x` argument!
func(x)
print(x) # prints: [1, 42, 3]

30
ch04/lambda.explained.py Normal file
View File

@ -0,0 +1,30 @@
# lambda.explained.py
"""
myfunc = lambda [parameter_list]: expression
def myfunc([parameter_list]):
return expression
"""
# example 1: adder
def adder(a, b):
return a + b
# is equivalent to:
adder_lambda = lambda a, b: a + b
# example 2: to uppercase
def to_upper(s):
return s.upper()
# is equivalent to:
to_upper_lambda = lambda s: s.upper()
if __name__ == "__main__":
print(adder(3, 4))
print(adder_lambda(3, 4))
print(to_upper("Hello"))
print(to_upper_lambda("Hello"))

0
ch04/lib/__init__.py Normal file
View File

6
ch04/lib/funcdef.py Normal file
View File

@ -0,0 +1,6 @@
# lib/funcdef.py
def square(n):
return n ** 2
def cube(n):
return n ** 3

View File

@ -0,0 +1,12 @@
# matrix.multiplication.func.py
# this function could also be defined in another module
def matrix_mul(a, b):
return [[sum(i * j for i, j in zip(r, c)) for c in zip(*b)]
for r in a]
a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
c = matrix_mul(a, b)
print(c)

View File

@ -0,0 +1,7 @@
# matrix.multiplication.nofunc.py
a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
c = [[sum(i * j for i, j in zip(r, c)) for c in zip(*b)]
for r in a]
print(c)

10
ch04/no.side.effects.py Normal file
View File

@ -0,0 +1,10 @@
# no.side.effects.py
# This file is not meant to be run
>>> numbers = [4, 1, 7, 5]
>>> sorted(numbers) # won't sort the original `numbers` list
[1, 4, 5, 7]
>>> numbers # let's verify
[4, 1, 7, 5] # good, untouched
>>> numbers.sort() # this will act on the list
>>> numbers
[1, 4, 5, 7]

View File

@ -0,0 +1,8 @@
# parameters.all.pkwonly.py
def allparams(a, /, b, c=42, *args, d=256, e, **kwargs):
print('a, b, c:', a, b, c)
print('d, e:', d, e)
print('args:', args)
print('kwargs:', kwargs)
allparams(1, 2, 3, 4, 5, 6, e=7, f=9, g=10)

7
ch04/parameters.all.py Normal file
View File

@ -0,0 +1,7 @@
# parameters.all.py
def func(a, b, c=7, *args, **kwargs):
print('a, b, c:', a, b, c)
print('args:', args)
print('kwargs:', kwargs)
func(1, 2, 3, 5, 7, 9, A='a', B='b')

View File

@ -0,0 +1,8 @@
# parameters.default.py
def func(a, b=4, c=88):
print(a, b, c)
func(1) # prints: 1 4 88
func(b=5, a=7, c=9) # prints: 7 5 9
func(42, c=9) # prints: 42 4 9
func(42, 43, 44) # prints: 42, 43, 44

View File

@ -0,0 +1,11 @@
# parameters.defaults.mutable.intermediate.call.py
def func(a=[], b={}):
print(a)
print(b)
print('#' * 12)
a.append(len(a)) # this will affect a's default value
b[len(a)] = len(a) # and this will affect b's one
func()
func(a=[1, 2, 3], b={'B': 1})
func()

View File

@ -0,0 +1,5 @@
# parameters.defaults.mutable.no.trap.py
def func(a=None):
if a is None:
a = []
# do whatever you want with `a` ...

View File

@ -0,0 +1,11 @@
# parameters.defaults.mutable.py
def func(a=[], b={}):
print(a)
print(b)
print('#' * 12)
a.append(len(a)) # this will affect a's default value
b[len(a)] = len(a) # and this will affect b's one
func()
func()
func()

View File

@ -0,0 +1,16 @@
# parameters.keyword.only.py
def kwo(*a, c):
print(a, c)
kwo(1, 2, 3, c=7) # prints: (1, 2, 3) 7
kwo(c=4) # prints: () 4
# kwo(1, 2) # breaks, invalid syntax, with the following error
# TypeError: kwo() missing 1 required keyword-only argument: 'c'
def kwo2(a, b=42, *, c):
print(a, b, c)
kwo2(3, b=7, c=99) # prints: 3 7 99
kwo2(3, c=13) # prints: 3 42 13
# kwo2(3, 23) # breaks, invalid syntax, with the following error
# TypeError: kwo2() missing 1 required keyword-only argument: 'c'

View File

@ -0,0 +1,6 @@
# parameters.positional.only.optional.py
def func(a, b=2, /):
print(a, b)
func(4, 5) # prints 4 5
func(3) # prints 3 2

View File

@ -0,0 +1,58 @@
# parameters.positional.only.py
def func(a, b, /, c):
print(a, b, c)
func(1, 2, 3) # prints: 1 2 3
func(1, 2, c=3) # prints 1 2 3
# func(1, b=2, c=3) # produces the following traceback:
"""
Traceback (most recent call last):
File "arguments.positional.only.py", line 7, in <module>
func(1, b=2, c=3)
TypeError: func() got some positional-only arguments
passed as keyword arguments: 'b'
"""
"""
def func_name(positional_only_parameters, /,
positional_or_keyword_parameters, *,
keyword_only_parameters):
Valid:
def func_name(p1, p2, /, p_or_kw, *, kw):
def func_name(p1, p2=None, /, p_or_kw=None, *, kw):
def func_name(p1, p2=None, /, *, kw):
def func_name(p1, p2=None, /):
def func_name(p1, p2, /, p_or_kw):
def func_name(p1, p2, /):
Invalid:
def func_name(p1, p2=None, /, p_or_kw, *, kw):
def func_name(p1=None, p2, /, p_or_kw=None, *, kw):
def func_name(p1=None, p2, /):
Why it is useful:
def divmod(a, b, /):
"Emulate the built in divmod() function"
return (a // b, a % b)
len(obj='hello') # The "obj" keyword argument impairs readability
"""
def func_name(name, /, **kwargs):
print(name)
print(kwargs)
func_name('Positional-only name', name='Name in **kwargs')
"""
Prints:
Positional-only name
{'name': 'Name in **kwargs'}
"""

View File

@ -0,0 +1,15 @@
# parameters.variable.db.py
def connect(**options):
conn_params = {
'host': options.get('host', '127.0.0.1'),
'port': options.get('port', 5432),
'user': options.get('user', ''),
'pwd': options.get('pwd', ''),
}
print(conn_params)
# we then connect to the db (commented out)
# db.connect(**conn_params)
connect()
connect(host='127.0.0.42', port=5433)
connect(port=5431, user='fab', pwd='gandalf')

View File

@ -0,0 +1,7 @@
# parameters.variable.keyword.py
def func(**kwargs):
print(kwargs)
func(a=1, b=42) # prints {'a': 1, 'b': 42}
func() # prints {}
func(a=1, b=46, c=99) # prints {'a': 1, 'b': 46, 'c': 99}

View File

@ -0,0 +1,12 @@
# parameters.variable.positional.py
def minimum(*n):
# print(type(n)) # n is a tuple
if n: # explained after the code
mn = n[0]
for value in n[1:]:
if value < mn:
mn = value
print(mn)
minimum(1, 3, -7, 9) # n = (1, 3, -7, 9) - prints: -7
minimum() # n = () - prints: nothing

47
ch04/primes.py Normal file
View File

@ -0,0 +1,47 @@
# primes.py
from math import sqrt, ceil
def get_primes(n):
"""Calculate a list of primes up to n (included). """
primelist = []
for candidate in range(2, n + 1):
is_prime = True
root = ceil(sqrt(candidate)) # division limit
for prime in primelist: # we try only the primes
if prime > root: # no need to check any further
break
if candidate % prime == 0:
is_prime = False
break
if is_prime:
primelist.append(candidate)
return primelist
if __name__ == "__main__":
def test():
primes = get_primes(10**3)
primes2 = [
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103,
107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353,
359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487,
491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631,
641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773,
787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857,
859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
941, 947, 953, 967, 971, 977, 983, 991, 997
]
return primes == primes2
print(test())
print(get_primes(100))

View File

@ -0,0 +1,8 @@
# recursive.factorial.py
def factorial(n):
if n in (0, 1): # base case
return 1
return factorial(n - 1) * n # recursive case
print([factorial(n) for n in range(10)])

26
ch04/return.multiple.py Normal file
View File

@ -0,0 +1,26 @@
# return.multiple.py
def moddiv(a, b):
return a // b, a % b
def test(n=10**4):
from random import choice, random, randint
m = 10 ** 6
for x in range(n):
a = choice((randint(0, m), m * random()))
b = 0
while not b:
b = choice((randint(1, m), m * random()))
r = divmod(a, b)
r2 = moddiv(a, b)
if r != r2:
print('Difference: ', a, b, r, r2)
if __name__ == "__main__":
test(10 ** 6)
print('Done')
print(moddiv(20, 7)) # prints (2, 6)

7
ch04/return.none.py Normal file
View File

@ -0,0 +1,7 @@
# return.none.py
def func():
pass
func() # the return of this call won't be collected. It's lost.
a = func() # the return of this one instead is collected into `a`
print(a) # prints: None

View File

@ -0,0 +1,12 @@
# return.single.value.2.py
from functools import reduce
from operator import mul
def factorial(n):
return reduce(mul, range(1, n + 1), 1)
f5 = factorial(5) # f5 = 120
print(f5)
print([factorial(k) for k in range(10)])

View File

@ -0,0 +1,11 @@
# return.single.value.py
def factorial(n):
if n in (0, 1):
return 1
result = n
for k in range(2, n):
result *= k
return result
f5 = factorial(5) # f5 = 120
print(f5)

9
ch04/scoping.level.1.py Normal file
View File

@ -0,0 +1,9 @@
# scoping.level.1.py
def my_function():
test = 1 # this is defined in the local scope of the function
print('my_function:', test)
test = 0 # this is defined in the global scope
my_function()
print('global:', test)

View File

@ -0,0 +1,16 @@
# scoping.level.2.global.py
def outer():
test = 1 # outer scope
def inner():
global test
test = 2 # global scope
print('inner:', test)
inner()
print('outer:', test)
test = 0 # global scope
outer()
print('global:', test)

View File

@ -0,0 +1,16 @@
# scoping.level.2.nonlocal.py
def outer():
test = 1 # outer scope
def inner():
nonlocal test
test = 2 # nearest enclosing scope (which is 'outer')
print('inner:', test)
inner()
print('outer:', test)
test = 0 # global scope
outer()
print('global:', test)

15
ch04/scoping.level.2.py Normal file
View File

@ -0,0 +1,15 @@
# scoping.level.2.py
def outer():
test = 1 # outer scope
def inner():
test = 2 # inner scope
print('inner:', test)
inner()
print('outer:', test)
test = 0 # global scope
outer()
print('global:', test)

7
ch04/vat.function.py Normal file
View File

@ -0,0 +1,7 @@
# vat.function.py
def calculate_price_with_vat(price, vat):
return price * (100 + vat) / 100
if __name__ == "__main__":
print(calculate_price_with_vat(100, 20))

12
ch04/vat.py Normal file
View File

@ -0,0 +1,12 @@
# vat.py
price = 100 # GBP, no VAT
final_price1 = price * 1.2
final_price2 = price + price / 5.0
final_price3 = price * (100 + 20) / 100.0
final_price4 = price + price * 0.2
if __name__ == "__main__":
for var, value in sorted(vars().items()):
if 'price' in var:
print(var, value)