Домашняя работа по курсу

Как сдавать домашнюю работу

  1. TODO скопировать сюда скриншотики

  2. Зарегистрироваться на факультетском Ejudge

    • По этой же ссылке заполнить графу «Имя» (там должны быть имя и группа, кому оценку ставить)
    • <!> ВНИМАНИЕ! Зарегистрированные пользователи заходят тут

  3. Выбрать 131-й «турнир» (UNИX Python 2019)
    • Возможно, придётся пойти по ссылке «Confirm registration» («Подтвердить регистрацию»)
    • Возможно, придётся пойти по ссылке «Participate» («Участвовать»)
  4. Выбрать соответствующую задачку
  5. Загрузить решение
    • Прежде, чем загружать решение, убедитесь, что оно правильное. Не надо вместо этого делать много различных вариантов решения в надежде, что какой-то один всё-таки пройдёт тесты.
    • Если возникают вопросы — спрашивайте, для этого есть и интерфейс eJudge, и почта/ВК/телеграф/телефон (FrBrGeorge)

  6. Дождаться конца проверки (как правило, несколько секунд) и обновить страницу браузера

Как оформлять решение

Задача типа «написать программу»

По умолчанию, т. е. если иное не указано отдельно:

⇒ Для ввода можно пользоваться input() (чаще даже eval(input())) без строки-подсказки, а для вывода — print(). Ещё раз: никаких переговоров с роботом — только ввод входных данных и вывод выходных, иначе программа не пройдёт тест!

Задача типа «написать функцию»

Задача типа «написать модуль»

Пример задачи: Написать модуль, в котором будет присутствовать целочисленный объект Count, изначально равный 0, и функция incr(level), увеличивающая Count на число level

Модуль-решение:

   1 Count = 0
   2 
   3 def incr(level):
   4     global Count
   5     Count += level

Тест:

   1 print(mod.Count)
   2 mod.incr(100)
   3 print(mod.Count)
   4 # Список неспециальных объектов модуля
   5 print(*sorted(s for s in dir(mod) if not s.startswith("_")))

Вывод:

0
100
Count incr

Тестирующая программа

