*Основа материала - курсы Сергея Лебедева и Алексея Кладова
Окружение для ОС Amoeba
Source:
HOW TO RETURN words document:
PUT {} IN collection
FOR line IN document:
FOR word IN split line:
IF wordnot.incollection:
INSERT word IN collection
RETURN collection
TRY
DO.Something()
EXCEPT
| IO.Error=> IO.Put("An I/O error occurred.")
END;
def magic(top):
acc = []
for entry in os.scandir(top):
if entry.is_file() and entry.name.endwith(".py"):
acc.append(entry.path)
return acc
Python — динамический интерпретируемый язык.
>>> def add(x, y):
... return x + y
...
>>> def bar(x):
... add(x, "1", "2") # не ошибка
...
>>> add.__code__ = bar.__code__
>>> add(42)
Traceback (most recent call last)
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in bar
TypeError: bar() takes 1 positional argument but 3 [...]
Python — динамический интерпретируемый язык.
$ cat ./hello.py
message= "Hello, world!"
$ python -m dis ./hello.py
0 LOAD_CONST0 ('Hello, world!')
3 STORE_NAME0 (message)
6 LOAD_CONST1 (None)
9 RETURN_VALUE
>>> import hello
>>> hello
<module 'hello' from '[...]/hello.py'>
>>> dir(hello)
['__builtins__', '__cached__', '__doc__', '__file__','__loader__', '__name__', '__package__', '__spec__','message']
>>> hello.__name__, hello.__file__
('hello', '[...]/hello.py')
>>> print(hello.message)
"Hello, world!"
>>> while True:
... print(42)
File "<stdin>", line 2
print(42)
^
IndentationError: expected an indented block
>>> import hello
>>> type(hello)
<class 'module'>
>>> type(type(hello))
<class 'type'>
>>>type(type(type(hello)))
<class 'type'>
>>> None # аналог null, но полноценный объект
>>> res = print(None) # любая функция возвращает значение
None
>>> res == None # неделайте так
True
>>> res is None # делайте лучше так
True
>>> id(res) # в CPython -- адрес
140503861261072
>>> id(None)
140503861261072
>>> to_be = False
>>> to_be ornot to_be # слова вместо значков
True
>>> x = 1
>>> y = 2
>>> x**2 + y**2 < 5 == True # True синглтон, не делайте так
False
>>> x**2 + y**2 < 5 is True # но и так тоже не делайте
False
>>> x**2 + y**2 < 5
False
>>> False and print('also') # short-circuiting!
False
>>> res = True and print('also')
also
>>> assert res is None, "print should return None"
>>> False or 92 # работает с любым значением
92
>>> x = 100
>>> y = 3
>>> assert x % y == 0, (x, y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: (100, 3)
>>> True + False + True # bool тоже числа
2
>>> 0
0
>>> 2**128 # сколько угодно знаков
340282366920938463463374607431768211456
>>> 1.0 # double
1.0
>>> float('inf')
inf
>>> int('92')
>>> 92
>>> 90 + 2j # комплексные числа тоже есть
(90+2j)
>>> 3 / 2 # вещественное деление
1.5
>>> 4 / 2
2.0
>>> 4 // 2 # деление состатком
2
>>> 3 // 2
1
>>> -3 // 2 # как в алгебре!
-2
>>> -1 % 3 # С/Java/Rust скажут -1
2
>>> x = 10
>>> 0 <= x and x < 100
True
>>> 0 <= x < 100
True
>>> []
[]
>>> xs = [1, 2, 3,]
>>> len(xs)
3
>>> xs[0]
1
>>> xs[0] = 0
>>> xs
[0, 2, 3]
>>> xs = [1, 2] * 3
>>> xs
[1, 2, 1, 2, 1, 2]
>>> xs = [[0] * 3] * 3 # не делайте так
>>> xs[0][0] = 1
>>> xs
[[1, 0, 0], [1, 0, 0], [1, 0, 0]] # :-(
>>> [1] + [2, 3] + [4] # O(?)
[1, 2, 3, 4]
>>> xs = [1, 2, 3]
>>> xs.append(4) # O(?)
>>> xs
[1, 2, 3, 4]
>>> xs.pop() # O(?)
4
>>> xs
[1, 2, 3]
>>> xs.pop(0) # O(?)
1
>>> xs
[2, 3]
>>> xs.insert(0, 92) # O(?)
>>> xs
[92, 2, 3]
>>> xs += [1] # так делать не стоит
>>> xs
[92, 2, 3, 1]
>>> xs = list(range(5))
>>> xs
[0, 1, 2, 3, 4]
>>> xs[len(xs) - 1]
4
>>> xs[-1]
4
>>> xs[2:4]
[2, 3]
>>> xs[:-2]
[0, 1, 2]
>>> xs[::2]
[0, 2, 4]
>>> y = xs[:] # или y = list(xs)
>>> y[0] = 92
>>> y
[92, 1, 2, 3, 4]
>>> xs
[0, 1, 2, 3, 4]
>>> xs[:100] # слайс может выходить за границу
[0, 1, 2, 3, 4]
>>> xs[100]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> xs[1:-1:2] = [None] * 2 # работает присваивание
>>> xs
[0, None, 2, None, 4]
>>> every_second = slice(None, None, 2)
>>> list(range(10))[every_second]
[0, 2, 4, 6, 8]
>>> s = "hello" # 'hello'
>>> len(s)
5
>>> s[:-1]
'hell'
>>> s[0]
'h'
>>> s[1] = "i" # в отличие от списков, строки не изменяемы
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> "<>" + "." * 8 + "<"
'<>........<'
>>> "hello \nworld".splitlines() # разбить на строчки
['hello ', 'world']
>>> "a b c".split() # на слова
['a', 'b', 'c']
>>> "\thello ".strip() # убрать пробелы
'hello'
>>> ", ".join(["a", "b", "c"]) # соединить список строк
'a, b, c' # через разделитель
>>> str(42)
'42'
>>> foo = 42
>>> "foo = %s" % foo # %-оператор (old style)
'foo = 42'
>>> "foo = {}".format(foo) # str.format (new style)
'foo = 42'
>>> f"foo = {foo}" # f-Strings (+3.6)
'foo = 42'
>>>
>>> a = 10
>>> b = 117
>>> f"{a:<4}: foo\n{b:<4}: bar" # выравнивание
10 : foo
117 : bar
>>> f"{a:+^12}" # padding
'+++++10+++++'
>>> date = ("September", 2018)
>>> len(date) # API, каку списка
2
>>> date[1] = 2019 # но менять нельзя
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> xs = ([], [])
>>> xs[0].extend([1, 2, 3])
>>> xs([1, 2, 3], [])
>>> () # пустой кортеж
()
>>> 1
1
>>> (1, ) # кортеж из одного элемента
(1,)
>>> date = "September", 2018 # скобки опциональны
>>> date
('September', 2018)
>>> def div_mod(x, y):
... return x // y, x % y
...
>>> d, m = div_mod(10, 3)
>>> assert (d, m) == (3, 1)
>>> xs = {1, 2, 3} # множество (hash set)
>>> 1 in xs
True
>>> 92 not in xs
True
>>> xs.add(1)
>>> xs.add(92)
>>> xs
{1, 2, 3, 92} # в множестве нет повторений
>>> set() # для пустого множества нет литерала
set()
>>> 1 in [1, 2, 3] # O(?)
True
>>> "world" in "hello, world"
True
>>> {1, 2, 3}.union({3, 4, 5}) # или |
{1, 2, 3, 4, 5}
>>> {1, 2, 3} & {3, 4, 5} # или .intersection
{3}
>>> {1, 2, 3} ^ {3, 4, 5} # или .symmetric_difference
{1, 2, 4, 5}
>>> xs = {1, 2, 3}
>>> xs.discard(2) # в реальной жизни операция удаления
>>> xs # -- редкая
{1, 3}
>>> xs = set()
>>> xs.add([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> date = {"year": 2018, "month": "September"}
>>> len(date)
2
>>> date["year"] # KeyError еслик лючанет,
2018 # в отличие от Java
>>> date.get("day", 14) # Значение поумолчанию
14
>>> date["day"] = 14
>>> date.pop("year")
2018
>>> date.keys()
dict_keys(['month', 'day']) # set
>>> date.values()
dict_values(['September', 14]) # не set
>>> date.items() # set!
dict_items([('month', 'September'), ('day', 14)])
>>> date.items() | {1: 2}.items()
{('day', 14), ('month', 'September'), (1, 2)}
>>> date.items() | {1: []}.items()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> 'day' in date.keys() # плохо!
True
>>> 'day' in date
True
>>> d = {}
>>> d["a"] = 1
>>> d["b"] = 2
>>> d["c"] = 3
>>> list(d.keys())
['a', 'b', 'c'] # порядок гарантируется
- одинаковый API для похожих типов.
- могущественные операции.
- не надо ничего изобретать, нужно брать и программировать
Документация:
if 0 <= n and n < len(xs):
print(xs[n])
x = 50
y = 25
small = x if x < y else y
# int small = x < y ? x : y;
# :( :( :(
if x[0] < 100 and x[1] > 100 and (is_full_moon() or not is_thursday()) and user.is_admin:
pass
# >:(
if x[0] < 100 and x[1] > 100
and (is_full_moon() or not is_thursday())
and user.is_admin:
pass
# :( :( :(
if x[0] < 100 and x[1] > 100 \
and (is_full_moon() or not is_thursday()) \
and user.is_admin:
pass
# :( :(
if (x[0] < 100 and x[1] > 100
and (is_full_moon() or not is_thursday())
and user.is_admin):
pass
# :|
value_in_range = x[0] < 100 and x[1] > 100
good_date = is_full_moon() or not is_thursday()
if value_in_range and good_date and user.is_admin:
pass
i = 0
while i < 4:
i += 1
i
>>> bool(True)
True
>>> bool(0)
False
>>> bool(1)
True
>>> bool([])
False
>>> bool([0])
True
(False, # Falsy!
None,
0, 0.0, 0j,
"", [], (), set(), {})
if len(xs) == 0: # плохо!
pass
if xs:
pass
if not xs:
pass
for x in [1, 2, 3]:
print(x)
for line in open("./HBA1.txt"): # как правильно
pass # -- вследующих сериях
for ch in "foobar":
pass
for i in range(10):
print(x)
for i in range(2, 10, 3):
print(x)
for i in range(9, -1, -1): # :(
print(x)
for i in reversed(range(10)): # :)
print(x)
for i in reversed("hello"):
print(x)
for i in reversed([1, 2, 3]):
print(x)
target = 92
for item in items:
if item == target:
print("Found!", item)
break
target = 92
for item in items:
if item == target:
print("Found!", item)
break
print("Not found") # :(
target = 92
found = False # :( :( :(
for item in items:
if item == target:
print("Found!", item)
found = True
break
if not found:
print("Not found")
target = 92
for item in items:
if item == target:
print("Found!", item)
break
else:
print("Not found")
target = 92
res = []
for item in items:
if item != target:
continue
res.append(item)
Документация:
exp = -1.05
value = (item_value / item_count) * offset / exp
tems = [
'this is the first', 'set of items',
'with more items', 'to come in this line',
'like this'
]
if bar: x += 1 # Плохо
while bar: do_something() # Плохо
if bar: # Лучше
x += 1
while bar: # Лучше
do_domething()
if 'md5' == method: # Плохо
pass
if method == 'md5': # Лучше
pass
Для сравнения на равенство
if foo: while not bar:
# ... # ...
if not key in d: # Плохо
if key not in d: # Лучше
def foo (x, y): # Плохо
pass
foo( 42, 24 ) # Плохо
def something_useful(arg, **options):
"""One-line summary.
Optional longer description of the function
behaviour.
"""