Задания для пересдачи

Можно пользоваться сайтами:

Другими сайтами (даже справочными) (stackoverflow и т. п.) пользоваться нельзя

Программирование-2

В качестве отчёта демонстрируется написанный код, а затем в командной строке — работа примеров, аналогичных примерами в задании, но не совпадающих с ними

  1. Написать класс Recurse, которому при создании передаётся функция f

    • Экземпляр класса должен поддерживать операцию индексирования по следующим правилам:
      1. recurse[x] возвращает бесконечную последовательность f(x), f(f(x)), … , f(…f(f(x))…), …

      2. recurse[x:n] возвращает бесконечную последовательность f(f(…n_раз…f(x))), f(f(…n+1_раз…f(x))), …,, т. е. исходную последовательность, начиная с n-го элемента

      3. recurse[x:n:k] возвращает конечную последовательность f(f(…n_раз…f(x))),  f(f(…n+1_раз…f(x))), … f(f(…k-1_раз…f(x))), т. е. исходную последовательность, начиная с n-го элемента и заканчивая перед k-м

    • Пример:
         1 >>> s=Recurse(lambda x: x*2+1)
         2 >>> list(zip(s[10], "QWERTYZ"))
         3 [(21, 'Q'), (43, 'W'), (87, 'E'), (175, 'R'), (351, 'T'), (703, 'Y'), (1407, 'Z')]
         4 >>> list(zip(s[10:2], "QWERTYZ"))
         5 [(87, 'Q'), (175, 'W'), (351, 'E'), (703, 'R'), (1407, 'T'), (2815, 'Y'), (5631, 'Z')]
         6 >>> list(zip(s[10:2:6], "QWERTYZ"))
         7 [(87, 'Q'), (175, 'W'), (351, 'E'), (703, 'R')]
         8 >>> from math import sin
         9 >>> g = Recurse(sin)
        10 >>> next(g[7:100500])
        11 0.005463237580162976
        12 >>> next(g[7:1005000])
        13 0.001727724719169488
        14 
      
  2. Написать класс Vect, унаследованный от list, со следующими изменениями:

    • При создании экземпляра должно проверяться, что
      1. Все элементы последовательности одного типа
      2. Этот тип поддерживает сложение и умножение на число
    • В противном случае возникает исключение Type Error

    • Класс поддерживает поэлементное умножение на число: vect @ 5

    • Класс поддерживает поэлементное сложение (вместо конкатенации): vect1 + vect2

    • Класс поддерживает запись в файл vect.write("файл") и чтение из файла vect.read("файл") (имя файла любое)

    • Пример:
         1 >>> v, w = Vect(range(9)), Vect(range(10,16))
         2 >>> v, w
         3 ([0, 1, 2, 3, 4, 5, 6, 7, 8], [10, 11, 12, 13, 14, 15])
         4 >>> v+w
         5 [10, 12, 14, 16, 18, 20]
         6 >>> v@3
         7 [0, 3, 6, 9, 12, 15, 18, 21, 24]
         8 >>> s = Vect("QWER")
         9 >>> s
        10 ['Q', 'W', 'E', 'R']
        11 >>> s+"ASDFG"
        12 ['QA', 'WS', 'ED', 'RF']
        13 >>> s@4
        14 ['QQQQ', 'WWWW', 'EEEE', 'RRRR']
        15 >>> l = Vect(i*2+1 for i in range(6))
        16 >>> l
        17 [1, 3, 5, 7, 9, 11]
        18 >>> e = Vect((1,2,3,4.4,5,6))
        19 Traceback (most recent call last):
        20   File "<stdin>", line 1, in <module>
        21   File "/home/george/src/Пересдача/vect.py", line 12, in 
        22 
        23 TypeError: All elements must share one type
        24 >>> e = Vect([None, None, None])
        25 Traceback (most recent call last):
        26   File "<stdin>", line 1, in <module>
        27   File "/home/george/src/Пересдача/vect.py", line 19, in 
        28 
        29 TypeError: Elements must be summable and multipliable
        30 >>> (v@3).write("EE")
        31 >>> s.read("EE")
        32 >>> s
        33 [0, 3, 6, 9, 12, 15, 18, 21, 24]
        34 
      

