Домашние задания по курсу «Язык программирования Python»

  • Установить Python на хорошо доступный вам компьютер
  • Найти установленную документацию, в частности tutorial
  • Запустить Python в режиме командной строки
  • Начать читать и отщелкивать tutorial, пока не надоест

  1. Прочитать и отщёлкать appetite.html, interpreter.html и introduction.html

  2. Добыть на рабочем компьютере
    • Python (третий, разумется)

    • Редактор, в котором можно писать программы (idle есть почти всегда, например, в дистрибутивах ALT Linux он лежит в пакете python3-tools и называется idle3)

    • Написать и запустить программу из файла, в котором написано:
         1 print("QQ")
      
  3. Зарегистрироваться в EJudge (164 турнир)

Более подробные формулировки задач и интерфейс для их сдачи доступны по ссылкам. В формулировках имеются советы и подсказки-спойлеры (доступны, если нажать «показать комментарии»). Пользоваться последовательностями Python (кроме преобразования ввода и множественного связывания) в этих задачах нельзя.

Ограничения Pytnon3.7

На факультетском EJudge используется Python3.7, в нём не работает конструкция «:=», увы!

  1. Прочитать и прощёлкать учебник (до функций)

  2. EJudge: SquareEquation 'Квадратное уравнение'

    Ввести через запятую три числа: a, b и c, вывести все вещественные решения уравнения $$ax^2+bx+c=0$$. При $$a\ne 0$$ это уравнение превращается в квадратное. Решения выводить через пробел в порядке возрастания, если решений нет, вывести 0, если их бесконечно много — -1.

    Input:

    1,-3,2
    Output:

    1.0 2.0
  3. EJudge: SecondMax 'Почти победа'

    Ввести по одному в строке целые числа, не равные нулю (не менее одного, конец ввода — 0), вывести второй максимум последовательности (число, строго меньшее максимума последовательности, и не меньшее остальных чисел в ней), и NO, если такового нет.

    Input:

    1
    2
    3
    4
    3
    2
    1
    0
    Output:

    3
  4. EJudge: DotBox 'Ящик с точками'

    Вводить вещественные числа x, y и z по три в строке через запятую, считая их координатами точек (не менее одной тройки). Конец ввода — пустая строка. Вывести минимальный объём параллелепипеда со сторонами, параллельными осям координат, содержащего все точки.

    Input:

    3,2,1
    -1.5, -1.5, -1.5
    1,-1.3,1
    0,0.5,0
    1,2,3
    
    Output:

    70.875
  5. EJudge: MaxSubsum 'Полоса удач'

    Ввести в столбик последовательность целых (положительных и отрицательных) чисел, не равных нулю; в конце этой последовательности стоит 0. Вывести наибольшую сумму последовательно идущих элементов этой последовательности (не менее одного).

    Input:

    2
    3
    -7
    -1
    3
    4
    5
    -2
    -4
    7
    8
    -6
    -1
    0
    Output:

    21
  1. Прочитать и прощёлкать тьюториалпро цикл for) TODO Тесты к задачам пока не готовы, появятся вечером.

  2. EJudge: HiddenText 'Скрытое послание'

    Ввести две строки и проверить, содержится ли вторая в первой, с учётом того, что символы второй строки могут находиться в первой на некотором равном расстоянии друг от друга. Вывести YES или NO.

    Input:

    q-We-Rt-Yu-Iweozzz
    WRYI
    Output:

    YES
  3. EJudge: MaxPrime 'Ближайшее простое'

    Ввести натуральное 1000000000000>N>1 и вывести максимальное простое число, не превосходящее N.

    Input:

    12345
    Output:

    12343
  4. EJudge: PairCubes 'Пары кубов'

    Ввести натуральное число и проверить, представимо ли оно в виде суммы кубов двух натуральных чисел. Вывести YES или NO. Придумать алгоритм поэффективнее.

    Input:

    32232195
    Output:

    YES
  5. EJudge: HandShakes 'Теория рукопожатий'

    Вводить построчно разделённые запятыми последовательности натуральных чисел (кортежи), окончание ввода — пустая строка. Числа в строке — идентификаторы людей, которые познакомились (или уже были знакомы) на некоторой вечеринке. Верно ли, что от любого из перечисленных людей можно построить цепочку знакомств к любому другому? Иными словами, если считать каждую пару x,y ребром неориентированного графа, является ли этот граф связным? Вывести YES или NO.

    Input:

    11,2,3
    7,8,9,
    36,10
    4,2
    5,7,
    11,3,4,
    9,5
    Output:

    NO
  1. Прочитать:
  2. EJudge: FourSquares 'Четыре квадрата'

    Известно, что любое натуральное число можно представить в виде суммы не более чем четырех квадратов неотрицательных целых чисел (теорема Лагранжа). Ввести натуральное N⩽100000 и найти для него такие целые неотрицательные x,y,z и t, чтобы x²+y²+z²+t²=N. Вывести все такие четвёрки в следующем формате: x,y,z и t — через пробел, и упорядочены по убыванию, а сами четвёрки — лексикографически по возрастанию (без повторений).

    Input:

    100
    Output:

    5 5 5 5
    7 5 5 1
    7 7 1 1
    8 4 4 2
    8 6 0 0
    9 3 3 1
    10 0 0 0
  3. (задача типа «написать функцию»)

    EJudge: Without2Zeros 'Без двух нулей'

    Написать функцию No_2Zero(N, K), которая вычисляет количество N-значных чисел в системе счисления с основанием K, таких что их запись не содержит двух подряд идущих нулей. Лидирующие нули не допускаются. Для EJudge N⩽33.

    Input:

    print(No_2Zero(6, 3))
    Output:

    328
  4. (задача типа «написать функцию»)

    EJudge: ArithFunct 'Арифметика функций'

    Написать четыре функции (функционала): ADD(f, g), SUB(f, g), MUL(f, g) и DIV(f, g), параметрами которых могут быть как обычные объекты, так и функции от одной переменной (проверить, является ли объект функцией можно с помощью callable(объект)). Возвращать эти функционалы должны функцию от одной переменнойh(x), которая выполняет соответствующее действие (f(x)+g(x), f(x)-g(x), f(x)*g(x) и f(x)/g(x)) над этими переменными. Если f или g не были функцией, вместо f(x) используется f, а вместо g(x)g (например, при умножении функции на константу).

    Input:

    from math import *
    
    f = SUB(sin, cos)
    print(f(12), sin(12)-cos(12))
    
    g = DIV(sin, cos)
    print(g(pi/6), tan(pi/6))
    
    h = MUL(exp, 0.1)
    print(h(2), e**2/10)
    
    t = ADD(len, sum)
    print(t(range(5)))
    Output:

    -1.380426876732927 -1.380426876732927
    0.5773502691896256 0.5773502691896257
    0.7389056098930651 0.738905609893065
    15
  1. Прочитать и прощёлкать про строки в учебнике, в документации, а также про форматирование строк в учебнике и в документации.