Сводный список домашних заданий

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

  2. Добыть на рабочем компьютере
    • Python3
    • Редактор, в котором можно писать программы
    • Написать и запустить программу из файла, в котором написано:
         1   print("QQ")
      
  3. Зарегистрироваться в EJudge (131 контест)

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

  2. EJudge: IntPalindrome 'Число-палиндром'

    Ввести целое положительное число и проверить, является ли оно палиндромом, т. е. совпадает ли первая цифра с последней, вторая — с предпоследней и т. д. Представлять число в виде последовательности (строки, списка и т. п.) нельзя. Вывести YES или NO соответственно. Лидирующие нули не учитывать (числа, заканчивающиеся на 0 — автоматически не палиндромы).

    Input:

    1234321
    Output:

    YES
  3. EJudge: AnyPower 'Какая-нибудь степень'

    Ввести небольшое натуральное число 2⩽N⩽1000000 и проверить, является ли оно степенью натурального числа (>1). Вывести YES или NO соответственно.

    Input:

    1024
    Output:

    YES
  4. EJudge: BiSection 'Половинное деление'

    Вводится строка — формула некоторой функции от x. В следующей строке вводятся через запятую два числа, A и B, такие что f(x) на [A,B] непрерывна, дифференцируема и имеет ровно один корень, будучи разных знаков на концах отрезка (проверять не надо). Найти и вывести этот корень с точностью 0.000001 (представление может быть любым). При вычислении f(x) (с помощью eval) предполагается, что в текущем пространстве имён присутствуют математические функции.

    Input:

    sin(x+0.00007)
    -1,2
    Output:

    -7.033348083496094e-05
  5. ( <!> если перейти по ссылке «Вращающееся число», вы увидите некоторые подсказки)

    EJudge: SwapFive 'Вращающееся число'

    (Жак Арсак. Программирование игр и головоломок.) Для заданной цифры k найти такое минимальное целое неотрицательное число, оканчивающееся на k, что, умножая его на k, мы получим новое число, полученное из предыдущего вычеркиванием цифры k на конце и приписыванием ее в начале. Строки/кортежи и иные последовательности не использовать.

    Input:

    4
    Output:

    102564
  1. Прочитать и прощёлкать тьюториалпро цикл for)

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

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

    Input:

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

    21
  3. EJudge: PackedQueue 'Чудо-конвейер'

    Ввести последовательность объектов Python (кортежей или целых чисел), и сымитировать работу Чудо-Конвейера. Если объект — кортеж, это означает, что на вход конвейеру подаются поочерёдно все объекты из этого кортежа. Если объект — натуральное число N, это означает, что с выхода конвейера надо снять поочерёдно N объектов, объединить их в кортеж и вывести. Если с конвейера нельзя снять N объектов, или в последовательности нет больше команд, Чудо-Конвейер немедленно останавливается.

    Input:

    ("QWE",1.1,234),2,(None,7),0,2,(7,7,7),2,(12,),(),3,(5,6),3,100500
    Output:

    ('QWE', 1.1)
    ()
    (234, None)
    (7, 7)
    (7, 7, 12)
  4. При подготовке последнего теста использовался графический редактор GIMP и формат XPM :)

    EJudge: FindRect 'Морской бой'

    Ввести несколько строк одинаковой длины, состоящих из символов '#' и '.'. Первый и последний символ каждой строки — '.', а первая и последняя строки состоят целиком из '-'. Известно (проверять не надо), что на получившемся поле изображены только прямоугольники, причём они не соприкасаются даже углами. Вывести количество этих прямоугольников.

    Input:

    ------------
    .###.....#..
    .###.##..#..
    .....##.....
    .....##..#..
    ............
    ............
    .####..####.
    .......####.
    .......####.
    ------------
    Output:

    6
  5. EJudge: SpiralDigits 'Цифры по спирали'

    Ввести целые M и N, вывести последовательность 0 1 2 3 4 5 6 7 8 9 0 1 2 3 … в виде спирально (по часовой стрелке, из верхнего левого угла) заполненной таблицы N×M (N строк, M столбцов). Не забываем про то, что M и N могут быть чётными, нечётными и неизвестно, какое больше.

    Input:

    6,5
    Output:

    0 1 2 3 4 5
    7 8 9 0 1 6
    6 7 8 9 2 7
    5 6 5 4 3 8
    4 3 2 1 0 9
  6. Д/З мне: на следующий раз не забыть про множество
  1. Прочитать в tutorial про функции, множества и различные последовательности

  2. EJudge: AplusB2 'Простая функция'

    Написать функцию (см. правила оформления таких Д/З), которая принимает два параметра, допускающие сложение, а результат сложения — умножение на целое число. Функция должна возвращать удвоенную сумму своих параметров.

    Input:

    print(AplusB2("A","B"))
    Output:

    ABAB
  3. EJudge: MoarTuple 'Подсчёт кратных'

    Написать функцию moar(a, b, n) от трёх параметров — целочисленных последовательностей a и b, и натурального числа n. Функция возвращает True, если в a больше чисел, кратных n, чем в b, и False в противном случае.

    Input:

    print(moar((25,0,-115,976,100500,7),(32,5,78,98,10,9,42),5))
    Output:

    True
  4. EJudge: MaxFun 'Функция побольше'

    Написать функцию maxfun(), которая принимает переменное число параметров — числовуюпоследовательность S, функцию F1 и, возможно, ещё несколько функций F2 … Fn. Возвращает она ту из функций Fi, сумма значений которой на всех элементах S наибольшая. Если таких функций больше одной, возвращается Fi с наибольшим i.

    Input:

    from math import *
    print(maxfun(range(-2,10), sin, cos, exp)(1))
    Output:

    2.718281828459045
  5. EJudge: MumboJumbo 'Мумбо-Юмбо'

    Ввод представляет собой строки из букв латинского алфавита. Это иероглифические письмена на языках двух племён: Mumbo и Jumbo. Чётные строки — предложения одного языка, нечётные — другого (какого — неизвестно). Иероглифы Mumbo и Jumbo частично одинаковые, а частично разные. Предложения на каждом языке в данном корпусе текстов содержат все разрешённые в этом языке иероглифы (т. е. если иероглиф разрешён в языке, он встречается хотя бы в одном предложении на этом языке). Если строка пустая, это признак окончания ввода. Известно, что в уникальном алфавите Mumbo иероглифов больше, чем в уникальном алфавите Jumbo. Определить и вывести, на каком языке написано первое предложение — Mumbo или Jumbo.

    Input:

    wazxwjd
    tvnhuj
    kjdjdsaxz
    kunvhts
    azkxdz
    vunshtk
    zzjdsxa
    nunvhct
    cdzxaa
    vtkuhvhnc
    dazx
    tunncvwh
    dzjasxz
    uunvhts
    dxdwzaxa
    vuhvuntt
    dzxad
    vthnwuh
    Output:

    Jumbo

