-
Notifications
You must be signed in to change notification settings - Fork 0
Python
Etsu edited this page Oct 3, 2017
·
42 revisions
''.join('{}{}'.format(key, val) for key, val in adict.items())
string = ast.literal_eval(string)
assert type(new_dict) is dict
def main():
a, b = map(int, input().split())
res = a + b
print(res)
if __name__ == "__main__":
main()
import numpy as np
np.show_config()
class Song:
def __init__(self, artist, song):
self.artist = artist
self.song = song
self.tags = []
def add_tags(self, *args):
self.tags.extend(args)
song1 = Song("artist_name1", "song_name2")
song1.add_tags("tag1", "tag2")
song2 = Song("artist_name3", "song_name4")
song2.add_tags("tag3", "tag4")
song2.tags
class MoneyBox:
def __init__(self, capacity):
self.capacity = capacity
self.value = 0
def can_add(self, v):
if (v <= (self.capacity - self.value)):
return True
else:
return False
def add(self, v):
self.value = self.value + v
isinstance(x,y)
type()
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# Проверим, что s.split не работает, если разделитель - не строка
with self.assertRaises(TypeError):
s.split(2)
if __name__ == '__main__':
unittest.main()
# return использовать не обязательно, функция вернёт None
# Для документации функции используются строковые литералы
>>> def foo():
... """I return 42."""
... return 42
...
# После объявлении функции документация доступна через определённый атрибут
>>> foo.__doc__
'I return 42.'
# В интерпретаторе удобнее пользоваться встроенной функцией
>>> help(foo) # или foo? в IPython.
>>> def min(x, y): # __o
... return x if x < y else y # _`\<,_
... # (_)/ (_)
# 1. Находить минимум произвольного количества аргументов
>>> min(-5, 12, 13)
-5
# 2. Использовать функцию min для кортежей, списков, множеств и других последовательностей
>>> xs = {-5, 12, 13}
>>> min(???)
-5
# 3. Ограничить минимум произвольным отрезком [lo, hi]
>>> bounded_min(-5, 12, 13, lo=0, hi=255)
12
# 4. По заданным lo и hi строить функцию bounded_min (фабрика функций)
>>> bounded_min = make_min(lo=0, hi=255)
>>> bounded_min(-5, 12, 13)
12
# 1.a
def min(*args): # type(args) == tuple
res = float("inf") # инициализируем бесконечностью
for arg in args:
if arg < res:
res = arg
return res
# >>> min(-5, 12, 13)
# -5
# >>> min()
# inf
1.b
def min(first, *args):
res = first
# ...
# min()
# TypeError: min() missing 1 required [...] argument: 'first'
# 2.a
# Синтаксис будет работать с любым объектом, поддерживающим протокол итератора
# Итератор - что-то, что можно обойти
>> xs = {-5, 12, 13} # но вообще set лучше не юзать
>>> min(*xs) # здесь он не критичен, но вообще, распаковывать set - странная идея
-5
>>> min(*[-5, 12, 13])
-5
>>> min(*(-5, 12, 13))
-5
...
# 3.a
def bounded_min(first, *args, lo=float("-inf"),
hi=float("inf")):
res = hi
# итерируемся по первому элементу + всё остальное
for arg in (first, ) + args: # args - это кортеж,
# соответственно fisrt тоже надо превратить к кортеж :)
if arg < res and lo < arg < hi:
res = arg
return max(res, lo)
# >>> bounded_min(-5, 12, 13, lo=0, hi=255)
# 12
# Нужно было написать функцию, которая принимает что-то,
# по чему можно итерироваться и возвращает список уникальных элементов
def unique(iterable, seen=set()):
acc = []
for item in iterable:
if item not in seen:
seen.add(item)
acc.append(item)
return acc
# >>> xs = [1, 1, 2, 3]
# >>> unique(xs)
# [1, 2, 3]
# >>> unique(xs)
# []
# Так происходит, потому что значение по умолчанию инициализируется ровно один раз -
# - в момент компиляции в байт-код
# Т.е. все вызовы unique() будут различать значения атрибута seen
# Вывод: никогда не использовать изменяемые значения в качестве значений по умолчанию
# (никакие списки, никакие словари)
# Атрибут __defaults__ - кортеж с инициализированными значениями элементов по умолчанию
# >>> unique.__defaults__
# ({1, 2, 3},)
def unique(iterable, seen=None): # None не изменяемый, потому что он Singleton
seen = set(seen or []) # None --- falsy.
# Поэтому если аргумент=None, то он станет пустым списком
# OR подразумевает операции над булевыми переменными,
# поэтому, если они не булевы,
# то он попытается их привести к таковым
# А если первая штука truesy, то мы берём её значение
acc = []
for item in iterable:
if item not in seen:
seen.add(item)
acc.append(item)
return acc
# >>> xs = [1, 1, 2, 3]
# >>> unique(xs)
# [1, 2, 3]
# >>> unique(xs)
# [1, 2, 3]
None
0
0,00
""
[] () {}
set()
# Если функция имеет фиксированную арность,
# то ключевые агрументы можно передавать без явного указания имени:
>>> def flatten(xs, depth=None):
... pass
...
>>> flatten([1, [2], 3], depth=1)
>>> flatten([1, [2], 3], 1)
# Можно явно потребовать, чтобы часть аргументов всегда передавалась как ключевые:
>>> def flatten(xs, *, depth=None): # звёздочка всё кушает и не связывает это с именем
# Всё, что идёт после звёздочки - ключевые аргументы
... pass
...
>>> flatten([1, [2], 3], 2)
TypeError: flatten() takes 1 positional argument [...]
def runner(cmd, **kwargs):
if kwargs.get("verbose", True):
print("Logging enabled")
>>> runner("mysqld", limit=42)
Logging enabled
>>> runner("mysqld", **{"verbose": False})
>>> options = {"verbose": False}
>>> runner("mysqld", **options)
# Присваивание
acc = []
seen = set()
(acc, seen) = ([], set())
# В качестве правого объекта можно использовать любой объект,
# поддерживающий протокол итератора
x, y, z = [1, 2, 3]
x, y, z = {1, 2, 3} # unordered
x, y, z = "xyz"
x, y = y, x # по сути справа - tuple (y, x)
# Скобки обычно опускают, но иногда они бывают полезны
rectangle = (0, 0), (4, 4)
(x1, y1), (x2, y2) = rectangle
# В Python 3.0 можно юзать * (что-то мы распакуем, а что-то обратно запакуем)
# rest всегда приводится к списку и копирует то, что справа
>>> first, *rest = range(1, 5)
>>> first, rest
(1, [2, 3, 4])
# * можно использовать в любом месте приложения
>>> first, *rest, last = range(1, 5)
>>> last
4
>>> first, *rest, last = [42]
ValueError: need more than 1 values to unpack
# Работает рекурсивно тоже
>>> *_, (first, *rest) = [range(1, 5)] * 5
>>> fisrt
1
https://www.python.org/dev/peps/pep-3132/
# Синтаксис распаковки работает и в цикле for, например:
for a, *b in [range(4), range(2)]:
print(b)
# [1, 2, 3]
# [1]
>>> import dis
>>> dis.dis("first, *rest, last = ('a', 'b', 'c')")
0 LOAD_CONST 4 (('a', 'b', 'c'))
3 UNPACK_EX 257
6 STORE_NAME 0 (first)
9 STORE_NAME 1 (rest)
12 STORE_NAME 2 (last)
15 LOAD_CONST 3 (None)
18 RETURN_VALUE
# Мораль: присваивание в Python работает слева-направо
>>> x, (x, y) = 1, (2, 3) # не надо так писать :)
>>> x
2
>>> dis.dis("first, *rest, last = ['a', 'b', 'c']")
0 LOAD_CONST 0 (1)
3 LOAD_CONST 1 (2)
6 LOAD_CONST 2 (3)
9 BUILD_LIST 3
12 UNPACK_EX 257
15 STORE_NAME 0 (first)
18 STORE_NAME 1 (rest)
21 STORE_NAME 2 (last)
24 LOAD_CONST 3 (None)
27 RETURN_VALUE
# Мораль: Синтаксически схожие конструкции могут
# иметь различную семантику времени исполнения
# Функции в Python могут принимать произвольное количество
# позиционных и ключевых аргументов
# Для объявления таких функций используется синтаксис упаковки,
# а для вызова синтаксис распаковки
>>> def f(*args, **kwargs):
... pass
...
>>> f(1, 2, 3, **{"foo":42})
# Синтаксис распаковки также можно использовать при присваивании
# нескольких аргументов в цикле for:
>>> first, *rest = range(4)
>>> for first, *rest in [range(4), range(2)]:
... pass
...