TODO

  1. EJudge: AsciiGlass 'Стакан'

    Вводится ASCII-art с изображением стакана (возможно, с водой), падающего в ведро (последняя строка — пустая). Толщина стенок стакана — 1. После падения стакан оказывается на боку в левом нижнем углу ведра (даже если он размером с ведро; больше он не бывает), а вода из него выливается, заполняя ровным слоем дно ведра и заслоняя стакан (толщина слоя округляется в большую сторону). Вывести ведро с упавшим стаканом.

    Input:

    ..........
    ..........
    .#....#...
    .#....#...
    .#****#...
    .#****#...
    .#****#...
    .#****#...
    .######...
    ..........
    ..........
    ..........
    Output:

    ..........
    ..........
    ..........
    ..........
    ..........
    ..........
    #######...
    #.........
    #.........
    #.........
    **********
    **********
  2. EJudge: ArbitPrec 'Произвольная точность'

    Вводится две строки: произвольная функция над x, содержащая операции, применимые к типу decimal.Decimal, имеющая единственный корень на интервале (-1.5, 1.5), непрерывная на нём и принимающая значения разных знаков на концах интервала, и натуральное число D. Вывести корень данной функции с точностью ровно D знаков после запятой (нули тоже выводятся). Воспользоваться десятичным контекстом для задания точности (см. примеры выше на странице документации).

    Input:

    1+x*3
    20
    Output:

    -0.33333333333333333333
  3. EJudge: XenLeaders 'Чемпионы дзена'

    Ввести построчно список участников некоторого соревнования на скорость неизвестно чего в виде Имя Фамилия Название команды часы:минуты:секунды (последняя строка пустая), и вывести всех, кто занял первые три места (минимальное затраченное неизвестно на что время; одно место может занять несколько человек, если время совпадает), в порядке возрастания времени, а внутри одного времени — лекcикографически: фамилия, имя, команда. Дополнительное условие: таблица чемпионов должна быть аккуратной: поля «Имя», «Фамилия», «Название команды» и «Время» должны начинаться в одной колонке, но при этом быть максимально «упакованными»: столбцы в таблице должны быть разделены ровно одним пробелом.

    Input:

    Модест Камноедов НИИЧАВО 10:0:0
    Николай Долгоносиков Телепаты и спириты 5:3:31
    Рудольф Хлебовводов ТПРУНЯ 5:43:55
    Лавр Вунюков ТПРУНЯ 6:12:12
    Эдельвейс Машкин Пенсионеры-изобретатели 5:43:55
    Анатолий Скворцов Золотые руки Китежграда 2:14:3
    Амвросий Выбегалло НИИЧАВО 6:12:12
    Output:

    Анатолий  Скворцов     Золотые руки Китежграда 2:14:3
    Николай   Долгоносиков Телепаты и спириты      5:3:31
    Эдельвейс Машкин       Пенсионеры-изобретатели 5:43:55
    Рудольф   Хлебовводов  ТПРУНЯ                  5:43:55
  1. Прочитать про словари в учебнике и в документации

  2. EJudge: RandSquare 'Точка в квадрате'

    Написать функцию randsquare(A, B), принимающую на вход две пары вещественных чисел — координаты диагонали квадрата на плоскости. Функция должна возвращать случайную точку, принадлежащую этому квадрату (ожидаются точки из любого места квадрата, например, с его границы, хотя вероятность этого события будем считать нулевой).

    Input:

    # Это ошибочный тест!
    for i in range(100000):
        x, y = randsquare((0,-10.01), (0,10.01))
        if x**2+y**2 > 100:
            print(f"Error: {x}:{y}")
    Output:

    Error: -0.002220480791093505:-10.002541596486285
    Error: 0.0008220827409817354:-10.005657011321619
    Error: -0.0019093494480841855:10.007641260813324
    • Вот код, который рисует красивую картинку на эту тему ☺:
         1 def showgr(Dots, Corners, Name="Dots"):
         2     import numpy as np
         3     import matplotlib.pyplot as plt
         4 
         5     X, Y = zip(*Dots)
         6     fig, ax = plt.subplots(num=Name)
         7     ax.set_aspect(1)
         8     ax.scatter(X, Y)
         9     ax.fill(*Corners, fill=False)
        10     plt.show()
        11 
        12 def show(A, B, num=1000):
        13     dots = [randsquare(A, B) for i in range(num)]
        14     R = [ (A[0], (B[0]+A[0])/2-(B[1]-A[1])/2, B[0], (B[0]+A[0])/2+(B[1]-A[1])/2),
        15           (A[1], (B[1]+A[1])/2+(B[0]-A[0])/2, B[1], (B[1]+A[1])/2-(B[0]-A[0])/2)]
        16     showgr(dots, R)
        17 
        18 show((6,7), (2,12), 5000)
      
  3. EJudge: AnnaKar 'Словарь Толстого'

    Ввести два натуральных числа через запятую: N и W, а за ними построчно некоторый текст. Последняя строка — пустая. Выделить из текста слова (последовательности символов, для которых isalpha() истинно), преобразовать их в нижний регистр, и вывести Top-N по частоте встречаемости слов длиной не меньше W. Например, в Top-2 список входят все слова, которые встречаются чаще всех, и все слова, которые встречаются реже этих, но чаще всех остальных (обратите внимание на то, что Counter.most_common() ведёт себя иначе). Ключи сортировки вывода: сначала длина, потом слово. Если различных количеств встречаемых слов не больше N (например, все слова в тексте встречаются по разу), в Top-N входят все слова.

    Input:

    3,4
    cerebral atrophy, n:
            The phenomena which occurs as brain cells become weak and sick, and
    impair the brain's performance.  An abundance of these "bad" cells can cause
    symptoms related to senility, apathy, depression, and overall poor academic
    performance.  A certain small number of brain cells will deteriorate due to
    everday activity, but large amounts are weakened by intense mental effort
    and the assimilation of difficult concepts.  Many college students become
    victims of this dread disorder due to poor habits such as overstudying.
    -
    cerebral darwinism, n:
            The theory that the effects of cerebral atrophy can be reversed
    through the purging action of heavy alcohol consumption.  Large amounts of
    alcohol cause many brain cells to perish due to oxygen deprivation.  Through
    the process of natural selection, the weak and sick brain cells will die
    first, leaving only the healthy cells.  This wonderful process leaves the
    imbiber with a healthier, more vibrant brain, and increases mental capacity.
    Thus, the devastating effects of cerebral atrophy are reversed, and academic
    performance actually increases beyond previous levels.
    Output:

    3: atrophy
    3: performance
    4: cerebral
    6: brain
    6: cells
    • Не слишком интересная задачка, но весьма поучительная, если её натравить на «Анну Каренину», например, с параметрами 11,5. Толстой зануда.

  4. EJudge: PokeMon 'Покемоны'

    Участники некоторой карточной игры владеют несколькими колодами, из которых они составляют свой уникальный игровой набор. Каждая колода имеет номер; колоды с одинаковыми номерами содержат совпадающие наборы карт. Ввести строки вида "имя игрока / номер колоды" (колода принадлежит игроку) или "номер колоды / название карты" (карта входит в колоду); последняя строка пустая. Вывести в алфавитном порядке имена игроков, которые могут составить игровой набор из наибольшего числа различных карт.

    Input:

    0 / Misdreavus
    Svjatoslav Devjatkov / 3
    2 / Yamask
    Vsevid Mladenov / 1
    1 / Keldeo
    0 / Keldeo
    1 / Misdreavus
    2 / Scatterbug
    0 / Crawdaunt
    2 / Keldeo
    1 / Vanillite
    Svjatoslav Devjatkov / 0
    2 / Gardevoir
    Neljub Mstislavin / 2
    2 / Crawdaunt
    0 / Yamask
    3 / Reshiram
    Output:

    Neljub Mstislavin
    Svjatoslav Devjatkov
  1. Прочитать