TODO

  1. Прочитать что Гвидо думает о хвостовых рекурсивных вызовах, про итераторы и генераторы, про yield from и про itertools

  2. (это не рекурсия, а вот итератор применить можно ☺)

    EJudge: UniInterval 'Объединение отрезков'

    Вводится кортеж пар натуральных чисел. Это координаты отрезков на прямой. Рассмотрим объединение этих отрезков и найдём длину этого объединения (т. е. совокупную длину всех «закрашенных» нашими отрезками отрезков на прямой).

    Input:

    (66, 91), (152, 230), (21, 81), (323, 342), (158, 211), (286, 332), (294, 330), (18, 58), (183, 236)
    Output:

    213
  3. EJudge: BinPow 'Бинарное возведение в степень'

    Написать рекурсивную функцию BinPow(), которая принимает три параметра: python3-объект a, натуральное число 0<N<1000000, и некоторую ассоциативную бинарную функциюf(). Функция BinPow() реализует алгоритм бинарного возведения в степень (кроме нулевой степени). Результатом BinPow(a, n, f) будет применение f(x) к a n-1 раз. Более точно, BinPow(a, 1, f) == a, BinPow(a, 2, f) == f(a,a), BinPow(a, 3, f) == f(a,f(a, a)) == f(f(a, a), a) (в силу ассоциативности), … BinPow(a, n, f) == f(f(…f(a, a), …), a).

    Input:

    print(BinPow(2,33,int.__mul__), 2**33)
    print(BinPow("Se", 7, str.__add__))
    Output:

    8589934592 8589934592
    SeSeSeSeSeSeSe
  4. EJudge: IterPi 'Пи /кродёться/'

    Пользуясь формулой Лейбница для вычисления числа Пи:

    • LeibnitzPi.png

    написать бесконечный генератор pigen(), возвращающий последовательно 4, 4-4/3, 4-4/3+4/5, 4-4/3+4/5-4/7…;

    Input:

    P=pigen()
    print(next(P), next(P), next(P), next(P), sep="\n")
    Output:

    4.0
    2.666666666666667
    3.466666666666667
    2.8952380952380956
  5. EJudge: ChainSlice 'Режем лазанью'

    Написать функцию chainslice(begin, end, seq0, seq1, …), которая принимает не менее трёх параметров: два целых числа и не менее одной последовательности. Рассмотрим последовательность seq, образованную всеми элементами seq0, затем — всеми элементами seq1, и т. д. Вернуть эта функция должна итератор, пробегающий элементы последовательности seq с №begin до №end-1 включительно.

    Input:

    print(*(chainslice(17, 33, range(7),  range(8),  range(6),  range(9),  range(5))))
    Output:

    2 3 4 5 0 1 2 3 4 5 6 7 8 0 1 2

Д/З мне:

  •  I = iter(Seq)
     old = next(I)
     for new in I:
      ...

