За разные задачи можно получить разное число баллов. Если не указано обратное, задача весит 1 балл. Максимум за ДЗ можно набрать 23 балла.
Чтобы сдать ДЗ, его надо загрузить в nbgr-x в виде ipynb
-файла. Получить ipynb
-файл можно, выбрав в Jupyter пункт меню File → Download as... → IPython Notebook (.ipynb).
Напишите функцию power_or_nan(a, b)
, которая возводит вещественное положительное число a
в степень, заданную вещественным положителным числом b
, и возвращает результат. Если числа оказались слишком большими и в процессе вычисления произошло переполнение, функция должна вернуть специальное значение float("NaN")
.
Примечание. Python 3 может работать со сколь угодно большими целыми числами (в принципе помещающимися в память), но для чисел с плавающей точкой существует ограничение: слишком большие числа просто невозможно записать. Если вы работаете с целыми числами и в какой-то момент эти числа становятся очень-очень большими, то компьютер будет очень долго думать: например, попробуйте вычислить 9 ** (9 ** 9)
(прекратить вычисление можно с помощью Kernel → Interrupt). Если аналогичное вычисление выполнить с числами с плавающей точкой, возникнет переполнение (попробуйте). В данной задаче требуется работать только с числами с плавающей точкой. Если вы хотите записать целое число как число с плавающей точкой, это можно сделать, поставив точку: например, type(9)
— это int
, а type(9.)
— это float
. Чтобы преобразовать переменную к типу float
нужно использовать одноимённую функцию (например: y = float(x)
).
"# YOUR CODE HERE"
from math import pi, e, isnan
from sys import float_info
from numpy import isclose
max_float = float_info.max
assert power_or_nan(2., 3.) == 8.
assert isclose(power_or_nan(pi, e), 22.45915771836104)
assert power_or_nan(max_float, 0.99) == max_float ** 0.99
assert isnan(power_or_nan(max_float, 1.01))
assert(isnan(power_or_nan(9., 9. ** 9)))
if isclose(max_float, 1.7976931348623157e+308):
assert isclose(power_or_nan(1.00000001, (9. ** 9)), 48.144400906189524)
assert isclose(power_or_nan(1.0000001, (9. ** 9)), 6.690479178194533e+16)
assert isnan(power_or_nan(1.00001, (9. ** 9)))
ok = True
try:
power_or_nan('a', 'b')
ok = False
except:
pass
assert ok, ("Вам нужно обрабатывать только исключение, "
"связанное с переполнением, другие исключения"
"обрабатывать не нужно")
Написать функцию sum_ints_in_file(filename)
, принимающую на вход имя файла, содержащего целые числа (каждое число на новой строке, некоторые строки могут быть пустыми). Функция должна вернуть сумму этих чисел.
Не забудьте закрыть файл!
"# YOUR CODE HERE"
try:
del open
except:
pass
from tempfile import NamedTemporaryFile
import os
testsuite = [([1, 2, 3]),
([5]),
([111, 23, 123]),
([0]),
([-1, -10, -123]),
(0, -1, 1, 100, 500, 9999)]
for testlist in testsuite:
try:
f = NamedTemporaryFile(dir='.', delete=False, mode='w')
name = f.name
f.file.write("\n".join(map(str, testlist)))
f.file.close()
assert sum_ints_in_file(name) == sum(testlist)
finally:
os.remove(name)
import io
test_txt = io.StringIO("1\n2\n")
def get_test_txt():
return test_txt
def open(file, mode = 'r', *args, **kwargs):
return get_test_txt()
try:
s = sum_ints_in_file("test.txt")
assert test_txt.closed, "Вы забыли закрыть файл"
assert s == 3
finally:
del open
try:
f = NamedTemporaryFile(dir='.', delete=False, mode='w')
name = f.name
f.file.write("1\n2\n\n")
f.file.close()
assert sum_ints_in_file(name) == 3
except:
print("Ошибка! Обратите внимание: файл может содержать пустые строки.")
raise
finally:
os.remove(name)
Написать функцию censore_haha(filename)
, считывающую файл с именем, лежащем в переменной filename
и записывающим его в новый файл, имя которого получается добавлением к концу имени исходного файла .censored.txt
. При записи в новый файл все вхождения слова haha
должны быть заменены на [censored]
.
Например, если функция была вызвана как censore_haha('test.txt')
, она должна создать файл test.txt.censored.txt
и записать в него отцензурированную версию исходного файла.
"# YOUR CODE HERE"
from tempfile import NamedTemporaryFile
import os
def test_censore(inp, outp):
try:
f = NamedTemporaryFile(dir='.', delete=False, mode='w')
name = f.name
f.file.write(inp)
f.file.close()
censore_haha(f.name)
with open(f.name + ".censored.txt") as f:
content = f.read()
assert content == outp, ("input file: {inp}, "
"expected output: {outp} "
"obtained output: {content}".format(
inp=inp, outp=outp, content=content
))
finally:
os.remove(name)
test_censore(
"haha test\nanother haha haha test\nhahahaha hahahaha\n"
"this is a test\nwell",
("[censored] test\nanother [censored] [censored] test\n"
"[censored][censored] [censored][censored]\nthis is a test\nwell")
)
test_censore(
(
"this is a haha haha haha\n"
"haha ha ha hahahahahaha ha haha\n"
"\n"
"ha\n"
"ha\n"
"\n"
"thisisahahahathis\n"
"well...\n"
"\n"
"Hello, world!\n"
),
(
"this is a [censored] [censored] [censored]\n"
"[censored] ha ha [censored][censored][censored] ha [censored]\n"
"\n"
"ha\n"
"ha\n"
"\n"
"thisisa[censored]hathis\n"
"well...\n"
"\n"
"Hello, world!\n"
)
)
Написать функцию three_best_applicants(portfolio)
, принимающую на вход имя файла с портфолио в формате, аналогичном этому файлу, и возвращающую список фамилий и имён трёх лучших абитуриентов, упорядоченных по числу набранных ими баллов (по убыванию). Каждый элемент возвращаемого списка должен был кортежем, в котором на первом месте стоит фамилия студента, а на втором — его имя. В файле идет сначала имя, потом фамилия, а потом число баллов, причём между именем и фамилией стоит пробел, а между фамилием и числом баллов — символ табуляции (\t
).
"# YOUR CODE HERE"
from tempfile import NamedTemporaryFile
import os
def test_portfolio(inp, outp):
try:
f = NamedTemporaryFile(dir='.', delete=False, mode='w')
name = f.name
f.file.write(inp)
f.file.close()
obtained = three_best_applicants(f.name)
assert obtained == outp, ("input file: {inp}, "
"expected output: {outp} "
"obtained output: {obtained}").format(
inp=inp, outp=outp, obtained=obtained)
finally:
os.remove(name)
test_portfolio(
"""Ann Brown\t25
Emily Calvert\t89
Alice Charr\t78
Bill Taylor\t94
Polly Smith\t32
Jill Acker\t68
Tom Bass\t15
Victoria Greg\t48
Philipp Pruitt\t65
Cristine Evans\t82
""",[('Taylor', 'Bill'), ('Calvert', 'Emily'), ('Evans', 'Cristine')])
test_portfolio(
"""Ann Brown\t125
Emily Calvert\t89
Alice Charr\t78
Bill Taylor\t94
Polly Smith\t932
Victoria Greg\t648
Philipp Pruitt\t65
Cristine Evans\t82
""",[('Smith', 'Polly'), ('Greg', 'Victoria'), ('Brown', 'Ann')])
Функция save_bill(clientname, cart, filename)
принимает на вход имя клиента, список покупок cart, состоящий из трехэлементных кортежей вида (название товара, количество, цена за единицу)
, и имя файла filename
. Функция должна создать файл, имя которого указано в переменной filename
с чеком по заданному образцу и ничего не возвращать. Все числа должны выводиться в файл с двумя значащами цифрами после десятичной точки. Например, save_bill('Alice', [('Oil', 2, 100.11), ('Bread', 0.345, 90), ('Milk', 1, 50.32)], "somefile.txt")
должна создать файл somefile.txt
со следующим содержимым:
Client name: Alice
Oil x 2.00: 200.22
Bread x 0.34: 31.05
Milk x 1.00: 50.32
Total: 281.59
Подсказка. Записать число с двумя знаками после десятичной точки можно так:
"{:.2f}".format(12.345)
А ещё подставить значение переменной в строку можно так:
x = 12.345
f"{x:.2f}
"# YOUR CODE HERE"
from tempfile import NamedTemporaryFile
import os
testsuite = [("Alice", [('Oil', 2, 100.11), ('Bread', 0.345, 90),
('Milk', 1, 50.32)],
('Client name: Alice\n\nOil x 2.00: 200.22\nBread'
' x 0.34: 31.05\nMilk x 1.00: 50.32\n\nTotal: 281'
'.59')),
("Bill Clinton", [('Thing', 1, 10),
('Other thing', 1.234, 32.32)],
('Client name: Bill Clinton\n\nThing x 1.00: 10.0'
'0\nOther thing x 1.23: 39.88\n\nTotal: 49.88')),
("Claudia", [('This', 1.3, 2.12),
('This', 1.6, 2.12)],
('Client name: Claudia\n\nThis x 1.30: 2.76\nThis'
' x 1.60: 3.39\n\nTotal: 6.15'))
]
for clientname, cart, output in testsuite:
f = NamedTemporaryFile(dir='.', delete=False)
name = f.name
f.close()
try:
save_bill(clientname, cart, name)
with open(name) as f:
collected_output = f.read().strip()
assert collected_output == output.strip(), (collected_output, output.strip())
finally:
os.remove(name)
Напишите класс Amoeba
, описывающий амёб. Каждая амёба имеет имя (атрибут name
), цвет (атрибут color
) и возраст (атрибут age
). Имя и цвет задаются строками, возраст — целым числом (количество дней, прошедших с момента рождения амёбы; в момент рождения инициализируется нулём). Когда амёбе исполняется 3 дня, она становится совершеннолетней и может производить потомство. Размножение у амёб бесполое. Каждая амёба хранит список своих детей (children
). При рождении амёбы этот список пустой, с рождением каждого ребёнка он вписывается в этот список (в порядке рождения: то есть каждый новый ребёнок записывается в конец списка). При создании амёбы человеком её цвет указывается явно в момент создания. Если амёба рождаёт ребёнка, его цвет совпадает с цветом амёбы-родителя. Амёба, рождённая другой амёбой, знает, кто её родитель (она хранит эту информацию в атрибуте parent
). Если амёбу создал человек, то атрибут parent
инициализируется None
.
Итак, класс Amoeba
должен обладать следующими атрибутами:
name
: строкаcolor
: строкаage
: целое числоparent
: экземпляр класса Amoeba
children
: список экземпляров класса Amoeba
(быть может, пустой)Необходимо реализовать следующие методы:
__init__()
: конструктор, принимает на вход name
, color
и parent
, если parent
не установлен, его следует считать равным None
. (1 балл.)__repr__()
: строковое представление, имеющее вид "Amoeba(name='{name}', color='{color}')"
, где {name}
и {color}
— её имя и цвет. Например, Amoeba(name='Laama', color='green')
(1 балл.)__str__()
: человекочитаемое строковое представление, имеющее вид <{color} amoeba named {name}>
. (Например, <green amoeba named Laama>
.) (1 балл.)grow()
: увеличить возраст на 1. (1 балл.)is_adult()
: проверить, является ли амёба взрослой; если да, вернуть True
, иначе вернуть False
. (1 балл.)give_birth()
: принимает на вход аргумент name
. Если амёба является взрослой, она должна родить ребёнка, то есть создать новую амёбу, имя которой равно name
и цвет которой совпадает со своим цветом, записать этого ребёнка в список своих детей (в конец списка), записать себя как родителя этого ребёнка и вернуть этого ребёнка. Если амёба не является взрослой, этот метод ничего не делает и возвращает None
. (2 балла.)get_brothers()
: возвращает список всех амёб, являющихся братьями данной. Амёба не считается братом самой себе. Если у амёбы нет родителя, возвращает None
. (2 балла.)get_grandmother()
: возвращает бабушку текущей амёбы или None
, если у амёбы нет бабушки (то есть она сама или её родитель были созданы человеком). (1 балл.)get_cousins()
: возвращает список всех двоюродных братьев (то есть всех внуков моей бабушки, не являющихся моими родными братьями) или None
если у неё нет бабушки. Если бабушка есть, но двоюродных братьев нет, то функция должна вернуть пустой список, а не None
. (3 балла.)is_relative_to(other)
: проверяет, является ли данная амёба родственницей амёбе other
. Родственниками называются амёбы, если одна из них является предком другой, или если они имеют общего предка (например, дядя и его племянник — родственники, потому что бабушка племянника является мамой дяди). Каждый является родственником самому себе. (4 балла.) Подсказка. При написании этого метода полезно создать метод _all_ancestors()
, возвращающий список всех предков. Вам также могут пригодиться множества (set
)."# YOUR CODE HERE"
laama = Amoeba("Laama", "green")
assert laama.color == 'green'
assert laama.age == 0
assert laama.children == []
assert laama.parent is None
assert laama.name == "Laama"
quuma = Amoeba("Quuma", "yellow")
assert quuma.color == 'yellow'
assert quuma.age == 0
assert quuma.parent is None
assert laama.children == []
assert quuma.name == 'Quuma'
laama = Amoeba("Laama", "green")
quuma = Amoeba("Quuma", "yellow")
import re
assert re.match(r"Amoeba\(name=['\"]Laama['\"], color=['\"]green['\"]\)$", repr(laama))
assert repr(laama).count("'") == 4 or repr(laama).count('"') == 4
assert re.match(r"Amoeba\(name=['\"]Quuma['\"], color=['\"]yellow['\"]\)$", repr(quuma))
laama = Amoeba("Laama", "green")
quuma = Amoeba("Quuma", "yellow")
assert str(laama) == '<green amoeba named Laama>'
assert str(quuma) == '<yellow amoeba named Quuma>'
laama = Amoeba("Laama", "green")
for i in range(100):
assert laama.age == i
laama.grow()
laama = Amoeba("Laama", "green")
assert not laama.is_adult()
laama.grow()
assert not laama.is_adult()
laama.grow()
assert not laama.is_adult()
laama.grow()
assert laama.is_adult()
laama.grow()
assert laama.is_adult()
laama = Amoeba("Laama", "green")
assert laama.give_birth("Laamiesh") is None
assert laama.children == []
laama.grow()
laama.grow()
laama.grow()
child = laama.give_birth("Laamiesh")
assert child is not None
assert child is laama.children[0]
assert child.parent is laama
assert child.color == laama.color
assert child.color == 'green'
oldchild = child
laama.grow()
child = laama.give_birth("Laamien")
assert child is not None
assert child is laama.children[1]
assert child.color == laama.color
assert child.color == 'green'
assert child.parent is laama
assert oldchild != child
laama = Amoeba("Laama", "green")
laama.grow()
laama.grow()
laama.grow()
child1 = laama.give_birth("Lammuq")
child2 = laama.give_birth("Laamaq")
child3 = laama.give_birth("Laameq")
assert set(child1.get_brothers()) == set([child2, child3])
assert set(child2.get_brothers()) == set([child1, child3])
assert set(child3.get_brothers()) == set([child1, child2])
assert laama.get_brothers() is None
quuma = Amoeba("Quuma", "yellow")
quuma.grow()
quuma.grow()
quuma.grow()
quuma_child = quuma.give_birth("Zzz")
assert quuma_child.get_brothers() == []
laama = Amoeba("Laama", "green")
laama.grow()
laama.grow()
laama.grow()
xeema = laama.give_birth("Xeema")
xeema.grow()
xeema.grow()
xeema.grow()
rooma = xeema.give_birth("Rooma")
assert rooma.get_grandmother() is laama
assert xeema.get_grandmother() is None
assert laama.get_grandmother() is None
laama = Amoeba("Laama", "green")
laama.grow()
laama.grow()
laama.grow()
child1 = laama.give_birth("Child 1")
child2 = laama.give_birth("Child 2")
child3 = laama.give_birth("Child 3")
child1.grow()
child1.grow()
child1.grow()
child2.grow()
child2.grow()
child2.grow()
child3.grow()
child3.grow()
child3.grow()
grandchild11 = child1.give_birth("Grandchild 1 1")
grandchild12 = child1.give_birth("Grandchild 1 2")
grandchild21 = child2.give_birth("Grandchild 2 1")
grandchild22 = child2.give_birth("Grandchild 2 2")
grandchild23 = child2.give_birth("Grandchild 2 3")
grandchild31 = child3.give_birth("Grandchild 3 1")
grandchild32 = child3.give_birth("Grandchild 3 2")
grandchild33 = child3.give_birth("Grandchild 3 3")
grandchild34 = child3.give_birth("Grandchild 3 4")
assert set(grandchild11.get_cousins()) == set([grandchild21, grandchild22,
grandchild23, grandchild31,
grandchild32, grandchild33,
grandchild34])
assert set(grandchild12.get_cousins()) == set([grandchild21, grandchild22,
grandchild23, grandchild31,
grandchild32, grandchild33,
grandchild34])
assert set(grandchild34.get_cousins()) == set([grandchild11, grandchild12,
grandchild21, grandchild22,
grandchild23])
assert set(grandchild31.get_cousins()) == set([grandchild11, grandchild12,
grandchild21, grandchild22,
grandchild23])
from itertools import product
laama = Amoeba("Laama", "green")
laama.grow()
laama.grow()
laama.grow()
child1 = laama.give_birth("Child 1")
child2 = laama.give_birth("Child 2")
child3 = laama.give_birth("Child 3")
child1.grow()
child1.grow()
child1.grow()
child2.grow()
child2.grow()
child2.grow()
child3.grow()
child3.grow()
child3.grow()
grandchild11 = child1.give_birth("Grandchild 1 1")
grandchild12 = child1.give_birth("Grandchild 1 2")
grandchild21 = child2.give_birth("Grandchild 2 1")
grandchild22 = child2.give_birth("Grandchild 2 2")
grandchild23 = child2.give_birth("Grandchild 2 3")
grandchild31 = child3.give_birth("Grandchild 3 1")
grandchild32 = child3.give_birth("Grandchild 3 2")
grandchild33 = child3.give_birth("Grandchild 3 3")
grandchild34 = child3.give_birth("Grandchild 3 4")
xeema = Amoeba("Xeema", "purple")
xeema.grow()
xeema.grow()
xeema.grow()
xeema_child1 = xeema.give_birth("Xeema Child 1")
xeema_child2 = xeema.give_birth("Xeema Child 2")
xeema_child1.grow()
xeema_child1.grow()
xeema_child1.grow()
xeema_child2.grow()
xeema_child2.grow()
xeema_child2.grow()
xeema_grandchild11 = xeema_child1.give_birth("Xeema Grandchild 1 1")
xeema_grandchild21 = xeema_child2.give_birth("Xeema Grandchild 2 1")
laama_family = [laama, child1, child2, child3, grandchild11, grandchild12,
grandchild21, grandchild22, grandchild23, grandchild31,
grandchild32, grandchild32, grandchild33, grandchild34]
xeema_family = [xeema, xeema_child1, xeema_child2, xeema_grandchild11,
xeema_grandchild21]
for lf1, lf2 in product(laama_family, repeat=2):
assert lf1.is_relative_to(lf2)
for xf1, xf2 in product(xeema_family, repeat=2):
assert xf1.is_relative_to(xf2)
for xf, lf in product(xeema_family, laama_family):
assert not xf.is_relative_to(lf)
assert not lf.is_relative_to(xf)