TODO

  1. EJudge: YinYang 'Ч/Б'

    Написать генератор YinYang(Seq,,1,,, …, Seq,,n,, …), который получает на вход конечное количество (возможно, бесконечных) числовых последовательностей, а возвращает сначала все чётные элементы этих последовательностей, а затем нечётные. Например, YinYang([1,2,3], [6,5,4,3]) вернёт 2 … 6 … 4 … 1 … 3 … 5 … 3.

    Input:

    print(*list(YinYang([1,2,3], [6,5,4,3])))
    Output:

    2 6 4 1 3 5 3
  2. EJudge: ChudnPi 'Много знаков Пи'

    Написать бесконечный генератор PiGen(), вычисляющий Decimal представление числа Пи c 9999 знаками после запятой (всего 10000☺) по алгоритму Чудновских (согласно английской Википедии Чудновских там было боле одного):

    • $$ \frac{(640320)^{3/2}}{12\pi}=\frac{426880\sqrt{10005}}{\pi} = \sum_{k=0}^{\infty} \frac{(6k)! (545140134k + 13591409)}{(3k)!(k!)^3 (-262537412640768000)^{k}} $$

    • На каждой итерации PiGen() возвращает значение для очередного k.

    Input:

       1 for i, p in enumerate(PiGen()):
       2     if i>120:
       3         break
       4 print(str(p)[1400:1470])
    
    Output:

    7967823547816360093417216412199245863150302861829745557067498385054945
  3. EJudge: VirtualTurtle 'Примитивная черепашка'

    Написать параметрический генератор turtle(coord, direction), описывающий движение «черепахи» по координатной плоскости. coord — это кортеж из двух целочисленных начальных координат, direction описывает первоначальное направление (0 — восток, 1 — север, 2 — запад, 3 — юг). Координаты увеличиваются на северо-восток. Генератор принимает три команды — "f" (переход на 1 шаг вперёд), "l" (поворот против часовой стрелки на 90°) и "r" (поворот по часовой стрелке на 90°) и возвращает текущие координаты черепахи.

    Input:

       1 robo = turtle((0,0),0)
       2 start = next(robo)
       3 for c in "flfrffrffr":
       4     print(*robo.send(c))
    
    Output:

    1 0
    1 0
    1 1
    1 1
    2 1
    3 1
    3 1
    3 0
    3 -1
    3 -1
  1. Прочитать про классы в tutorial; про «волшебные методы» например, тут

  2. EJudge: CountFields 'Счётчик полей'

    Написать функцию fcounter(), которая первым параметром получает некоторый класс, а остальные параметры применяет для создания экземпляра этого класса (передаёт конструктору). Функция должна возвращать 4 отсортированных списка: имена методов класса, имена полей класса, имена методов, которые появились в экземпляре (т. е. в классе их не было, а при создании экземпляра они появились) и имена полей, которые появились в экземпляре (под «полями» имеются в виду не-callable() атрибуты). Внимание! Поле может внезапно сделаться классом (и наоборот), такие ситуации тоже надо отслеживать. Имена, начинающиеся на "_", не учитываются.

    Input:

    class C:
        x, y, z = 1, 3, 5
    
        def X(self): return self.x
        def Y(self): return self.y
    
        def __init__(self, dx, dy, dz):
            self.x = dx
            self.Y = dy
            self.Z = dz
    
    cm, cf, om, of = fcounter(C, 6, 7, 8)
    print("Class: methods", *cm)
    print("Class: fields", *cf)
    print("Object: methods", *om)
    print("Object: fields", *of)
    Output:

    Class: methods X Y
    Class: fields x y z
    Object: methods
    Object: fields Y Z
  3. EJudge: NutsClass 'Странный класс'

    Написать класс Nuts, экземпляры которого

    • можно конструировать из чего угодно (в т. ч. из ничего)
    • можно индексировать по чему угодно (возвращается объект, который использовался в индексе)
      • в том числе позволяют присваивать и удалять по индексу (ничего не происходит)
    • содержат любое поле (возвращается имя этого поля)

      • в том числе позволяют присваивать и удалять поля (ничего не происходит)
    • итерируемы (последовательность пуста)
    • в виде строки представляются как "Nuts"

    Input:

       1 M, N = Nuts(), Nuts(1,2,3,4)
       2 print(M, N)
       3 M[100] = N.qwerty = 42
       4 print(M[100], N.qwerty)
       5 print(*list(Nuts("QWERQWERQWER")))
       6 del M["QQ"], N[6:10], M[...], N._
       7 print(M.asdfg, N[-2])
    
    Output:

    Nuts Nuts
    100 qwerty
    
    asdfg -2
  4. EJudge: SpiralString 'Спиральки'

    Написать класс Spiral, экземпляр которого образуется из строки, содержащей одну или несколько последовательностей одинаковых символов, например, "122333444455555". При преобразовании в строку такая последовательность должна «закручиваться в спираль» против часовой стрелки(см. пример). Помимо преобразования в строку объект типа Spiral должен:

    • Поддерживать сложение с таким же объектом: существующие в исходном объекте последовательности увеличиваются на соответствующее количество символов, новые — добавляются в конец
    • Поддерживать вычитание объектов типа Spiral, при этом существующие последовательности уменьшаются в длине (до полного исчезновения, если в вычитаемом было больше таких символов)

    • Поддерживать умножение на натуральное число N (количество символов в последовательностях увеличивается в N раз)

    • Поддерживать итератор по всем символам последовательности
    Input:

       1 S = Spiral("abbcccddddeeeee")
       2 I = Spiral("abcdefghi")
       3 
       4 print(f"{S}\n")
       5 print(S+I, "\n")
       6 print(S-I, "\n")
       7 print(I*2, "\n")
       8 print(I*2-S, "\n")
       9 print(*list(S+I))
    
    Output:

    dccc
    d  b
    d ab
    d
    eeeee
    
       ihg
         f
    ccbb e
    c  b e
    c aa e
    d    e
    ddddee
    
    eddd
    e  c
    e bc
    e
    
    dccb
    d  b
    e aa i
    e    i
    ffgghh
    
    hhgg
    i  f
    i af
    
    a a b b b c c c c d d d d d e e e e e e f g h i
  1. Прочитать и прощёлкать
  2. EJudge: RegexDump 'Структура РВ'

    Написать программу, которой на вход подаётся синтаксически верное регулярное выражение, а затем — строки поиска (последняя строка пустая). Программа должна выводить информацию о первой найденной в строке поиска подстроке, соответствующей регулярному выражению, в таком формате:

    • Если подстрока не найдена, выводится «<NONE>»

    • Если подстрока найдена, выводится позиция: подстрока, где «позиция» — это номер символа в строке, начиная с которого была найдена подстрока

    • Если в регулярном выражении присутствовала группировка с сохранением (попросту скобочки), выводится номер группы/позиция: подстрока для каждой группы

    • Если в регулярном выражении присутствовали именованные группы, выводится имя группы/позиция: подстрока для каждой группы

    • Если какая-то группа присутствует в исходном выражении, но не нашла сопоставления (например, была помечена повторителем * и пропущена), она не выводится

    Input:

    (\w)+(@+)?(?P<nonalpha>\W+)--(\w+)
    ^_^awww-----foo;_;
    #$qwer@@@--wqer#$
    Output:

    3: awww-----foo
    1/6: w
    3/7: ---
    4/12: foo
    nonalpha/7: ---
    2: qwer@@@--wqer
    1/5: r
    2/6: @@
    3/8: @
    4/11: wqer
    nonalpha/8: @
  3. EJudge: ChicagoTurabian 'Чикаго Турабьян'

    Написать программу, которой на вход подаётся две строки — библиографическая ссылка B на некоторую книгу и внутритекстовая ссылка N на эту же книгу. программа должна проверить, что обе ссылки синтаксически верны и ссылаются на одну и ту же книгу. Формат ссылок — упрощённый стиль Турабьян. Вывод программы — True, если B соответствует N, и False — если не соответствует, или такое соответствие невозможно определить из-за синтаксической некорректности

    • Полное описание стиля для задачи с примерами

      • Обратите внимание на то, как в B слились точка после инициала автора и точка после списка авторов.

    • Будем считать, что страница может быть указана или одна, или диапазоном
      • Во всех примерах со страницами «» — это не «» и не «-». Серьёзно! А в интернете бывает все три.

    • Будем считать, что у первого автора всегда есть и имя, и фамилия
    • Никаких вложенных скобок!
    • Обратите внимание на т. н. «оксфордскую запятую» перед словом «and» (она не соблюдается только для двух авторов в N, в B и в остальных N — соблюдается)

    Input:

    42. Roger Frey, Utility and Rights (Minneapolis: University of Minnesota Press, 1984), 95.
    Frey, Roger. Utility and Rights. Minneapolis: University of Minnesota Press, 1984.
    Output:

    True
  4. EJudge: PigLatin 'Поросячья латынь'

    Согласно правилам «поросячьей латыни» английские слова при разговоре преобразуются так:

    • Если слово начинается на согласную — эта согласная переносится в конец слова, после чего добавляется «ay»: "latin" ⇒ "atinlay"

    • Если слово начинается на несколько согласных, они все переносятся в конец слова, после чего добавляется «ay»: "stupid" ⇒ "upidstay"

    • Если слово начинается на гласную, "aouie" (не "y"!) и имеет более одного слога, лидирующая гласная и все согласные за ней переносятся в конец с добавлением «ay»: "under" ⇒ "erunday" (в Википедии это второй вариант)

      • для нашего удобства непроизносимые гласные тоже считаются слогом, например "are" ⇒ "earay"; (так исторически не было: язык всё-таки разговорный)

    • Односложные слова, начинающиеся на гласную, просто дополняются «yay»: "egg" ⇒ "eggyay"

    • Слова без гласных не изменяются. Гласными считаются "aouieAOUIE", но не "Y/y". Это случайно здесь оказавшееся требование, которое я не буду удалять, потому что некоторые уже решили так.

    • Апостроф считается согласной буквой (маленькой), а дефис — разделителем (опять-таки для простоты)

    Написать программу, которая построчно вводит «английский» текст (текст, содержащий последовательности латинских букв и другие символы; последняя строка пустая) и выводит перевод на поросячью латынь (для простоты любая последовательность английских букв с гласными считается словом). Обратите внимание на то, что слово, написанное со прописной буквы, в поросячьей латыни также пишется со прописной буквы. Более одной прописной буквы в слове не встречается.

    Input:

    This is an example of Hog Latin. As you can see, it's silly,
    but lots of fun for children.
    Output:

    Isthay isyay anyay ampleexay ofyay Oghay Atinlay. Asyay ouyay ancay eesay, it'syay illysay,
    utbay otslay ofyay unfay orfay ildrenchay.
  1. Прочитать:
  2. EJudge: MroC3 'MRO C3'

    Написать программу, на вход которой подаётся ситнаксически верный код на ЯП Python, без пустых строк и многострочных констант; пустая только последняя строка. В этом коде

    • Могут быть определены некоторые классы с помощью оператора class на верхнем уровне программы (т. е. не внутри классов/функций)

    • Имена классов не меняются (т. е. после class C: … никогда не бывает C = …)

    • В наследовании используются только уже определённые в этом коде классы
    • На выходе программа должна отчитаться, допустимо ли наследование, которое (возможно) встретилось в коде (с точки зрения NRO C3), и вывести "Yes" или "No".

    Input:

    class A:
        B = 0
    class B(A): pass
    class C(A, B):
        A = B = C = 5
    Output:

    No
  3. EJudge: BoldCalc 'Надёжный калькулятор'

    Написать программу — калькулятор с переменными и обработкой ошибок. Программа построчно вводит команды калькулятора, и если надо, выводит результат их выполнения или ошибку.

    • Пробелы в строках игнорируются
    • Команда, начинающаяся на '#' — комментарий, такие команды игнорируются

    • Команда вида Идентификатор = выражение задаёт переменную Идентификатор

      • идентификатор определяется стандартно: «произвольная последовательность латинских букв, цифр и символов подчёркивания не начинающаяся с цифры»

      • Если слева от "=" стоит не идентификатор, выводится "Assignment error"; всё, что справа, игнорируется, присваивания не происходит

    • Команда вида выражение выводит значение выражения.

    • Выражение вычисляется по правилам арифметики, и может состоять из
      • целых чисел

      • уже определённых идентификаторов
      • круглых скобок, внутри которых должно находиться непустое выражение
      • действий +, -, *, /, % и унарных + и -.

        • Деление целочисленное

      • Любое другое выражение приводит к выводу ошибки "Syntax error"

    • Если выражение нельзя вычислить, потому что в нём встречаются неопределённые переменные, выводится ошибка "Name error"

    • Если выражение нельзя вычислить по какой-то другой причине, выводится "Runtime error"

    Input:

    # Ошибок нет
    234
    10/3
    A = 3*(2+(1-7)%5)
    A+100
    + ++ - -- - + - - 0
    # Начинаются ошибки
    7*B
    3=3
    A=4=5
    A()
    A/0
    Output:

    234
    3
    118
    0
    Name error
    Assignment error
    Syntax error
    Syntax error
    Runtime error
  4. EJudge: SubString 'Строки с вычитанием'

    Реализовать класс SubString, который бы полностью воспроизводил поведение str, но вдобавок бы поддерживал операцию вычитания строк. Вычитание устроено так: «уменьшаемое» просматривается посимвольно, и если соответствующий символ присутствует в «вычитаемом», то он однократно удаляется из обеих строк. Исходные объекты не меняются; то, что осталось от уменьшаемого, объявляется результатом вычитания.

    • К моменту прохождения теста ничего нового, кроме класса SubString в глобальном пространстве имён быть не должно

    Input:

       1 print(SubString("qwertyerty")-SubString("ttttr"))
    
    Output:

    qweyery
  1. Прочитать про всё, упомянутое выше. Пощёлкать примеры по каждой теме.