вместо

  •    1  old = Seq[0]
       2  for new in Seq[1:]:
       3   ...
    
  1. Прочитать и прощёлкать про строки в учебнике, в документации, а также про форматирование строк в учебнике и в документации.

  2. EJudge: TrimImage 'Обрезать картинку'

    Вводятся строки, содержащие четыре целых числа и символ, разделённые пробелами. Код символа 32 < c < 128. Это абсцисса, ордината (ось ординат направлена вниз) некоторых точек, а также длина и ширина построенных на них прямоугольников, «нарисованных» с помощью указанных символов. Последняя строка начинается на четыре нуля (никаких трюков с -0 на этот раз ☺). Вывести наименьшую область, содержащюю все раскрашенные точки, нарисованные в порядке ввода прямоугольников. Область также прямоугольна и изначально заполнена символами '.'. Координаты и размеры могут быть отрицательны (в этом случае прямогуольник откладывается от исходной точки в противоположную сторону, а сама точка в него не попадает) или равны нулю.

    Input:

    1 2 10 10 *
    -2 -1 10 10 #
    3 4 -10 10 @
    5 6 10 -10 %
    0 0 0 0 0
    Output:

    ............%%%%%%%%%%
    ............%%%%%%%%%%
    ............%%%%%%%%%%
    .....#######%%%%%%%%%%
    .....#######%%%%%%%%%%
    .....#######%%%%%%%%%%
    .....#######%%%%%%%%%%
    .....#######%%%%%%%%%%
    @@@@@@@@@@##%%%%%%%%%%
    @@@@@@@@@@##%%%%%%%%%%
    @@@@@@@@@@#####***....
    @@@@@@@@@@#####***....
    @@@@@@@@@@#####***....
    @@@@@@@@@@********....
    @@@@@@@@@@********....
    @@@@@@@@@@********....
    @@@@@@@@@@............
    @@@@@@@@@@............
  3. EJudge: MultTable 'Таблица умножения'

    Ввести два натуральных числа через запятую: N и M. Вывести таблицу умножения от 1 до N включительно в формате, представленном ниже. Количество столбцов в выводе должно быть наибольшим, но общая ширина строки не должна превышать M (предполагается, что M достаточно велико, чтобы вместить один столбец). Ширина колонок под сомножители и произведения должна соответствовать максимальной ширине соответствующего значения (даже если в данной колонке данного столбца эта ширина не достигается, см. пример). Таким образом все столбцы должны быть одинаковой ширины, без учёта пробелов в конце строк, которых быть не должно. Разделители вида "===…===" должны быть ширины M.

    Input:

    11, 62
    Output:

    ==============================================================
     1 * 1  = 1   |  2 * 1  = 2   |  3 * 1  = 3   |  4 * 1  = 4  
     1 * 2  = 2   |  2 * 2  = 4   |  3 * 2  = 6   |  4 * 2  = 8  
     1 * 3  = 3   |  2 * 3  = 6   |  3 * 3  = 9   |  4 * 3  = 12 
     1 * 4  = 4   |  2 * 4  = 8   |  3 * 4  = 12  |  4 * 4  = 16 
     1 * 5  = 5   |  2 * 5  = 10  |  3 * 5  = 15  |  4 * 5  = 20 
     1 * 6  = 6   |  2 * 6  = 12  |  3 * 6  = 18  |  4 * 6  = 24 
     1 * 7  = 7   |  2 * 7  = 14  |  3 * 7  = 21  |  4 * 7  = 28 
     1 * 8  = 8   |  2 * 8  = 16  |  3 * 8  = 24  |  4 * 8  = 32 
     1 * 9  = 9   |  2 * 9  = 18  |  3 * 9  = 27  |  4 * 9  = 36 
     1 * 10 = 10  |  2 * 10 = 20  |  3 * 10 = 30  |  4 * 10 = 40 
     1 * 11 = 11  |  2 * 11 = 22  |  3 * 11 = 33  |  4 * 11 = 44 
    ==============================================================
     5 * 1  = 5   |  6 * 1  = 6   |  7 * 1  = 7   |  8 * 1  = 8  
     5 * 2  = 10  |  6 * 2  = 12  |  7 * 2  = 14  |  8 * 2  = 16 
     5 * 3  = 15  |  6 * 3  = 18  |  7 * 3  = 21  |  8 * 3  = 24 
     5 * 4  = 20  |  6 * 4  = 24  |  7 * 4  = 28  |  8 * 4  = 32 
     5 * 5  = 25  |  6 * 5  = 30  |  7 * 5  = 35  |  8 * 5  = 40 
     5 * 6  = 30  |  6 * 6  = 36  |  7 * 6  = 42  |  8 * 6  = 48 
     5 * 7  = 35  |  6 * 7  = 42  |  7 * 7  = 49  |  8 * 7  = 56 
     5 * 8  = 40  |  6 * 8  = 48  |  7 * 8  = 56  |  8 * 8  = 64 
     5 * 9  = 45  |  6 * 9  = 54  |  7 * 9  = 63  |  8 * 9  = 72 
     5 * 10 = 50  |  6 * 10 = 60  |  7 * 10 = 70  |  8 * 10 = 80 
     5 * 11 = 55  |  6 * 11 = 66  |  7 * 11 = 77  |  8 * 11 = 88 
    ==============================================================
     9 * 1  = 9   | 10 * 1  = 10  | 11 * 1  = 11 
     9 * 2  = 18  | 10 * 2  = 20  | 11 * 2  = 22 
     9 * 3  = 27  | 10 * 3  = 30  | 11 * 3  = 33 
     9 * 4  = 36  | 10 * 4  = 40  | 11 * 4  = 44 
     9 * 5  = 45  | 10 * 5  = 50  | 11 * 5  = 55 
     9 * 6  = 54  | 10 * 6  = 60  | 11 * 6  = 66 
     9 * 7  = 63  | 10 * 7  = 70  | 11 * 7  = 77 
     9 * 8  = 72  | 10 * 8  = 80  | 11 * 8  = 88 
     9 * 9  = 81  | 10 * 9  = 90  | 11 * 9  = 99 
     9 * 10 = 90  | 10 * 10 = 100 | 11 * 10 = 110
     9 * 11 = 99  | 10 * 11 = 110 | 11 * 11 = 121
    ==============================================================
  4. EJudge: PatternFind 'Простой шаблон'

    Ввести строку, содержащую произвольные символы (кроме символа «@»). Затем ввести строку-шаблон, которая может содержать символы '@'. Проверить, содержится ли в исходной строке подстрока, совпадающая со строкой-шаблоном везде, кроме символов '@'; на месте '@' в исходной строке должен стоять ровно один произвольный символ. Вывести наименьшую позицию в строке, с которой начинается эта подстрока, или '-1', если её там нет. Использовать регулярные выражения нельзя! ☺

    Input:

    lorem ipsum, quia dolor sit, amet, consectetur
    dolor @it,@@met
    Output:

    18
  1. Прочитать про словари в учебнике и в документации

  2. EJudge: DungeonMap 'Карта подземелья'

    Вводится карта проходимых в обе стороны тоннелей подземлья в виде строк, содержащих разделённые пробелом названия двух пещер, которые соединяет соответствующий тоннель. Две последние строки не содержат пробелов — это название входа в подземелье и название выхода. Вывести "YES", если из входа можно попасть в выход, и "NO" в противном случае. Пары могут повторяться или содержать одинаковые слова.

    Input:

    markers jumping
    jumping guinea
    skiing pre
    markers gauge
    skiing mpeg
    solar jackson
    skiing solar
    guinea gauge
    mpeg honor
    pre honor
    guinea gauge
    pre mpeg
    markers guinea
    markers gauge
    honor mpeg
    markers jumping
    skiing
    jumping
    Output:

    NO
  3. EJudge: FarGalaxy 'В далёкой галактике'

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

    Input:

    35.764 -797.636 -770.320 almost
    88.213 -61.688 778.457 gene
    -322.270 -248.555 -812.730 trend
    721.262 630.355 968.287 dow
    -895.519 -970.173 97.282 non
    -561.036 -350.840 -723.149 disco
    -151.546 -900.962 -658.862 bidder
    -716.197 478.576 -695.843 hawaii
    -744.664 -173.034 -11.211 sad
    -999.968 990.467 650.551 erik
    .
    Output:

    almost erik
  4. EJudge: CheckHash 'Хороший ли хеш'

    Написать функцию checkhash(seq, f, mod), которой на вход подаётся последовательность неравных друг другу (это гарантируется) хешируемых объектов, хеш-функция и число mod. Функция формирует новую редуцированную хеш-функцию r()=f()%mod, и собирает статистику коллизий по каждому значению r() на исходной последовательности. checkhash(seq, f, mod) возвращает кортеж из двух элементов — наибольшее и наименьшее количество произошедших коллизий.

    Input:

    from math import *
    print(checkhash(range(-1000000,1000000,77),hash,128))
    print(checkhash(range(-1000000,1000000,77),lambda x: int(f"{sin(x+1):14.13f}"[-5:]),128))
    Output:

    (204, 202)
    (260, 112)
    • В примере используется питоновская функция hash(), котороая, как мы выяснили, при каджом новом запуске может возвращать иные значения. В тестах её нет.

    • В примере используется формула из лекции. Что-то с ней явно не так!
  1. Прочитать про все эти удивительные вещи по ссылкам и прощёлкать примеры оттуда

