├── first_module ├── __init__.py ├── 1.5 │ ├── piggybank.py │ └── number_buffer.py ├── 1.6 │ ├── loggable.py │ ├── extended_stack.py │ └── parents.py └── 1.4 │ └── namespace_simulation.py ├── third_module ├── 3.3 │ ├── test.py │ ├── all_websites.py │ └── link_cheker.py ├── 3.4 │ ├── test.py │ └── crimes.py ├── 3.2 │ ├── reg_exp9.py │ ├── reg_exp8.py │ ├── reg_exp6.py │ ├── reg_exp5.py │ ├── reg_exp7.py │ ├── reg_exp4.py │ ├── reg_exp3.py │ ├── reg_exp2.py │ └── reg_exp1.py ├── 3.1 │ ├── string_count.py │ └── string_manipulator.py └── 3.5 │ ├── api_numbers.py │ └── api_arts.py └── second_module ├── 2.2 ├── import_lesson.py ├── import_me.py ├── days_count.py └── decriptor.py ├── 2.4 ├── reverse_file.py └── py_finder.py ├── 2.1 ├── foo.py ├── positive_list.py └── exceptions.py └── 2.3 ├── primes.py └── multifilter.py /first_module/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_module/3.3/test.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /second_module/2.2/import_lesson.py: -------------------------------------------------------------------------------- 1 | import import_me 2 | 3 | import_me.greet(100) 4 | -------------------------------------------------------------------------------- /second_module/2.2/import_me.py: -------------------------------------------------------------------------------- 1 | def greet(n): 2 | for _ in range(n): 3 | print('Hello!') 4 | -------------------------------------------------------------------------------- /third_module/3.4/test.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | st = [str(input()) for i in range(2)] 4 | pattern = f'{st[1]}' 5 | 6 | quantity = 7 | print(re.search(pattern, st[0]).span()[1]) 8 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp9.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. В каждой строке замените все вхождения 3 | нескольких одинаковых букв на одну букву. Буквой считается символ из группы 4 | \w. Sample Input: 5 | 6 | attraction 7 | buzzzz 8 | Sample Output: 9 | 10 | atraction 11 | buz 12 | """ 13 | 14 | import sys 15 | import re 16 | 17 | for line in sys.stdin: 18 | print(re.sub(r"(\w)(\1+)", r"\1", line.strip())) 19 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp8.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. В каждой строке поменяйте местами две 3 | первых буквы в каждом слове, состоящем хотя бы из двух букв. Буквой 4 | считается символ из группы \w. Sample Input: 5 | 6 | this is a text 7 | "this' !is. ?n1ce, 8 | Sample Output: 9 | 10 | htis si a etxt 11 | "htis' !si. ?1nce, 12 | """ 13 | 14 | import re 15 | import sys 16 | 17 | for line in sys.stdin: 18 | print(re.sub(r"\b(\w)(\w)\b", r'\2\1', line.strip())) 19 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp6.py: -------------------------------------------------------------------------------- 1 | """Вам дана последовательность строк. В каждой строке замените все вхождения 2 | подстроки "human" на подстроку "computer" и выведите полученные строки. 3 | 4 | Sample Input: 5 | 6 | I need to understand the human mind 7 | humanity 8 | Sample Output: 9 | 10 | I need to understand the computer mind 11 | computerity 12 | """ 13 | 14 | import sys 15 | import re 16 | 17 | 18 | for line in sys.stdin: 19 | print(re.sub('human', 'computer', line.strip())) 20 | re.fullmatch() 21 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp5.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. Выведите строки, содержащие слово, 3 | состоящее из двух одинаковых частей (тандемный повтор). 4 | 5 | Sample Input: 6 | 7 | blabla is a tandem repetition 8 | 123123 is good too 9 | go go 10 | aaa 11 | Sample Output: 12 | 13 | blabla is a tandem repetition 14 | 123123 is good too 15 | """ 16 | 17 | import sys 18 | import re 19 | 20 | pattern = r'\b(\w+)\1\b' 21 | 22 | for line in sys.stdin: 23 | line = line.rstrip() 24 | if re.search(pattern, line): 25 | print(line) 26 | 27 | 28 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp7.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. В каждой строке замените первое 3 | вхождение слова, состоящего только из латинских букв "a" (регистр не важен), 4 | на слово "argh". 5 | 6 | Примечание: 7 | Обратите внимание на параметр count у функции sub. 8 | Sample Input: 9 | 10 | There’ll be no more "Aaaaaaaaaaaaaaa" 11 | AaAaAaA AaAaAaA 12 | Sample Output: 13 | 14 | There’ll be no more "argh" 15 | argh AaAaAaA 16 | """ 17 | 18 | import sys 19 | import re 20 | 21 | for line in sys.stdin: 22 | print(re.sub(re.compile(r'\b[a|A]+\b'), 'argh', line.rstrip(), count=1)) 23 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp4.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. 3 | Выведите строки, содержащие обратный слеш "\". 4 | Sample Input: 5 | 6 | \w denotes word character 7 | No slashes here 8 | Sample Output: 9 | 10 | \w denotes word character 11 | """ 12 | 13 | import sys 14 | import re 15 | 16 | pattern = r"\\" 17 | 18 | # выводит и работает правильно 19 | for line in sys.stdin: 20 | if re.search(pattern, line.strip()): 21 | print(line.strip()) 22 | 23 | # проходит тесты но непонятно почему ничего не выводит? 24 | print(*[line for line in sys.stdin if re.search(r"\\", line)], sep='') 25 | 26 | -------------------------------------------------------------------------------- /second_module/2.4/reverse_file.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дается текстовый файл, содержащий некоторое количество непустых 3 | строк. На основе него сгенерируйте новый текстовый файл, содержащий те же 4 | строки в обратном порядке. 5 | 6 | Пример входного файла: 7 | ab 8 | c 9 | dde 10 | ff 11 | 12 | Пример выходного файла: 13 | ff 14 | dde 15 | c 16 | ab 17 | """ 18 | 19 | res =[] 20 | with open (r'D:/Download/dataset_24465_4.txt') as fin, \ 21 | open(r'D:/Download/res.txt', 'w') as fout: 22 | for line in fin: 23 | res.append(line.rstrip()) 24 | for i in range(len(res)-1, -1, -1): 25 | fout.write(res[i]+'\n') 26 | 27 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. 3 | Выведите строки, содержащие две буквы "z", между которыми ровно три символа. 4 | Sample Input: 5 | 6 | zabcz 7 | zzz 8 | zzxzz 9 | zz 10 | zxz 11 | zzxzxxz 12 | Sample Output: 13 | 14 | zabcz 15 | zzxzz 16 | """ 17 | 18 | import re 19 | import sys 20 | 21 | # first method 22 | # finding match z***z 23 | 24 | pattern = r'z...z' 25 | for line in sys.stdin: 26 | line = line.rstrip() 27 | if re.search(pattern, line): 28 | print(line) 29 | 30 | # second method 31 | # finding match 'z.{3}z' 32 | re.compile() 33 | print(*filter(re.compile(r'z.{3}z').search, sys.stdin), sep='') -------------------------------------------------------------------------------- /third_module/3.2/reg_exp2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. 3 | Выведите строки, содержащие "cat" в качестве слова. 4 | 5 | Примечание: 6 | Для работы со словами используйте группы символов \b и \B. 7 | Описание этих групп вы можете найти в документации. 8 | Sample Input: 9 | 10 | cat 11 | catapult and cat 12 | catcat 13 | concat 14 | Cat 15 | "cat" 16 | !cat? 17 | Sample Output: 18 | 19 | cat 20 | catapult and cat 21 | "cat" 22 | !cat? 23 | """ 24 | 25 | import sys 26 | import re 27 | 28 | pattern = r'\bcat\b' 29 | for line in sys.stdin: 30 | line = line.rstrip() 31 | if re.search(pattern, line): 32 | print(line) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /second_module/2.1/foo.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вашей программе будет доступна функция foo, которая может бросать исключения. 3 | 4 | Вам необходимо написать код, который запускает эту функцию, затем ловит 5 | исключения ArithmeticError, AssertionError, ZeroDivisionError и выводит имя 6 | пойманного исключения. 7 | 8 | Пример решения, которое вы должны отправить на проверку. 9 | 10 | try: 11 | foo() 12 | except Exception: 13 | print("Exception") 14 | except BaseException: 15 | print("BaseException") 16 | Подсказка: https://docs.python.org/3/library/ 17 | exceptions.html#exception-hierarchy 18 | """ 19 | 20 | try: 21 | foo() 22 | except AssertionError: 23 | print("AssertionError") 24 | except ZeroDivisionError: 25 | print("ZeroDivisionError") 26 | except ArithmeticError: 27 | print("ArithmeticError") 28 | -------------------------------------------------------------------------------- /third_module/3.2/reg_exp1.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана последовательность строк. 3 | Выведите строки, содержащие "cat" в качестве подстроки хотя бы два раза. 4 | 5 | Примечание: Считать все строки по одной из стандартного потока ввода вы 6 | можете, например, так 7 | 8 | import sys 9 | 10 | for line in sys.stdin: 11 | line = line.rstrip() 12 | # process line 13 | 14 | Sample Input: 15 | 16 | catcat 17 | cat and cat 18 | catac 19 | cat 20 | ccaatt 21 | Sample Output: 22 | 23 | catcat 24 | cat and cat 25 | """ 26 | 27 | import sys 28 | import re 29 | 30 | match = r'cat' 31 | pattern = r'(cat.*){2,}' 32 | 33 | for line in sys.stdin: 34 | 35 | line = line.rstrip() 36 | if len(re.findall(match, line)) > 1: 37 | print(line) 38 | 39 | # second method using match 40 | if re.search(pattern, line) is not None: 41 | print('second method ', line) 42 | -------------------------------------------------------------------------------- /third_module/3.1/string_count.py: -------------------------------------------------------------------------------- 1 | """Вашей программе на вход подаются две строки s и t, состоящие из строчных 2 | латинских букв. 3 | 4 | Выведите одно число – количество вхождений строки t в строку s. 5 | 6 | Пример: 7 | s = "abababa" 8 | t = "aba" 9 | 10 | Вхождения строки t в строку s: 11 | abababa 12 | abababa 13 | abababa 14 | 15 | Sample Input 1: 16 | 17 | abababa 18 | aba 19 | Sample Output 1: 20 | 21 | 3 22 | Sample Input 2: 23 | 24 | abababa 25 | abc 26 | Sample Output 2: 27 | 28 | 0 29 | Sample Input 3: 30 | 31 | abc 32 | abc 33 | Sample Output 3: 34 | 35 | 1 36 | Sample Input 4: 37 | 38 | aaaaa 39 | a 40 | Sample Output 4: 41 | 42 | 5 43 | """ 44 | 45 | a, b = [str(input()) for _ in range(2)] 46 | 47 | count = 0 48 | 49 | while a.find(b) != -1: 50 | count += 1 51 | index = a.find(b) 52 | a = a[index + 1:] 53 | 54 | print(count) 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /third_module/3.4/crimes.py: -------------------------------------------------------------------------------- 1 | """Вам дана частичная выборка из датасета зафиксированных преступлений, 2 | совершенных в городе Чикаго с 2001 года по настоящее время. 3 | 4 | Одним из атрибутов преступления является его тип – Primary Type. 5 | 6 | Вам необходимо узнать тип преступления, которое было зафиксировано 7 | максимальное число раз в 2015 году. 8 | 9 | Файл с данными: 10 | Crimes.csv 11 | """ 12 | 13 | import csv 14 | import re 15 | 16 | res = {} 17 | pattern = r'\w+/\w+/2015' 18 | with open(r'D:/Download/Crimes.csv', 'r') as file: 19 | reader = csv.reader(file) 20 | 21 | for line in reader: 22 | if re.match(pattern, line[2].split()[0]) is not None: 23 | res[line[5]] = 1 24 | 25 | with open(r'D:/Download/Crimes.csv', 'r') as file: 26 | reader = csv.reader(file) 27 | 28 | for line in reader: 29 | if re.match(pattern, line[2].split()[0]) is not None: 30 | res[line[5]] += 1 31 | 32 | print(res) 33 | -------------------------------------------------------------------------------- /first_module/1.5/piggybank.py: -------------------------------------------------------------------------------- 1 | """ 2 | Реализуйте класс MoneyBox, для работы с виртуальной копилкой. 3 | 4 | Каждая копилка имеет ограниченную вместимость, которая выражается целым 5 | числом – количеством монет, которые можно положить в копилку. 6 | Класс должен поддерживать информацию о количестве монет в копилке, 7 | предоставлять возможность добавлять монеты в копилку и узнавать, 8 | можно ли добавить в копилку ещё какое-то количество монет, 9 | не превышая ее вместимость. 10 | 11 | Класс должен иметь следующий вид 12 | """ 13 | 14 | 15 | class MoneyBox: 16 | 17 | def __init__(self, capacity): 18 | self.capacity = capacity 19 | self.count = 0 20 | 21 | def can_add(self, v): 22 | # True, если можно добавить v монет, False иначе 23 | if self.count + v <= self.capacity: 24 | return True 25 | else: 26 | return False 27 | 28 | def add(self, v): 29 | # положить v монет в копилку 30 | self.count += v 31 | -------------------------------------------------------------------------------- /second_module/2.4/py_finder.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дана в архиве ссылка) файловая структура, состоящая из директорий и 3 | файлов. 4 | 5 | Вам необходимо распаковать этот архив, и затем найти в данной в файловой 6 | структуре все директории, в которых есть хотя бы один файл с расширением 7 | ".py". 8 | 9 | Ответом на данную задачу будет являться файл со списком таких директорий, 10 | отсортированных в лексикографическом порядке. 11 | 12 | Для лучшего понимания формата задачи, ознакомьтесь с примером. 13 | Пример архива 14 | Пример ответа 15 | """ 16 | 17 | import os 18 | 19 | 20 | def find_py(directory="D:\\main"): 21 | res = [] 22 | 23 | for current_dir, dir, files in os.walk(directory): 24 | for file in files: 25 | if '.py' in file: 26 | res.append(current_dir.replace("D:\\", "")) 27 | break 28 | 29 | with open('D:/res.txt', 'w') as f: 30 | for each in res: 31 | f.write(each + '\n') 32 | 33 | 34 | print(find_py()) 35 | -------------------------------------------------------------------------------- /second_module/2.2/days_count.py: -------------------------------------------------------------------------------- 1 | """ 2 | В первой строке дано три числа, соответствующие некоторой дате date -- год, 3 | месяц и день. 4 | Во второй строке дано одно число days -- число дней. 5 | 6 | Вычислите и выведите год, месяц и день даты, которая наступит, когда с 7 | момента исходной даты date пройдет число дней, равное days. 8 | 9 | Примечание: Для решения этой задачи используйте стандартный модуль datetime. 10 | Вам будут полезны класс datetime.date для хранения даты и класс 11 | datetime.timedelta для прибавления дней к дате. 12 | 13 | Sample Input 1: 14 | 15 | 2016 4 20 16 | 14 17 | Sample Output 1: 18 | 19 | 2016 5 4 20 | Sample Input 2: 21 | 22 | 2016 2 20 23 | 9 24 | Sample Output 2: 25 | 26 | 2016 2 29 27 | Sample Input 3: 28 | 29 | 2015 12 31 30 | 1 31 | Sample Output 3: 32 | 33 | 2016 1 1 34 | """ 35 | 36 | 37 | import datetime 38 | 39 | year, month, day = input().split() 40 | 41 | start = datetime.date(int(year), int(month), int(day)) 42 | end = start + datetime.timedelta(days=int(input())) 43 | 44 | print(end.year, end.month, end.day) 45 | 46 | 47 | -------------------------------------------------------------------------------- /second_module/2.1/positive_list.py: -------------------------------------------------------------------------------- 1 | """Реализуйте класс PositiveList, отнаследовав его от класса list, 2 | для хранения положительных целых чисел. Также реализуйте новое исключение 3 | NonPositiveError. 4 | 5 | В классе PositiveList переопределите метод append(self, x) таким образом, 6 | чтобы при попытке добавить неположительное целое число бросалось исключение 7 | NonPositiveError и число не добавлялось, а при попытке добавить 8 | положительное целое число, число добавлялось бы как в стандартный list. 9 | 10 | В данной задаче гарантируется, что в качестве аргумента x метода append 11 | всегда будет передаваться целое число. 12 | 13 | Примечание: 14 | Положительными считаются числа, строго большие нуля. 15 | """ 16 | 17 | 18 | class NonPositiveError(Exception): 19 | pass 20 | 21 | 22 | class PositiveList(list): 23 | 24 | def append(self, item): 25 | 26 | if item > 0: 27 | return super(PositiveList, self).append(item) 28 | else: 29 | raise NonPositiveError 30 | 31 | 32 | s = PositiveList() 33 | s.append(1) 34 | s.append(0) 35 | s.append(1) 36 | 37 | print(s) 38 | -------------------------------------------------------------------------------- /second_module/2.3/primes.py: -------------------------------------------------------------------------------- 1 | """Целое положительное число называется простым, если оно имеет ровно два 2 | различных делителя, то есть делится только на единицу и на само себя. 3 | Например, число 2 является простым, так как делится только на 1 и 2. Также 4 | простыми являются, например, числа 3, 5, 31, и еще бесконечно много чисел. 5 | Число 4, например, не является простым, так как имеет три делителя – 1, 2, 6 | 4. Также простым не является число 1, так как оно имеет ровно один делитель 7 | – 1. 8 | 9 | Реализуйте функцию-генератор primes, которая будет генерировать простые 10 | числа в порядке возрастания, начиная с числа 2. 11 | 12 | Пример использования: 13 | 14 | print(list(itertools.takewhile(lambda x : x <= 31, primes()))) 15 | # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31] 16 | """ 17 | 18 | 19 | def is_prime(x): 20 | for i in range(2, int(x ** 0.5) + 1): 21 | if x % i == 0: 22 | return False 23 | return True 24 | 25 | 26 | def primes(): 27 | num = 2 28 | while True: 29 | if is_prime(num): 30 | yield num 31 | num += 1 32 | 33 | 34 | p = primes() 35 | for i in range(32): 36 | print(next(p)) 37 | -------------------------------------------------------------------------------- /third_module/3.5/api_numbers.py: -------------------------------------------------------------------------------- 1 | """ 2 | В этой задаче вам необходимо воспользоваться API сайта numbersapi.com 3 | 4 | Вам дается набор чисел. Для каждого из чисел необходимо узнать, существует 5 | ли интересный математический факт об этом числе. 6 | 7 | Для каждого числа выведите Interesting, если для числа существует интересный 8 | факт, и Boring иначе. Выводите информацию об интересности чисел в таком же 9 | порядке, в каком следуют числа во входном файле. 10 | 11 | Пример запроса к интересному числу: 12 | http://numbersapi.com/31/math?json=true 13 | 14 | Пример запроса к скучному числу: 15 | http://numbersapi.com/999/math?json=true 16 | 17 | Пример входного файла: 18 | 31 19 | 999 20 | 1024 21 | 502 22 | 23 | Пример выходного файла: 24 | Interesting 25 | Boring 26 | Interesting 27 | Boring 28 | """ 29 | 30 | import requests as re 31 | import json as js 32 | 33 | nums = [] 34 | 35 | with open(r'D:/Download/dataset_24476_3.txt', 'r') as file: 36 | for line in file: 37 | nums.append(line.strip()) 38 | 39 | for n in nums: 40 | response = re.get(f'http://numbersapi.com/{n}/math?json=true') 41 | result = js.loads(response.content) 42 | 43 | if result['found']: 44 | print('Interesting') 45 | else: 46 | print('Boring') 47 | -------------------------------------------------------------------------------- /first_module/1.6/loggable.py: -------------------------------------------------------------------------------- 1 | """ 2 | Одно из применений множественного наследование – расширение функциональности 3 | класса каким-то заранее определенным способом. Например, если нам понадобится 4 | логировать какую-то информацию при обращении к методам класса. 5 | 6 | Рассмотрим класс Loggable: 7 | 8 | import time 9 | 10 | class Loggable: 11 | def log(self, msg): 12 | print(str(time.ctime()) + ": " + str(msg)) 13 | 14 | У него есть ровно один метод log, который позволяет выводить в лог (в данном 15 | случае в stdout) какое-то сообщение, добавляя при этом текущее время. 16 | Реализуйте класс LoggableList, отнаследовав его от классов list и Loggable 17 | таким образом, чтобы при добавлении элемента в список посредством метода 18 | append в лог отправлялось сообщение, состоящее из только что добавленного 19 | элемента. 20 | 21 | Примечание 22 | Ваша программа не должна содержать класс Loggable. При проверке вашей программе 23 | будет доступен этот класс, и он будет содержать метод log, описанный выше. 24 | """ 25 | 26 | import time 27 | 28 | 29 | class Loggable: 30 | def log(self, msg): 31 | print(str(time.ctime()) + ": " + str(msg)) 32 | 33 | 34 | class LoggableList(list, Loggable): 35 | def append(self, message): 36 | 37 | self.log(message) 38 | return super(LoggableList, self).append(message) 39 | -------------------------------------------------------------------------------- /third_module/3.3/all_websites.py: -------------------------------------------------------------------------------- 1 | """Вашей программе на вход подается ссылка на HTML файл. Вам необходимо 2 | скачать этот файл, затем найти в нем все ссылки вида 3 | и вывести список сайтов, на которые есть ссылка. 4 | 5 | Сайтом в данной задаче будем называть имя домена вместе с именами 6 | поддоменов. То есть, это последовательность символов, которая следует сразу 7 | после символов протокола, если он есть, до символов порта или пути, если они 8 | есть, за исключением случаев с относительными ссылками вида . 10 | 11 | Сайты следует выводить в алфавитном порядке. 12 | 13 | Пример HTML файла: 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Пример ответа: 24 | 25 | mail.ru 26 | neerc.ifmo.ru 27 | stepic.org 28 | www.ya.ru 29 | ya.ru 30 | """ 31 | 32 | 33 | import requests 34 | import re 35 | from urllib.parse import urlparse 36 | 37 | pattern = r']*?href="(.*?)"[^>]*?>' 38 | 39 | link = str(input()) 40 | links = (re.findall(pattern, requests.get(link).text)) 41 | 42 | res = [] 43 | 44 | for each in links: 45 | tmp = urlparse(each).netloc 46 | if tmp != 'biztorg.ru:80': 47 | res.append(tmp) 48 | 49 | 50 | res = sorted(set(res)) 51 | for i in res: 52 | print(i) -------------------------------------------------------------------------------- /third_module/3.3/link_cheker.py: -------------------------------------------------------------------------------- 1 | """Рассмотрим два HTML-документа A и B. Из A можно перейти в B за один 2 | переход, если в A есть ссылка на B, т. е. внутри A есть тег , 3 | возможно с дополнительными параметрами внутри тега. Из A можно перейти в B 4 | за два перехода если существует такой документ C, что из A в C можно перейти 5 | за один переход и из C в B можно перейти за один переход. 6 | 7 | Вашей программе на вход подаются две строки, содержащие url двух документов 8 | A и B. Выведите Yes, если из A в B можно перейти за два перехода, 9 | иначе выведите No. 10 | 11 | Обратите внимание на то, что не все ссылки внутри HTML документа могут вести 12 | на существующие HTML документы. 13 | 14 | Sample Input 1: 15 | 16 | https://stepic.org/media/attachments/lesson/24472/sample0.html 17 | https://stepic.org/media/attachments/lesson/24472/sample2.html 18 | Sample Output 1: 19 | 20 | Yes 21 | Sample Input 2: 22 | 23 | https://stepic.org/media/attachments/lesson/24472/sample0.html 24 | https://stepic.org/media/attachments/lesson/24472/sample1.html 25 | Sample Output 2: 26 | 27 | No 28 | Sample Input 3: 29 | 30 | https://stepic.org/media/attachments/lesson/24472/sample1.html 31 | https://stepic.org/media/attachments/lesson/24472/sample2.html 32 | Sample Output 3: 33 | 34 | Yes 35 | """ 36 | 37 | import requests 38 | import re 39 | 40 | link1, link2 = [str(input()) for i in range(2)] 41 | 42 | pattern = r']*?href="(.*?)"[^>]*?>' 43 | 44 | 45 | def check(url1, url2): 46 | for each in re.findall(pattern, requests.get(url1).text): 47 | if url2 in re.findall(pattern, requests.get(each).text): 48 | return 'Yes' 49 | 50 | return 'No' 51 | 52 | 53 | print(check(link1, link2)) -------------------------------------------------------------------------------- /third_module/3.1/string_manipulator.py: -------------------------------------------------------------------------------- 1 | """Вашей программе на вход подаются три строки s, a, b, состоящие из 2 | строчных латинских букв. За одну операцию вы можете заменить все вхождения 3 | строки a в строку s на строку b. 4 | 5 | Например, s = "abab", a = "ab", b = "ba", тогда после выполнения одной 6 | операции строка s перейдет в строку "baba", после выполнения двух и операций 7 | – в строку "bbaa", и дальнейшие операции не будут изменять строку s. 8 | 9 | Необходимо узнать, после какого минимального количества операций в строке s 10 | не останется вхождений строки a. Если операций потребуется более 1000, 11 | выведите Impossible. 12 | 13 | Выведите одно число – минимальное число операций, после применения которых в 14 | строке s не останется вхождений строки a, или Impossible, если операций 15 | потребуется более 1000. 16 | 17 | Условие задачи было изменено 12.09.2018 18 | Sample Input 1: 19 | 20 | ababa 21 | a 22 | b 23 | Sample Output 1: 24 | 25 | 1 26 | Sample Input 2: 27 | 28 | ababa 29 | b 30 | a 31 | Sample Output 2: 32 | 33 | 1 34 | Sample Input 3: 35 | 36 | ababa 37 | c 38 | c 39 | Sample Output 3: 40 | 41 | 0 42 | Sample Input 4: 43 | 44 | ababac 45 | c 46 | c 47 | Sample Output 4: 48 | 49 | Impossible 50 | """ 51 | 52 | 53 | def swop(start, a, b): 54 | counter = 0 55 | while counter <= 1000: 56 | if counter == 1000: 57 | print("Impossible") 58 | if start.count(a) >= 1: 59 | start = start.replace(a, b) 60 | counter += 1 61 | if start.count(a) == 0: 62 | print(counter) 63 | break 64 | else: 65 | print('0') 66 | break 67 | 68 | 69 | swop(*[str(input()) for _ in range(3)]) 70 | -------------------------------------------------------------------------------- /first_module/1.5/number_buffer.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дается последовательность целых чисел и вам нужно ее обработать и 3 | вывести на экран сумму первой пятерки чисел из этой последовательности, 4 | затем сумму второй пятерки, и т. д. 5 | 6 | Но последовательность не дается вам сразу целиком. С течением времени 7 | к вам поступают её последовательные части. Например, сначала первые 8 | три элемента, потом следующие шесть, потом следующие два и т. д. 9 | 10 | Реализуйте класс Buffer, который будет накапливать в себе элементы 11 | последовательности и выводить сумму пятерок последовательных элементов 12 | по мере их накопления. 13 | 14 | Одним из требований к классу является то, что он не должен хранить в себе 15 | больше элементов, чем ему действительно необходимо, т. е. он не должен 16 | хранить элементы, которые уже вошли в пятерку, для которой была выведена сумма. 17 | 18 | Класс должен иметь следующий вид: 19 | class Buffer: 20 | def __init__(self): 21 | # конструктор без аргументов 22 | 23 | def add(self, *a): 24 | # добавить следующую часть последовательности 25 | 26 | def get_current_part(self): 27 | # вернуть сохраненные в текущий момент элементы последовательности в 28 | # порядке, в котором они были 29 | # добавлены 30 | """ 31 | 32 | 33 | class Buffer: 34 | def __init__(self): 35 | self.storage = [] 36 | 37 | def add(self, *a): 38 | self.storage += list(a) 39 | 40 | # пока длинна массива > 5, выводим сумму 5к и обрезаем список 41 | while len(self.storage) >= 5: 42 | print(sum(self.storage[:5])) 43 | self.storage = self.storage[5:] 44 | 45 | def get_current_part(self): 46 | return self.storage 47 | 48 | 49 | -------------------------------------------------------------------------------- /second_module/2.2/decriptor.py: -------------------------------------------------------------------------------- 1 | """Алиса владеет интересной информацией, которую хочет заполучить Боб. Алиса 2 | умна, поэтому она хранит свою информацию в зашифрованном файле. У Алисы 3 | плохая память, поэтому она хранит все свои пароли в открытом виде в 4 | текстовом файле. 5 | 6 | Бобу удалось завладеть зашифрованным файлом с интересной информацией и 7 | файлом с паролями, но он не смог понять какой из паролей ему нужен. Помогите 8 | ему решить эту проблему. 9 | 10 | Алиса зашифровала свою информацию с помощью библиотеки simple-crypt. Она 11 | представила информацию в виде строки, и затем записала в бинарный файл 12 | результат работы метода simplecrypt.encrypt. 13 | 14 | Вам необходимо установить библиотеку simple-crypt, и с помощью метода 15 | simplecrypt.decrypt узнать, какой из паролей служит ключом для расшифровки 16 | файла с интересной информацией. 17 | 18 | Ответом для данной задачи служит расшифрованная интересная информация Алисы. 19 | 20 | Файл с информацией 21 | Файл с паролями 22 | 23 | Примечание: Для того, чтобы считать все данные из бинарного файла, 24 | можно использовать, например, следующий код: 25 | 26 | with open("encrypted.bin", "rb") as inp: 27 | encrypted = inp.read() 28 | 29 | Примечание: Работа с файлами рассмотрена в следующем уроке, поэтому вы 30 | можете вернуться к этой задаче после просмотра следующего урока. """ 31 | 32 | from simplecrypt import decrypt as dc 33 | import simplecrypt 34 | 35 | data = [] 36 | password = [] 37 | 38 | with open(r"D:\Download\encrypted.bin", "rb") as inp, \ 39 | open(r'D:\Download\passwords.txt', 'r') as txt: 40 | encrypted = inp.read() 41 | for lines in txt: 42 | password.append(lines.strip()) 43 | 44 | for pwd in password: 45 | try: 46 | print(pwd) 47 | print(dc(pwd, encrypted).decode('utf8')) 48 | except simplecrypt.DecryptionException: 49 | pass 50 | -------------------------------------------------------------------------------- /first_module/1.6/extended_stack.py: -------------------------------------------------------------------------------- 1 | """Реализуйте структуру данных, представляющую собой расширенную структуру 2 | стек. Необходимо поддерживать добавление элемента на вершину стека, удаление 3 | с вершины стека, и необходимо поддерживать операции сложения, вычитания, 4 | умножения и целочисленного деления. 5 | 6 | Операция сложения на стеке определяется следующим образом. Со стека 7 | снимается верхний элемент (top1), затем снимается следующий верхний элемент 8 | (top2), и затем как результат операции сложения на вершину стека кладется 9 | элемент, равный top1 + top2. 10 | 11 | Аналогичным образом определяются операции вычитания (top1 - top2), умножения 12 | (top1 * top2) и целочисленного деления (top1 // top2). 13 | 14 | Реализуйте эту структуру данных как класс ExtendedStack, отнаследовав его от 15 | стандартного класса list. Требуемая структура класса: 16 | 17 | class ExtendedStack(list): 18 | def sum(self): 19 | # операция сложения 20 | 21 | def sub(self): 22 | # операция вычитания 23 | 24 | def mul(self): 25 | # операция умножения 26 | 27 | def div(self): 28 | # операция целочисленного деления 29 | 30 | Примечание Для добавления элемента на стек используется метод append, 31 | а для снятия со стека – метод pop. Гарантируется, что операции будут 32 | совершаться только когда в стеке есть хотя бы два элемента. """ 33 | 34 | 35 | class ExtendedStack(list): 36 | def append(self, item): 37 | return super(ExtendedStack, self).append(item) 38 | 39 | def pop(self): 40 | return super(ExtendedStack, self).pop() 41 | 42 | def sum(self): 43 | self.append(self.pop() + self.pop()) 44 | 45 | def sub(self): 46 | # операция вычитания 47 | self.append(self.pop() - self.pop()) 48 | 49 | def mul(self): 50 | # операция умножения 51 | self.append(self.pop() * self.pop()) 52 | 53 | def div(self): 54 | # операция целочисленного деления 55 | self.append(self.pop() // self.pop()) -------------------------------------------------------------------------------- /first_module/1.6/parents.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дано описание наследования классов в следующем формате. 3 | <имя класса 1> : <имя класса 2> <имя класса 3> ... <имя класса k> 4 | Это означает, что класс 1 отнаследован от класса 2, класса 3, и т. д. 5 | 6 | Или эквивалентно записи: 7 | 8 | class Class1(Class2, Class3 ... ClassK): 9 | pass 10 | Класс A является прямым предком класса B, если B отнаследован от A: 11 | 12 | class B(A): 13 | pass 14 | 15 | Класс A является предком класса B, если 16 | A = B; 17 | A - прямой предок B 18 | существует такой класс C, что C - прямой предок B и A - предок C 19 | 20 | Например: 21 | class B(A): 22 | pass 23 | 24 | class C(B): 25 | pass 26 | 27 | # A -- предок С 28 | 29 | Вам необходимо отвечать на запросы, является ли один класс предком 30 | другого класса 31 | 32 | Важное примечание: Создавать классы не требуется. Мы просим вас 33 | промоделировать этот процесс, и понять существует ли путь от одного класса 34 | до другого. Формат входных данных В первой строке входных данных содержится 35 | целое число n - число классов. 36 | 37 | В следующих n строках содержится описание наследования классов. В i-й строке 38 | указано от каких классов наследуется i-й класс. Обратите внимание, что класс 39 | может ни от кого не наследоваться. Гарантируется, что класс не наследуется 40 | сам от себя (прямо или косвенно), что класс не наследуется явно от одного 41 | класса более одного раза. 42 | 43 | В следующей строке содержится число q - количество запросов. 44 | 45 | В следующих q строках содержится описание запросов в формате <имя класса 1> 46 | <имя класса 2>. Имя класса – строка, состоящая из символов латинского 47 | алфавита, длины не более 50. 48 | 49 | Формат выходных данных Для каждого запроса выведите в отдельной строке слово 50 | "Yes", если класс 1 является предком класса 2, и "No", если не является. """ 51 | 52 | import sys 53 | 54 | 55 | def is_parent(tree, start, end, path=[]): 56 | path = path + [start] 57 | 58 | if start not in tree: 59 | return None 60 | if start == end: 61 | return path 62 | 63 | for cl in tree[start]: 64 | if cl not in path: 65 | newpath = is_parent(tree, cl, end, path) 66 | 67 | if newpath: 68 | return newpath 69 | 70 | return None 71 | 72 | 73 | # read n classes relationship queries from stdin 74 | def read_classes(n): 75 | reader = (tuple(map(str.strip, line.split(':'))) for line in sys.stdin) 76 | classes = {} 77 | 78 | for i in range(n): 79 | key, *val = next(reader) 80 | if len(val) != 0: 81 | val = val.pop().split() 82 | classes[key] = val 83 | 84 | return classes 85 | 86 | 87 | # read q check queries from stdin 88 | def read_queries(q): 89 | reader = [line.split() for line in sys.stdin] 90 | queries = list(reader) 91 | 92 | return queries 93 | 94 | 95 | n = int(input()) 96 | classes = read_classes(n) 97 | q = int(input()) 98 | queries = read_queries(q) 99 | 100 | for query in queries: 101 | base, child = query 102 | if is_parent(classes, child, base): 103 | print("Yes") 104 | else: 105 | print("No") 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /second_module/2.1/exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Вам дано описание наследования классов исключений в следующем формате. 3 | имя исключения 1 : имя исключения 2 имя исключения 3 ... имя исключения k 4 | Это означает, что исключение 1 наследуется от исключения 2, исключения 3, и т.д 5 | 6 | Или эквивалентно записи: 7 | 8 | class Error1(Error2, Error3 ... ErrorK): 9 | pass 10 | Антон написал код, который выглядит следующим образом. 11 | 12 | try: foo() except <имя 1>: print("<имя 1>") except <имя 2>: print("<имя 2>") 13 | ... Костя посмотрел на этот код и указал Антону на то, что некоторые 14 | исключения можно не ловить, так как ранее в коде будет пойман их предок. Но 15 | Антон не помнит какие исключения наследуются от каких. Помогите ему выйти из 16 | неловкого положения и напишите программу, которая будет определять обработку 17 | каких исключений можно удалить из кода. 18 | 19 | Важное примечание: 20 | 21 | В отличие от предыдущей задачи, типы исключений не созданы. 22 | 23 | Создавать классы исключений также не требуется 24 | 25 | Мы просим вас промоделировать этот процесс, и понять какие из исключений 26 | можно и не ловить, потому что мы уже ранее где-то поймали их предка. 27 | 28 | Формат входных данных 29 | 30 | В первой строке входных данных содержится целое число n - число классов 31 | исключений. 32 | 33 | В следующих n строках содержится описание наследования классов. В i-й строке 34 | указано от каких классов наследуется i-й класс. Обратите внимание, что класс 35 | может ни от кого не наследоваться. Гарантируется, что класс не наследуется 36 | сам от себя (прямо или косвенно), что класс не наследуется явно от одного 37 | класса более одного раза. 38 | 39 | В следующей строке содержится число m - количество обрабатываемых 40 | исключений. Следующие m строк содержат имена исключений в том порядке, 41 | в каком они были написаны у Антона в коде. Гарантируется, что никакое 42 | исключение не обрабатывается дважды. 43 | 44 | Формат выходных данных 45 | 46 | Выведите в отдельной строке имя каждого исключения, обработку которого можно 47 | удалить из кода, не изменив при этом поведение программы. Имена следует 48 | выводить в том же порядке, в котором они идут во входных данных. 49 | 50 | Пример теста 1 51 | 52 | Рассмотрим код 53 | 54 | try: foo() except ZeroDivision : print("ZeroDivision") except OSError: 55 | print("OSError") except ArithmeticError: print("ArithmeticError") except 56 | FileNotFoundError: print("FileNotFoundError") ... По условию этого теста, 57 | Костя посмотрел на этот код, и сказал Антону, что исключение 58 | FileNotFoundError можно не ловить, ведь мы уже ловим OSError -- предок 59 | FileNotFoundError 60 | 61 | Sample Input: 62 | 4 63 | ArithmeticError 64 | ZeroDivisionError : ArithmeticError 65 | OSError 66 | FileNotFoundError : OSError 67 | 4 68 | ZeroDivisionError 69 | OSError 70 | ArithmeticError 71 | FileNotFoundError 72 | Sample Output: 73 | FileNotFoundError 74 | """ 75 | 76 | exceptions = {} 77 | throwed_exceptions = [] 78 | 79 | 80 | def found_path(exceptions, start, end, path=[]): 81 | path = path + [start] 82 | if start == end: 83 | return path 84 | if start not in exceptions: 85 | return [] 86 | for node in exceptions[start]: 87 | if node not in path: 88 | new_path = found_path(exceptions, node, end, path) 89 | if new_path: 90 | return new_path 91 | return [] 92 | 93 | 94 | for _ in range(int(input())): 95 | inpt = input().split() 96 | child = inpt[0] 97 | parents = inpt[2:] 98 | exceptions[child] = parents 99 | 100 | 101 | for _ in range(int(input())): 102 | throwing = input() 103 | for throwed_exception in throwed_exceptions: 104 | if len(found_path(exceptions, throwing, throwed_exception)) > 1: 105 | print(throwing) 106 | break 107 | throwed_exceptions.append(throwing) 108 | -------------------------------------------------------------------------------- /third_module/3.5/api_arts.py: -------------------------------------------------------------------------------- 1 | """ 2 | В этой задаче вам необходимо воспользоваться API сайта artsy.net 3 | 4 | API проекта Artsy предоставляет информацию о некоторых деятелях искусства, 5 | их работах, выставках. 6 | 7 | В рамках данной задачи вам понадобятся сведения о деятелях искусства ( 8 | назовем их, условно, художники). 9 | 10 | Вам даны идентификаторы художников в базе Artsy. Для каждого идентификатора 11 | получите информацию о имени художника и годе рождения. Выведите имена 12 | художников в порядке неубывания года рождения. В случае если у художников 13 | одинаковый год рождения, выведите их имена в лексикографическом порядке. 14 | 15 | Работа с API Artsy 16 | 17 | Полностью открытое и свободное API предоставляют совсем немногие проекты. В 18 | большинстве случаев, для получения доступа к API необходимо 19 | зарегистрироваться в проекте, создать свое приложение, и получить уникальный 20 | ключ (или токен), и в дальнейшем все запросы к API осуществляются при помощи 21 | этого ключа. 22 | 23 | Чтобы начать работу с API проекта Artsy, вам необходимо пройти на стартовую 24 | страницу документации к API https://developers.artsy.net/start и выполнить 25 | необходимые шаги, а именно зарегистрироваться, создать приложение, 26 | и получить пару идентификаторов Client Id и Client Secret. Не публикуйте эти 27 | идентификаторы. 28 | 29 | После этого необходимо получить токен доступа к API. На стартовой странице 30 | документации есть примеры того, как можно выполнить запрос и как выглядит 31 | ответ сервера. Мы приведем пример запроса на Python. 32 | 33 | import requests 34 | import json 35 | 36 | client_id = '...' 37 | client_secret = '...' 38 | 39 | # инициируем запрос на получение токена 40 | r = requests.post("https://api.artsy.net/api/tokens/xapp_token", 41 | data={ 42 | "client_id": client_id, 43 | "client_secret": client_secret 44 | }) 45 | 46 | # разбираем ответ сервера 47 | j = json.loads(r.text) 48 | 49 | # достаем токен 50 | token = j["token"] 51 | 52 | Теперь все готово для получения информации о художниках. На стартовой 53 | странице документации есть пример того, как осуществляется запрос и как 54 | выглядит ответ сервера. Пример запроса на Python. # создаем заголовок, 55 | содержащий наш токен headers = {"X-Xapp-Token" : token} # инициируем запрос 56 | с заголовком r = requests.get( 57 | "https://api.artsy.net/api/artists/4d8b92b34eb68a1b2c0003f4", headers=headers) 58 | 59 | # разбираем ответ сервера 60 | j = json.loads(r.text) 61 | 62 | 63 | Примечание: В качестве имени художника используется параметр sortable_name в 64 | кодировке UTF-8. 65 | 66 | Пример входных данных: 67 | 4d8b92b34eb68a1b2c0003f4 68 | 537def3c139b21353f0006a6 69 | 4e2ed576477cc70001006f99 70 | 71 | Пример выходных данных: 72 | Abbott Mary 73 | Warhol Andy 74 | Abbas Hamra 75 | 76 | Примечание для пользователей Windows При открытии файла для записи на 77 | Windows по умолчанию используется кодировка CP1251, в то время как для 78 | записи имен на сайте используется кодировка UTF-8, что может привести к 79 | ошибке при попытке записать в файл имя с необычными символами. Вы можете 80 | использовать print, или аргумент encoding функции open. """ 81 | 82 | 83 | import requests 84 | import json 85 | 86 | client_id = '74b7d5f6aa978a524ef8' 87 | client_secret = '2e5b0c1e3575126884699f96436c3f42' 88 | 89 | # инициируем запрос на получение токена 90 | r = requests.post("https://api.artsy.net/api/tokens/xapp_token", 91 | data={ 92 | "client_id": client_id, 93 | "client_secret": client_secret 94 | }) 95 | 96 | # разбираем ответ сервера 97 | j = json.loads(r.text) 98 | 99 | # достаем токен 100 | token = j["token"] 101 | 102 | # создаем заголовок, содержащий наш токен 103 | headers = {"X-Xapp-Token": token} 104 | 105 | names = [] 106 | with open(r'D:/Download/dataset_24476_4.txt', 'r') as file: 107 | for line in file: 108 | # инициируем запрос с заголовком 109 | r = requests.get( 110 | f"https://api.artsy.net/api/artists/{line.strip()}", 111 | headers=headers) 112 | r.encoding = 'utf-8' 113 | # разбираем ответ сервера 114 | j = json.loads(r.text) 115 | names.append(j['birthday'] + ' ' + j['sortable_name']) 116 | 117 | 118 | for name in sorted(names): 119 | print(name[5:]) -------------------------------------------------------------------------------- /first_module/1.4/namespace_simulation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Реализуйте программу, которая будет эмулировать работу с пространствами имен. 3 | Необходимо реализовать поддержку создания пространств имен и добавление в них 4 | переменных. 5 | В данной задаче у каждого пространства имен есть уникальный текстовый 6 | идентификатор – его имя. 7 | Вашей программе на вход подаются следующие запросы: 8 | create – создать новое пространство имен с именем 9 | внутри пространства 10 | add – добавить в пространство переменную 11 | get – получить имя пространства, из которого будет взята 12 | переменная при запросе из пространства , или None, если 13 | такого пространства не существует 14 | Рассмотрим набор запросов: 15 | add global a 16 | create foo global 17 | add foo b 18 | create bar foo 19 | add bar a 20 | Структура пространств имен описанная данными запросами будет эквивалентна 21 | структуре пространств имен, созданной при выполнении данного кода 22 | a = 0 23 | def foo(): 24 | b = 1 25 | def bar(): 26 | a = 2 27 | В основном теле программы мы объявляем переменную a, тем самым добавляя ее в 28 | пространство global. Далее мы объявляем функцию foo, что влечет за собой 29 | создание локального для нее пространства имен внутри пространства global. 30 | В нашем случае, это описывается командой create foo global. Далее мы объявляем 31 | внутри функции foo функцию bar, тем самым создавая пространство bar 32 | внутри пространства foo, и добавляем в bar переменную a. 33 | Добавим запросы get к нашим запросам 34 | get foo a 35 | get foo c 36 | get bar a 37 | get bar b 38 | Представим как это могло бы выглядеть в коде 39 | a = 0 40 | def foo(): 41 | b = 1 42 | get(a) 43 | get(c) 44 | def bar(): 45 | a = 2 46 | get(a) 47 | get(b) 48 | Результатом запроса get будет имя пространства, из которого будет взята нужная 49 | переменная. 50 | Например, результатом запроса get foo a будет global, потому что в пространстве 51 | foo не объявлена переменная a, но в пространстве global, внутри которого 52 | находится пространство foo, она объявлена. Аналогично, результатом запроса 53 | get bar b будет являться foo,а результатом работы get bar a будет являться bar. 54 | Результатом get foo c будет являться None, потому что ни в пространстве foo, 55 | и в его внешнем пространстве global не была объявлена переменная с. 56 | Более формально, результатом работы get является 57 | , если в пространстве была объявлена переменная 58 | get – результат запроса к пространству, внутри которого было 59 | создано пространство , если переменная не была объявлена 60 | None, если не существует , т. е.  – это global 61 | Формат входных данных 62 | В первой строке дано число n (1 ≤ n ≤ 100) – число запросов. 63 | В каждой из следующих n строк дано по одному запросу. 64 | Запросы выполняются в порядке, в котором они даны во входных данных. 65 | Имена пространства имен и имена переменных представляют из себя строки длины не более 10, состоящие из строчных латинских букв. 66 | Формат выходных данных 67 | Для каждого запроса get выведите в отдельной строке его результат. 68 | """ 69 | 70 | 71 | def create(_name, _arg): 72 | if _arg not in namespace.keys(): 73 | namespace[_arg] = [_name] 74 | 75 | # if parent is present in keys -> add namespace inside parent array 76 | if _arg in namespace.keys(): 77 | namespace[_arg].append(_name) 78 | 79 | # if not present and we need to add another namesp-arg pair: 80 | if _arg in namespace.keys() and _name not in namespace.keys(): 81 | namespace[_name] = [_arg] 82 | 83 | 84 | # add 85 | def add(_name, _arg): 86 | # adding in namespace: 87 | namespace[_name].append(_arg) 88 | 89 | 90 | # get 91 | def get(_name, _arg): 92 | # return None if no parent: 93 | if _name == 'global' and _arg in namespace['global']: 94 | print('global') 95 | elif _name == 'global' and _arg not in namespace['global']: 96 | print(None) 97 | 98 | else: 99 | # if in 100 | if _arg in namespace[_name]: 101 | print(_name) 102 | else: 103 | get(namespace[_name][0], _arg) 104 | 105 | 106 | storage = [] 107 | namespace = {'global': []} 108 | 109 | for commands in range(int(input())): 110 | cmd, name, arg = str(input()).split() 111 | if cmd == 'create': 112 | create(name, arg) 113 | elif cmd == 'add': 114 | add(name, arg) 115 | elif cmd == 'get': 116 | get(name, arg) -------------------------------------------------------------------------------- /second_module/2.3/multifilter.py: -------------------------------------------------------------------------------- 1 | """Одним из самых часто используемых классов в Python является класс filter. 2 | Он принимает в конструкторе два аргумента a и f – последовательность и 3 | функцию, и позволяет проитерироваться только по таким элементам x из 4 | последовательности a, что f(x) равно True. Будем говорить, что в этом случае 5 | функция f допускает элемент x, а элемент x является допущенным. 6 | 7 | В данной задаче мы просим вас реализовать класс multifilter, который будет 8 | выполнять ту же функцию, что и стандартный класс filter, но будет 9 | использовать не одну функцию, а несколько. 10 | 11 | Решение о допуске элемента будет приниматься на основании того, сколько 12 | функций допускают этот элемент, и сколько не допускают. Обозначим эти 13 | количества за pos и neg. 14 | 15 | Введем понятие решающей функции – это функция, которая принимает два 16 | аргумента – количества pos и neg, и возвращает True, если элемент допущен, 17 | и False иначе. 18 | 19 | Рассмотрим процесс допуска подробнее на следующем примере. a = [1, 2, 20 | 3] f2(x) = x % 2 == 0 # возвращает True, если x делится на 2 f3(x) = x % 3 21 | == 0 judge_any(pos, neg) = pos >= 1 # возвращает True, если хотя бы одна 22 | функция допускает элемент 23 | 24 | В этом примере мы хотим отфильтровать последовательность a и оставить только 25 | те элементы, которые делятся на два или на три. 26 | 27 | Функция f2 допускает только элементы, делящиеся на два, а функция f3 28 | допускает только элементы, делящиеся на три. Решающая функция допускает 29 | элемент в случае, если он был допущен хотя бы одной из функций f2 или f3, 30 | то есть элементы, которые делятся на два или на три. 31 | 32 | Возьмем первый элемент x = 1. f2(x) равно False, т. е. функция f2 не 33 | допускает элемент x. f3(x) также равно False, т. е. функция f3 также не 34 | допускает элемент x. В этом случае pos = 0, так как ни одна функция не 35 | допускает x, и соответственно neg = 2. judge_any(0, 2) равно False, значит 36 | мы не допускаем элемент x = 1. 37 | 38 | Возьмем второй элемент x = 2. 39 | f2(x) равно True 40 | f3(x) равно False 41 | pos = 1, neg = 1 42 | judge_any(1, 1) равно True, значит мы допускаем элемент x = 2. 43 | 44 | Аналогично для третьего элемента x = 3. 45 | 46 | Таким образом, получили последовательность допущенных элементов [2, 3]. 47 | 48 | Класс должен обладать следующей структурой: 49 | 50 | class multifilter: def judge_half(pos, neg): 51 | # допускает элемент, если его 52 | # допускает хотя бы половина фукнций (pos >= neg) 53 | 54 | def judge_any(pos, neg): 55 | # допускает элемент, если его допускает хотя бы одна функция (pos >= 1) 56 | 57 | def judge_all(pos, neg): 58 | # допускает элемент, если его допускают все функции (neg == 0) 59 | 60 | def __init__(self, iterable, *funcs, judge=judge_any): 61 | # iterable - исходная последовательность 62 | # funcs - допускающие функции 63 | # judge - решающая функция 64 | 65 | def __iter__(self): 66 | # возвращает итератор по результирующей последовательности 67 | 68 | Пример использования: 69 | 70 | def mul2(x): 71 | return x % 2 == 0 72 | 73 | def mul3(x): 74 | return x % 3 == 0 75 | 76 | def mul5(x): 77 | return x % 5 == 0 78 | 79 | 80 | a = [i for i in range(31)] # [0, 1, 2, ... , 30] 81 | 82 | print(list(multifilter(a, mul2, mul3, mul5))) 83 | # [0, 2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 84 | # 26, 27, 28, 30] 85 | 86 | print(list(multifilter(a, mul2, mul3, mul5, judge=multifilter.judge_half))) 87 | # [0, 6, 10, 12, 15, 18, 20, 24, 30] 88 | 89 | print(list(multifilter(a, mul2, mul3, mul5, judge=multifilter.judge_all))) 90 | """ 91 | 92 | 93 | def mul2(x): 94 | return x % 2 == 0 95 | 96 | 97 | def mul3(x): 98 | return x % 3 == 0 99 | 100 | 101 | def mul5(x): 102 | return x % 5 == 0 103 | 104 | 105 | class multifilter(list): 106 | 107 | def judge_half(pos, neg): 108 | # допускает элемент, если его допускает хотя бы половина фукнций (pos >= neg) 109 | return pos >= neg 110 | 111 | def judge_any(pos, neg): 112 | # допускает элемент, если его допускает хотя бы одна функция (pos >= 1) 113 | return pos >= 1 114 | 115 | def judge_all(pos, neg): 116 | # допускает элемент, если его допускают все функции (neg == 0) 117 | return neg == 0 118 | 119 | def __init__(self, iterable, *funcs, judge=judge_any): 120 | # iterable - исходная последовательность 121 | # funcs - допускающие функции 122 | # judge - решающая функция 123 | self.iterable = iterable 124 | self.judge = judge 125 | self.func = funcs 126 | 127 | def __iter__(self): 128 | # возвращает итератор по результирующей последовательности 129 | for i in self.iterable: 130 | neg = 0 131 | pos = 0 132 | for f in self.func: 133 | if f(i): 134 | pos += 1 135 | else: 136 | neg += 1 137 | 138 | if self.judge(pos, neg): 139 | yield i 140 | 141 | 142 | a = [i for i in range(31)] # [0, 1, 2, ... , 30] 143 | print(list(multifilter(a, mul2, mul3, mul5, judge=multifilter.judge_all))) 144 | # [0, 30] 145 | print(list(multifilter(a, mul2, mul3, mul5, judge=multifilter.judge_half))) 146 | # [0, 6, 10, 12, 15, 18, 20, 24, 30] 147 | print(list(multifilter(a, mul2, mul3, mul5))) 148 | # [0, 2, 3, 4, 5, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30] --------------------------------------------------------------------------------