TODO

  1. EJudge: TypeCheck 'Проверка типов'

    Написать параметрический декоратор TypeCheck(последовательность_типов, тип_результата), который бросает исключение TypeError при вызове функции со следующим сообщением:

    • "Type of argument Номер is not Тип", если не совпадает тип позиционного параметра функции и соответствующий ему по порядку тип в последовательности_типов

    • "Type of argument 'Имя' is not Тип", если не совпадает тип именного параметра функции и соответствующий ему тип в последовательности_типов.

      • Типы именованных параметров перечислены в конце последовательности_типов

      • Типы именованных параметров проверяются в порядке их появления при вызове функции
    • "Type of result is not Тип", если тип возвращённого функцией значения не совпадает с типом_результата

    • "Function функция must have число arguments" — если количество переданных функции параметров (включая переданные по умолчанию) не соответствует длине последовательности_типов

    • Сначала проверяются параметры в порядке описания в функции, затем вызывается функция, после чего проеряется результат. Ислкючение возникает при первом несовпадении типа.
    Input:

    18
    Type of argument 2 is not <class 'str'>
    Output:

    18
    Type of argument 2 is not <class 'str'>
  2. EJudge: FieldCounter 'Статистика с полей'

    Написать функцию,Stat() которая умеет выполнять две роли:

    • С одним параметром Stat(класс) — работает как декоратор класса

      • Добавляет в объекты класса сбор статистики по всем полям данных
        • упомянутым в самом классе (т. е. встречающимся в vars(класс))

        • имя которых не начинается с "_"

      • По всем остальным атрибутам (методам, спецметодам и т. п., а так же атрибутам, динамически добавленным в __init__() и других методах) статистика не ведётся

    • С двумя параметрами Stat(объект, "поле") — выводит статистику использования поля поле: два целых числа (количество чтений, количество записей)

      • объект — экземпляр класса, декорированного с помощью Stat

      • поле — поле этого класса

      • Если статистика по данному полю не ведётся, или поля не существует, обя значения равны 0
    • Экземпляр класса инициализируется с помощью __init__(), т. е. класс не является потомком встроенного класса, не переопределяет __new__(), __getattribute__() и т. п., изначально не содержит слотов/дескрипторов.

    Input:

       1 @Stat
       2 class C:
       3     A, B = 3, 4
       4     def __init__(self, a=None):
       5         if a:
       6             self.A = a
       7 
       8 c, d = C(), C(123)
       9 print(Stat(c, "A"), Stat(d, "A"))
      10 d.A = c.A * 2 + c.B
      11 c.B = d.A - 1 - len([d.B, d.B, d.B])
      12 print(Stat(c, "A"), Stat(c, "B"))
      13 print(Stat(d, "A"), Stat(d, "B"))
      14 print(Stat(c, "Foo"))
    
    Output:

    (0, 0) (0, 1)
    (1, 0) (1, 1)
    (1, 2) (3, 0)
    (0, 0)
  1. Прощёлкать примеры с файлами в Tutorial, а также примеры по pickle и struct

  2. EJudge: TotalBnopnya 'Неудачная перекодировка'

    Текст процедуры на языке Рапира в кодировке koi8-r был несколько (не более четырёх раз) раз перекодирован, причём перекодировщику сообщали совершенно произвольную исходную и целевую кодировку (например, из CP866 в latin1). Восстановить предполагаемый текст процедуры.

    • В первой строке ввода — возможные кодировки, не более 8 (через пробел)
    • Во второй строке ввода — последовательность шестнадцатеричных цифр — это байты закодированной процедуры
    • На выходе — исходный текст процедуры.
    • Для упрощения будет считать, что в программе на языке Рапира могут присутствовать только
      • Заглавные русские и латинские буквы (строчных нет)

      • Цифры и символы из набора ()[]+-*/%;.,>=<"!:

      • Пробелы, табуляции и переводы строки
    • Известно, что неоднозначная перекодировка (в которой более одного входного символа соответствует одному выходному) не производилась

    Input:

    utf8 koi8-r CP1251 CP866 ISO8859-1 ISO8859-5 mac-arabic cp1140
    d0aed091e2959ed19120d0a6d094e29591d091d09428293b0a20202020d093d098d093e2959ee295933a2022d099e29593d091e29591d093d0a6d094d093d095e295992c20e2959ce29598d09121223b0ae2959ae2959dd1913b0a
    Output:

    utf8 koi8-r CP1251 CP866 ISO8859-1 ISO8859-5 mac-arabic cp1140
    6641665066316635c28066476644663366506644c288c289c29bc28ec280c280c280c28066c2b966c2ad66c2b966316657c29ac280c28266c3b466576650663366c2b96647664466c2b9664566c29fc28cc28066c39c66c3996650c281c282c29bc28e6639665c6635c29bc28e
  3. EJudge: ZipInfo 'Размер архива'

    Написать программу, которой на стандартный ввод подаётся zip-архив в виде шестнадцатеричного дампа (последовательность шестнадцатеричных цифр, возможно, разделённых пробелами и переводами строки), а на выходе она показывает количество и суммарный объём хранящихся в нём файлов, если их распаковать.

    • Внимание! в отличие от всех предыдущих задач, никакой пустой строки в конце нет, пользуйтесь файловыми операциями ввода!

    Input:

    504b03040a0000000000d6a07c5100000000000000000000000002001c00
    6f2f5554090003a483c25fab83c25f75780b000104f501000004f5010000
    504b03040a00000000000ea77c5100000000000000000000000004001c00
    6f2f312f55540900034c8fc25f568fc25f75780b000104f501000004f501
    0000504b03040a0000000000d8a07c510000000000000000000000000600
    1c006f2f312f352f5554090003a783c25fab83c25f75780b000104f50100
    0004f5010000504b03040a00000000000da77c5100000000000000000000
    000006001c006f2f312f322f5554090003498fc25f568fc25f75780b0001
    04f501000004f5010000504b03040a00000000000da77c514b8325172100
    0000210000000a001c006f2f312f322f646174655554090003498fc25f56
    8fc25f75780b000104f501000004f5010000d0a1d0b120d0bdd0bed18f20
    32382032303a35363a3235204d534b20323032300a504b03040a00000000
    0066a67c5100000000000000000000000008001c006f2f312f322f332f55
    54090003108ec25f3f8ec25f75780b000104f501000004f5010000504b03
    040a00000000000aa77c51ba7488890b0000000b0000000b001c006f2f31
    2f322f332f63616c5554090003438fc25f568fc25f75780b000104f50100
    0004f5010000323032302d31312d32380a504b03040a0000000000d6a07c
    510000000000000000000000000a001c006f2f312f322f332f342f555409
    0003a483c25fab83c25f75780b000104f501000004f5010000504b03040a
    00000000000ea77c5100000000000000000000000008001c006f2f312f6e
    6f6e6555540900034c8fc25f568fc25f75780b000104f501000004f50100
    00504b01021e030a0000000000d6a07c5100000000000000000000000002
    0018000000000000001000ed41000000006f2f5554050003a483c25f7578
    0b000104f501000004f5010000504b01021e030a00000000000ea77c5100
    0000000000000000000000040018000000000000001000ed413c0000006f
    2f312f55540500034c8fc25f75780b000104f501000004f5010000504b01
    021e030a0000000000d8a07c510000000000000000000000000600180000
    00000000001000ed417a0000006f2f312f352f5554050003a783c25f7578
    0b000104f501000004f5010000504b01021e030a00000000000da77c5100
    0000000000000000000000060018000000000000001000ed41ba0000006f
    2f312f322f5554050003498fc25f75780b000104f501000004f501000050
    4b01021e030a00000000000da77c514b83251721000000210000000a0018
    000000000001000000a481fa0000006f2f312f322f646174655554050003
    498fc25f75780b000104f501000004f5010000504b01021e030a00000000
    0066a67c51000000000000000000000000080018000000000000001000ed
    415f0100006f2f312f322f332f5554050003108ec25f75780b000104f501
    000004f5010000504b01021e030a00000000000aa77c51ba7488890b0000
    000b0000000b0018000000000001000000a481a10100006f2f312f322f33
    2f63616c5554050003438fc25f75780b000104f501000004f5010000504b
    01021e030a0000000000d6a07c510000000000000000000000000a001800
    0000000000001000ed41f10100006f2f312f322f332f342f5554050003a4
    83c25f75780b000104f501000004f5010000504b01021e030a0000000000
    0ea77c51000000000000000000000000080018000000000000000000a481
    350200006f2f312f6e6f6e6555540500034c8fc25f75780b000104f50100
    0004f5010000504b05060000000009000900b7020000770200000000
    Output:

    3 44