TODO

  1. EJudge: SimpleDecorator 'Простой декоратор'

    Написать функцию-декоратор nonify(func), которая заменяет возвращаемое значение функции func на None, если оно было пустое (и не меняет в противном случае).

    Input:

    @nonify
    def aNb(a, n, b):
        return a*n+b
    
    print(aNb(1,2,3), aNb("QWE",0,""))
    Output:

    5 None
  2. EJudge: FixFloat 'Фиксированная точность'

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

    Input:

    @fix(4)
    def aver(*args, sign=1):
        return sum(args)*sign
    
    print(aver(2.45675901, 3.22656321, 3.432654345, 4.075463224, sign=-1))
    Output:

    -13.1916
  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
  4. Исследовательская задача.

    EJudge: StatCounter 'Статистика вызовов'

    Написать, держитесь крепче, генератор-декоратор statcounter(), который конструирует объекты (назовём один из них stat) со следующим поведением. Первый вызов next(stat) (он же stat.send(None)) возвращает словарь, в котором stat будет хранить информацию вида функция: количество вызовов, где функция — это исходный (не обёрнутый) объект-функция (да, так тоже можно!). Все последующие вызовы stat.send(function) оборачивают вызов произвольной функции function увеличением на 1 соответствующего элемента словаря. Глобальными именами пользоваться нельзя. В примере видны уникальные id объектов, в тестах их не будет (я воспользуюсь function.__name__ или просто не буду их учитывать).

    Input:

    stat = statcounter()
    stats = next(stat)
    
    @stat.send
    def f1(a): return a+1
    
    @stat.send
    def f2(a, b): return f1(a)+f1(b)
    
    print(f1(f2(2,3)+f2(5,6)))
    print(stats)
    Output:

    21
    {<function f2 at 0x7fc3151ebb90>: 2, <function f1 at 0x7fc315283e60>: 5}
  1. Прочитать
  2. В задачах типа «написать модуль» требуется написать модуль (с любым именем, в тест он приедет с именем mod).

    EJudge: FakeRnd 'Неслучайные числа'

    Написать модуль, в котором будет две фальшивые функции: randrange() и randint(), которые принимают тек же параметры, что и настоящие. При каждом чётном по порядку вызове функция randint(a, b) возвращает a, при нечётном — b. Функция randrange() может принимать от 1 до 4 параметров. Четвёртый параметр она игнорирует, а начало диапазона a, конец диапазона b и шаг d интерпретирует так. Если при очередном вызове эти величины совпадают с предыдущим вызовом, то randrange() сперва работает как если бы возвращала очередной элемент range(), то есть сначала a, затем a+d и т. д., пока не доберётся до конца диапазона, после чего продолжает с начала диапазона (шаг при этом не сбивается, см. пример). Пустых диапазонов (когда знак шага не соответствует концам диапазона) во входных данных нет. Если же при очередном вызове значения a, b или d оказываются иными, процесс запускается с начала.

    Input:

    print(*(mod.randrange(5) for i in range(6)))
    print(*(mod.randrange(10,15,2) for i in range(7)))
    print(*(mod.randrange(20,36,3,False) for i in range(9)))
    print(*(mod.randint(5,7) for i in range(3)), *(mod.randint(5,17) for i in range(5)))
    Output:

    0 1 2 3 4 0
    10 12 14 11 13 10 12
    20 23 26 29 32 35 22 25 28
    5 7 5 17 5 17 5 17
  3. 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