Программирование

  1. Написать функцию parcount(), которая

    • принимает произвольное количество позиционных и именных параметров
    • возвращает кортеж из двух чисел: количество различных типов данных среди позиционных параметров, количество различных типов данных среди именных параметров
    • вызывает исключение TypeError, если среди параметров встречается объект типа complex

    • вызывает исключение NameError (не TypeError), если среди именных параметров встречается параметр с именем complex

    • Пример:
         1 >>> parcount(1, 2, 3.3, 4, qwer="QWE", _=1, QQ=1.1)
         2 (2, 3)
         3 >>> parcount(j=1j)
         4 Traceback (most recent call last):
         5   File "<stdin>", line 1, in <module>
         6   File "/home/george/src/Пересдача/parcount.py", line 13, in parcount
         7 
         8 TypeError: No complex arguments is allowed
         9 >>> parcount(…)
        10 Traceback (most recent call last):
        11   File "<stdin>", line 1, in <module>
        12   File "/home/george/src/Пересдача/parcount.py", line 15, in parcount
        13 
        14 NameError: No 'complex' parameter name is allowed
      
    • Обратите внимание на то, что необходимо сделать пример, иллюстрирующий последнее требование (формат этого примера входит в задание, поэтому скрыт)
  2. Написать генератор-функцию zigzag(), принимающую на вход последовательность подпоследовательностей (например, список строк или итератор по кортежам).

    • Итератор, возвращаемый этой функцией, должен проходить элементы подпоследовательностей, находящихся на чётных местах, в прямом порядке, а на нечётных — в обратном
    • Если одна из подпоследовательностей пуста, итератор завершает работу
    • Если очередной элемент не является подпоследовательностью, должно вызываться исключение IndexError (а не Type Error)

    • Пример:
         1 >>> list(zigzag(["QE", "123", "ZXCVB"]))
         2 ['Q', 'E', '3', '2', '1', 'Z', 'X', 'C', 'V', 'B']
         3 >>> for z in zigzag(([1,2], "AB", [], [3,4,5,6])):
         4 ...     print(z)
         5 ... 
         6 1
         7 2
         8 B
         9 A
        10 >>> for z in zigzag([range(3), 1.1, "QWE"]):
        11 ...     print(z)
        12 ... 
        13 0
        14 1
        15 2
        16 Traceback (most recent call last):
        17   File "<stdin>", line 1, in <module>
        18   File "/home/george/src/Пересдача/zigzag.py", line 18, in zigzag
        19 
        20 IndexError: 1.1 must be iterable
      
  3. Написать функцию ifeval() от одного параметра-строки, которая проверяет, является ли эта строка вычислимым арифметическим выражением без скобок

    • Допустимое выражение может состоять только из
      • Целых десятичных чисел без знака
      • Идентификаторов (последовательность букв, цифр и символов подчёркивания, не начинающаяся с цифры)
      • Четырёх знаков арифметических операций (+, -, *, /)

      • Пробелов между операндами и знаками
    • Если выражение не вычислимо, функция возвращает False

    • Если выражение вычислимо, но содержит идентификатор, функция возвращает True

    • Если выражение вычислимо и состоит только из операций и числа, функция возвращает результат вычисления
    • Если при этом должно произойти исключение (например, деление на 0), оно происходит
    • Подсказка 1: задача решается с помощью двух несложных регулярных выражений, причём одно — часть второго
    • Подсказка 2: eval()

    • Пример:
         1 >>> ifeval("1 + 2 * 3 / 4")
         2 2.5
         3 >>> ifeval("int+2*SomeThing/4")
         4 True
         5 >>> ifeval("1+2+3+")
         6 False
         7 >>> ifeval("V a r + 1 2 3")
         8 False
         9 >>> 
      
  4. Написать параметрический декоратор unitype(N), в результате обработки которым

    • Функция принимает ровно N>0 позиционных параметров, причём всё эти параметры должны быть одного и того же типа.

    • Возвращаемое значение должно быть того же самого типа
    • В противном случае вызывается исключение TypeError

    • Пример:
         1 >>> fun(1., .1, 1.1)
         2 1.0909090909090908
         3 >>> fun(1., .1, 1)
         4 Traceback (most recent call last):
         5   File "<stdin>", line 1, in <module>
         6   File "/home/george/src/Пересдача/unitype.py", line 17, in newfun
         7 
         8 TypeError: Argument 1 must be of type <class 'float'>
         9 >>> fun(1., .1, 1., 1.)
        10 Traceback (most recent call last):
        11   File "<stdin>", line 1, in <module>
        12   File "/home/george/src/Пересдача/unitype.py", line 14, in newfun
        13 
        14 TypeError: Tere must be 3 arguments
        15 >>> fun(1, 1, 1)
        16 Traceback (most recent call last):
        17   File "<stdin>", line 1, in <module>
        18   File "/home/george/src/Пересдача/unitype.py", line 20, in newfun
        19 
        20 TypeError: Result must be of type <class 'int'>
      
      • fun(1., .1, 1.1) вернёт 1.090909090909090…, а fun(1, 1, 1), fun(1, 1., 1) и fun(1., 1., 1., 1.) — вызовут исключение

  5. Написать класс Person() с единственным параметром — строкой, содержащей разделённые одним или несколькими пробелами

    • Имя — одно слово (обязательный параметр)
    • (необязательные) Дополнительные имена — несколько слов
    • Фамилию (обязательные параметр) — одно слово
    • Класс должен поддерживать
      • Вывод с помощью print() (имена и фамилия, разделённые пробелами)

      • Поля .name и .family — строка с первым именем и фамилией соответственно

      • Операцию индексирования person[i], которая возвращает i-е имя персонажа (имя №0 — основное, фамилия именем не считается)

      • Операцию смены фамилии person <<= "NewFamily", которая заменяет фамилию персонажа

    • В случае отсутствия основного имени или фамилии при инициализации, или i-го имени при индексировании возбуждается какое-нибудь соответствующее исключение

    • Пример:
         1 >>> p = Person("Johann     Carl Friedrich   Gauß")
         2 >>> print(p)
         3 Johann Carl Friedrich Gauß
         4 >>> p <<= "Пупкин"
         5 >>> print(p)
         6 Johann Carl Friedrich Пупкин
         7 >>> p.name
         8 'Johann'
         9 >>> p[0]
        10 'Johann'
        11 >>> print(p[3])
        12 Traceback (most recent call last):
        13   File "<stdin>", line 1, in <module>
        14   File "/home/george/src/Пересдача/Person.py", line 21, in 
        15 
        16 IndexError: 
        17 >>> print(p[2])
        18 Friedrich
        19 >>> print(p.family)
        20 Пупкин
        21 
      
  6. Написать класс Stack, у которого есть поле buffer

    • Присваивание этому полю произвольного значения — это операция «положить значение на вершину стека»
    • Чтение значения этого поля — это операция «снять значение с вершины стека», которая возвращает это значение если стек не пуст
    • Если стек пуст, порождается исключение NotImplementedError (внимание: не IndexError)

    • Удаление этого поля — также операция «снять значение с вершины стека», которая ничего не возвращает, и не вызывает исключения на пустом стеке
    • Класс должен поддерживать вывод содержимого стека в любом удобном формате с помощью print()

    • Пример:
         1 >>> s=Stack()
         2 >>> s.buf=100500
         3 >>> s.buf=100500
         4 >>> s.buf="ADASDFASD"
         5 >>> print(s)
         6 100500 100500 ADASDFASD
         7 >>> del s.buf
         8 >>> print(s)
         9 100500 100500
        10 100500
        11 >>> s.buf
        12 100500
        13 >>> s.buf
        14 Traceback (most recent call last):
        15   File "<stdin>", line 1, in <module>
        16   File "/home/george/src/Пересдача/Stack.py", line 25, in 
        17 
        18 NotImplementedError: Stack is emplty
        19 >>> del(s.buf)
        20 >>> print(s)
        21 
        22 >>>
        23 
      

Форматы данных

Скачать двоичный файл в соответствующем формате и написать программу, которая показывает текст на русском языке в кодировке ru_RU.UTF-8, хранящийся в этом файле.

  1. Файл: base64.dat, модуль

  2. Файл: bz2.dat, модуль

  3. Файл: gzip.dat, модуль

  4. Файл: lzma.dat, модуль

  5. Файл: pickle.dat, модуль

  6. Файл: zlib.dat, модуль

Тест

LecturesCMC/PythonIntro2020/Пересдача (last edited 2021-04-21 09:22:22 by FrBrGeorge)