Задача сложная, присутствует исследование документации!

  1. Прочитать про:
    • Метаклассы
    • Модуль inspect (вот тут исследование)

    • Аннотации
  2. EJudge: MyMypy 'Типизация вручную'

    Написать метакласс checked, при использовании которого в порождаемом классе проверяются соответствия типов всех аннотированных параметров и возвращаемых значений всех методов. В случае несовпадения инициируется TypeError: Type mismatch: <параметр>

    • Значения параметров по умолчанию не проверяются (для простоты)
    • Поля не проверяются, только методы
    • Предполагается, что должна быть верна проверка isinstance(объект, тип), в противном случае соответствие считается неуспешным

    • При вызове (по крайней мере, в тестах) не используются конструкции *args и **kwargs

    • Параметры проверяются (если они аннотированы, конечно) в следующем порядке
      1. Позиционные (переданные в кортеже и распакованные) параметры, по порядку
      2. Явно заданные именные (переданные в словаре и распакованные) параметры в порядке вызова метода
      3. Нераспакованные позиционные параметры, полученные через *args. В этом случае в строке исключения пишется args (имя, которое при описании функции принимало запакованные позиционные параметры)

      4. Нераспакованные именные параметры, полученные через **kwargs

      5. Возвращаемое значение (имя параметра "return", как в аннотации)

    Input:

       1 class E(metaclass=checked):
       2     def __init__(self, var: int):
       3         self.var = var if var%2 else str(var)
       4 
       5     def mix(self, val: int, opt) -> int:
       6         return self.var*val + opt
       7 
       8     def al(self, c: int, d:int=1, *e:int, f:int=1, **g:int):
       9         return self.var*d
      10 
      11 e1, e2 = E(1), E(2)
      12 code = """
      13 e1.mix("q", "q")
      14 e1.mix(2, 3)
      15 e2.mix(2, "3")
      16 e1.al("q")
      17 e1.al(1, 2, 3, 4, 5, 6, foo=7, bar=8)
      18 e2.al(1, 2, 3, 4, 5, 6, foo=7, bar=8)
      19 e1.al("E", 2, 3, 4, 5, 6, foo=7, bar=8)
      20 e1.al(1, "E", 3, 4, 5, 6, foo=7, bar=8)
      21 e1.al(1, 2, "E", 4, 5, 6, foo=7, bar=8)
      22 e1.al(1, 2, 3, "E", 5, 6, foo="7", bar=8)
      23 e1.al(1, f="E", d=1)
      24 e1.al(1, f=1, d="E")
      25 e1.al(1, f="E", d="1")
      26 e1.al(1, d="E", f="1")
      27 e1.al(1, e="E")
      28 e1.al(1, g="E")
      29 """
      30 
      31 for c in code.strip().split("\n"):
      32     try:
      33         res = eval(c)
      34     except TypeError as E:
      35         res = E
      36     print(f"Run: {c}\nGot: {res}")
    
    Output:

    Run: e1.mix("q", "q")
    Got: Type mismatch: val
    Run: e1.mix(2, 3)
    Got: 5
    Run: e2.mix(2, "3")
    Got: Type mismatch: return
    Run: e1.al("q")
    Got: Type mismatch: c
    Run: e1.al(1, 2, 3, 4, 5, 6, foo=7, bar=8)
    Got: 2
    Run: e2.al(1, 2, 3, 4, 5, 6, foo=7, bar=8)
    Got: 22
    Run: e1.al("E", 2, 3, 4, 5, 6, foo=7, bar=8)
    Got: Type mismatch: c
    Run: e1.al(1, "E", 3, 4, 5, 6, foo=7, bar=8)
    Got: Type mismatch: d
    Run: e1.al(1, 2, "E", 4, 5, 6, foo=7, bar=8)
    Got: Type mismatch: e
    Run: e1.al(1, 2, 3, "E", 5, 6, foo="7", bar=8)
    Got: Type mismatch: e
    Run: e1.al(1, f="E", d=1)
    Got: Type mismatch: f
    Run: e1.al(1, f=1, d="E")
    Got: Type mismatch: d
    Run: e1.al(1, f="E", d="1")
    Got: Type mismatch: f
    Run: e1.al(1, d="E", f="1")
    Got: Type mismatch: d
    Run: e1.al(1, e="E")
    Got: Type mismatch: e
    Run: e1.al(1, g="E")
    Got: Type mismatch: g

Задач на EJudge нет.

TODO

Include: Ничего не найдено по регулярному выражению «== Д/З ==».

Модули. Будущее Python

Синтаксис — семантика — прагматика — практика. Нельзя объять необъятного.

Модули

Как работает import

Пакеты

Структура:

  • пакет/

    • __init__.py

    • (возможно) ещё что-то .py

    • (возможно) подпакет/

      • __init__.py

      • (возможно) ещё что-то .py

      • (возможно) подподпакет/

    • (возможно) подпакет/

Правила:

  • import пакет — только __init__.py

  • from пакет import что-то

  • from пакет import *, если в __init__ есть __all__ — имена из __all__

Дополнительно

  • Пакет — это программа, if __name__ == "__main__"

  • python -m пакет

Cборники (namespace packages)

TODO

Стандартные пакеты

обзор

  • Показать pydoc

PyPi

And finally

LecturesCMC/PythonIntro2020/Homework (последним исправлял пользователь FrBrGeorge 2021-03-31 09:19:50)