TODO

  1. EJudge: BitCoding 'Сжатие со словарём'

    Написать модуль, в котором будет 4 функции. Первые две: shex(n), которая переводит число n в 64-ричное представление, и xehs(s), которая переводит строку с 64-ричным числом в число. 64-ричная система счисления пользуется «цифрами» с ASCII-кодом от 32 до 32+63=95 (т. е. от пробела до подчёркивания) включительно. Функция encode(txt) упаковывает строку txt, состоящую из символов диапазона " "…"_" по следующим правилам. Символы, встретившиеся в тексте, упорядочиваются по убыванию частоты их появления в тексте (вторичный ключ — сам символ). Самому частому (и с наибольшим ASCII-кодом, если таковых несколько) ставится в соответствие бит "0", следующему — последовательность битов "10", следующему — "110", и т. д. Биты записываются единой строкой, строка дополняется нулями, если это необходимо, и превращается в 64-ричное число. Функция encode(txt) возвращает кортеж (длина txt, строка упорядоченных символов, закодированная строка). Четвёртая функция, decode(length, chars, code), раскодирует строку code, используя описанное выше сопоставление chars битам, и возвращает раскодированную строку длиной length.

    Input:

    print(xehs("BREAKFAST"))
    print(shex(10844745761445995))
    res = encode("ENGINEERING WITHOUT MANAGEMENT IS ART.")
    print(res)
    txt = decode(*res)
    print(txt)
    Output:

    9792630319357172
    FASTBREAK
    (38, 'NETI GARMWUSOH.', 'GW*_N?>_[M__?_O_;W^_/WU_IO=_][]_;__ ')
    ENGINEERING WITHOUT MANAGEMENT IS ART.
  1. Прочитать про классы в tutorial; про «волшебные методы» например, тут

  2. EJudge: DahDit 'Морзянка'

    Написать класс morse("строка"), экземпляр которого переводит арифметические выражения в морзянку! Параметр «строка» бывает разных видов, более подробно описан в подсказках, желающие могут догадаться о его компонентах по примеру (пример почти полный). «+» — точка, «-» — тире, «~» — промежуток между буквами (бывает только между буквами и только один, проверять не надо).

    Input:

       1 print(-+morse())
       2 print(-++~+-+morse())
       3 print(--+~-~-++~+++-morse())
       4 print(--+~-~-++~+++-morse(".-"))
       5 print(--+~-~-++~+++-morse("..-"))
       6 print(--+~-~-++~+++-morse("..-|"))
       7 print(--+~-~-++~+++-morse("dot DOT dash"))
       8 print(--+~-~-++~+++-morse("ai aui oi "))
       9 print(--+~-~-++~+++-morse("dot dot dash ///")) 
    
    Output:

    dah dit.
    dah di dit, di dah dit.
    dah dah dit, dah, dah di dit, di di di dah.
    --. - -.. ...-
    --. - -.. ...-
    --. - -.. ...-|
    dash dash DOT, dash, dash dot DOT, dot dot dot dash.
    oi oi aui, oi, oi ai aui, ai ai ai oi
    dash dash dot, dash, dash dot dot, dot dot dot dash///
  3. EJudge: CyberSausage 'Киберколбаса'

    Написать класс sausage, имитирующий киберколбасу. Киберколбаса может быть проинициализирована нулём значений (создаётся колбаса по умолчанию), одним (фарш) и двумя (фарш и объём). Длина целого батона киберколбасы 12 символов фарша и 2 оболочки. Колбаса единичного объёма — это один полный батон, более, чем единичного — это несколько батонов (последний, возможно, неполон). Неполный батон заканчивается срезом. Киберколбаса поддерживает операции умножения и деления на целое число, а также сложения и вычитания с другой киберколбасой (фарш результата совпадает с фаршем первого операнда). Если объём киберколбасы нулевой, батон считается пустым.

    Input:

       1 a, b, c = sausage(), sausage("HAM", "5/6"), sausage("SPAM.", 1.25)
       2 print(a, b, c, sep="\n")
       3 print(a+b+c)
       4 print(b*2, 4*c/5, sep="\n")
       5 d, e = b+a/6-5*c/4, a-c
       6 print(d, not d)
       7 print(e, not e)
    
    Output:

    /------------\
    |pork!pork!po|
    |pork!pork!po|
    |pork!pork!po|
    \------------/
    /----------|
    |HAMHAMHAMH|
    |HAMHAMHAMH|
    |HAMHAMHAMH|
    \----------|
    /------------\/---|
    |SPAM.SPAM.SP||SPA|
    |SPAM.SPAM.SP||SPA|
    |SPAM.SPAM.SP||SPA|
    \------------/\---|
    /------------\/------------\/------------\/-|
    |pork!pork!po||pork!pork!po||pork!pork!po||p|
    |pork!pork!po||pork!pork!po||pork!pork!po||p|
    |pork!pork!po||pork!pork!po||pork!pork!po||p|
    \------------/\------------/\------------/\-|
    /------------\/--------|
    |HAMHAMHAMHAM||HAMHAMHA|
    |HAMHAMHAMHAM||HAMHAMHA|
    |HAMHAMHAMHAM||HAMHAMHA|
    \------------/\--------|
    /------------\
    |SPAM.SPAM.SP|
    |SPAM.SPAM.SP|
    |SPAM.SPAM.SP|
    \------------/
    /|
    ||
    ||
    ||
    \| True
    /|
    ||
    ||
    ||
    \| True
  4. EJudge: SelfCount 'Сколько экземпляров'

    Написать класс WeAre, объекты которого содержат поле count, содержащее количество существующих экземпляров этого класса. Игнорировать попытки изменить значение этого поля вручную или удалить его.

    Input:

       1 a = WeAre()
       2 print(a.count)
       3 b, c = WeAre(), WeAre(),
       4 a.count = 100500
       5 print(a.count, b.count, c.count)
       6 del b.count
       7 del b
       8 print(a.count)
    
    Output:

    1
    3 3 3
    2
  1. Почитать ещё о классах и наследовании в учебнике

  2. EJudge: UniSize 'Размер объекта'

    Написать декоратор класса sizer, который добавляет в него поле size, равное длине объекта, если у объекта есть длина, или модулю целочисленного представления объекта в противном случае (предполагается, что ошибок нет). Предоставить пользователю возможность произвольно менять это поле.

    Input:

       1 @sizer
       2 class S(str): pass
       3 
       4 @sizer
       5 class N(float): pass
       6 
       7 s = S("QSXWDC")
       8 n = N(2.718281828459045)
       9 print(s, n)
      10 print(s.size, n.size)
      11 s.size, n.size = "Wait", "what?"
      12 print(s.size, n.size)
    
    Output:

    QSXWDC 2.718281828459045
    6 2
    Wait what?
  3. Исследовательская задача. Результаты моего исследования в комментариях по ссылке (нажать «комментарии»).

    EJudge: DivStr 'Делимая строка'

    Написать класс DivStr(str), полностью (за исключением правых операций со строками и split()/splitlines()) воспроизводящий работу str. Дополнительно класс должен поддерживать операцию деления «/n», где n — натуральное число, которая должна возвращать n-ю часть от начала строки (если не делится, округлённую в меньшую сторону, если n>len(s) — пустую строку). Задача в том, чтобы любое возвращаемое методами значение типа str превращалось в DivStr. Согласно документации, мы не можем подсунуть методы, начинающиеся на «__», прямо в __dict__, или поймать __getattr__-ом, или даже __getattribute__-ом, а должны задать их явно, например, с помощью def. С другой стороны, руками все методы перебивать не хочется. См. далее.

    Input:

    s = DivStr("Qwertupy")
    print(len(s))
    print(s*3/2)
    print((s+"ZZZZZZZZZZ")/2)
    print(s[3:]/2)
    print(s[0].join("12345678")/2) 
    Output:

    8
    QwertupyQwer
    QwertupyZ
    rt
    1Q2Q3Q4
  4. EJudge: LetterAttr 'Буквенное поле'

    Написать класс LetterAttr, в котором будут допустимы поля с любым именем; значение каждого поля по умолчанию будет совпадать с именем поля (строка), а при задании нового строкового значения туда будут попадать только буквы, встречающиеся в имени поля.

    Input:

       1 A = LetterAttr()
       2 print(A.letter)
       3 print(A.digit)
       4 A.letter = "teller"
       5 print(A.letter)
       6 A.letter = "fortune teller"
       7 print(A.letter)
    
    Output:

    letter
    digit
    teller
    rteteller
  1. Прочитать про исключения в учебнике и в справочнике про исключения, try и raise

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

    Написать программу — калькулятор с переменными и обработкой ошибок

    • Команда, начинающаяся на '#' — комментарий
    • Команда вида Переменная=выражение задаёт переменную

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

    • Если команда содержит знак "=", но не является присваиванием, выводится диагностика "invalid assignment" (см. пример)
    • Если слева от "=" находится не идентификатор, выводится диагностика "invalid identifier (см. пример)"
    • В случае любых других ошибок выводится текст ошибки.

    «Выражение» — это произвольное выражение Python3, в котором вдобавок можно использовать уже определённые переменные (и только их). Пробелов в командах нет. Пустая команда или точка означает конец вычислений. Калькулятор вводит и исполняет команды по одной, тут же выводя диагностику, но в тестах это выглядит как ввод последовательности строк и вывод последовательности строк.

    Input:

    42
    100500//33
    "Qq!"*(6-2)
    # Здесь ошибка
    3,,5
    10/(8-8)
    "wer"[2]+"qwe"[1]
    "wer"[7]+"qwe"[9]
    1+(2+(3
    a0=5
    b0=7
    # И здесь ошибка
    12N=12
    # И ещё где-то были
    a0+b0*8
    c=b0//2+a0
    d==100
    c+d
    sorted(dir())
    .
    Output:

    42
    3045
    Qq!Qq!Qq!Qq!
    invalid syntax (<string>, line 1)
    division by zero
    rw
    string index out of range
    unexpected EOF while parsing (<string>, line 1)
    invalid identifier '12N'
    61
    invalid assignment 'd==100'
    name 'd' is not defined
    ['__builtins__', 'a0', 'b0', 'c']

Include: Nothing found for "== Д/З ==$"!

Рекомендации по дальнейшему изучению

Долги: б/м удобное программирование на Python.

  • sys — сам Python

    • .argv (BTW, optparse

    • .path

    • .ps1/.ps2

    • .stdin/.stdout/.stderr

    • .version/.platform./.

  • os — операционая система

    • .environ

    • работа с каталогами/файлами/процессами/... — чем не системное программирование?
    • .path. — с именами файлов

    • .getrandom/.urandom

  • random

    • randrange/randint, random и пр.

    • choice/random.sample("QWRTRUYOIUIOOPDSFGHFDH",3)

    • shuffle

    • seed и пр.

    • среди прочего (3.6+): random.choices("ABC",(1,2,4),k=10)

  • time/datetime

  • UI: tkinter/turtle

  • PYTHONSTARTUP

Короче,

Что пропустили

BTW: https://pypi.org : 210,100 projects

And finally

   1 >> import this
   2 

   1 import antigravity
   2 

LecturesCMC/PythonIntro2019/HomeworkRules (last edited 2019-10-10 10:53:23 by FrBrGeorge)