From c6024e76146a90451de9308f5178903400c25d67 Mon Sep 17 00:00:00 2001 From: european-54 Date: Tue, 20 Apr 2021 00:58:57 +0700 Subject: [PATCH 01/29] lesson_1 --- .../lesson_1/task_1.py" | 80 +++++++++++++++++++ .../lesson_1/task_2.py" | 41 ++++++++++ .../lesson_1/task_3.py" | 66 +++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 "\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_1.py" create mode 100644 "\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_2.py" create mode 100644 "\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_3.py" diff --git "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_1.py" "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_1.py" new file mode 100644 index 00000000..4c3b47c5 --- /dev/null +++ "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_1.py" @@ -0,0 +1,80 @@ +""" +Задание 1. + +Для каждой из трех задач выполнить следующее: + +1) для каждой инструкции рядом в комментарии определите сложность этой инструкции +2) определите сложность алгоритма в целом + +укажите сложность непосредственно в этом файле +точки, где нужно поработать вам, отмечены знаком '!!!' +Не забудтье оценить итоговую сложность каждого из трех алгоритмов. + +Примечание: +Если у вас возникают сложности, постарайтесь подумать как можно решить задачу, +а не писать "мы это не проходили)". +Алгоритмизатор должен развивать мышление, а это прежде всего практика. +А без столкновения со сложностями его не развить. +""" + +import random + + +############################################################################################# +def check_1(lst_obj): + """Функция должна создать множество из списка. + + Алгоритм 3: + Создать множество из списка + + Сложность: !!!. O(n) -- из-за количества элементов массива + """ + lst_to_set = set(lst_obj) # !!! O(n) + return lst_to_set # !!! O(1) + + +############################################################################################# +def check_2(lst_obj): + """Функция должная вернуть True, если все элементы списка различаются. + + Алгоритм 1: + Проходимся по списку и для каждого элемента проверяем, + что такой элемент отстутствует + в оставшихся справа элементах + + Сложность: !!!. O(n) + """ + for j in range(len(lst_obj)): # !!! O(n) + if lst_obj[j] in lst_obj[j+1:]: # !!! O(1) + return False # !!! O(1) + return True # !!! o(1) + + +############################################################################################# +def check_3(lst_obj): + """Функция должная вернуть True, если все элементы списка различаются. + + Алгоритм 2: + Вначале выполним для списка сортировку, далее, сравниваем элементы попарно + Если присутствуют дубли, они будут находиться рядом. + + Сложность: !!! O(n) + """ + lst_copy = list(lst_obj) # !!! O(n) + lst_copy.sort() # !!! O(n) + for i in range(len(lst_obj) - 1): # !!! O(n) + if lst_copy[i] == lst_copy[i+1]: # !!! O(1) + return False # !!! O(1) + return True # !!! O(1) + +############################################################################################# + + +for j in (50, 500, 1000, 5000, 1000): + # Из 100000 чисел возьмем 'j' случайно выбранных + # Всего 10 тыс. чисел + lst = random.sample(range(-100000, 100000), j) + +print(check_1(lst)) +print(check_2(lst)) +print(check_3(lst)) diff --git "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_2.py" "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_2.py" new file mode 100644 index 00000000..35366bf6 --- /dev/null +++ "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_2.py" @@ -0,0 +1,41 @@ +""" +Задание 2. + +Реализуйте два алгоритма. + +Первый, в виде функции, должен обеспечивать поиск минимального значения для списка. +В основе алгоритма должно быть сравнение каждого числа со всеми другими элементами списка. +Сложность такого алгоритма: O(n^2) - квадратичная. + +Второй, в виде функции, должен обеспечивать поиск минимального значения для списка. +Сложность такого алгоритма: O(n) - линейная. + +Не забудьте указать где какая сложность. + +Примечание: +Построить список можно через списковое включение. +Если у вас возникают сложности, постарайтесь подумать как можно решить задачу, +а не писать "мы это не проходили)". +Алгоритмизатор должен развивать мышление, а это прежде всего практика. +А без столкновения со сложностями его не развить. +""" +# Квадратичная сложность +def alg_1 (lst_obj): + + l_list_obj = list(lst_obj) + l_first = l_list_obj[1] + for idx in range(len(l_list_obj)): + for idx1 in idx: + if l_first < l_list_obj[idx]: + l_first = l_list_obj[idx] + return l_first + +# Линейная сложность +def alg_2 (lst_obj): + + l_list_obj = list(lst_obj) + l_first = l_list_obj[1] + for idx in range(len(l_list_obj)): + if l_first < l_list_obj[idx]: + l_first = l_list_obj[idx] + return l_first diff --git "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_3.py" "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_3.py" new file mode 100644 index 00000000..a50ca40f --- /dev/null +++ "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/lesson_1/task_3.py" @@ -0,0 +1,66 @@ +""" +Задание 3. + +Для этой задачи: +1) придумайте 2-3 решения (не менее двух) +2) оцените сложность каждого решения в нотации О-большое +3) сделайте вывод, какое решение эффективнее и почему + +Примечание: +Без выполнения пунктов 2 и 3 задание считается нерешенным. Пункты 2 и 3 можно выполнить +через строки документации в самом коде. +Если у вас возникают сложности, постарайтесь подумать как можно решить задачу, +а не писать "мы это не проходили)". +Алгоритмизатор должен развивать мышление, а это прежде всего практика. +А без столкновения со сложностями его не развить. + +Сама задача: +Имеется хранилище с информацией о компаниях: название и годовая прибыль. +Для реализации хранилища можно применить любой подход, +который вы придумаете, например, реализовать словарь. +Реализуйте поиск трех компаний с наибольшей годовой прибылью. +Выведите результат. +""" +""" + +import operator + +dict1 = {"one": 10000, "two": 30000, "three": 15000, "four": 25000, "five": 20000} +sorted_values = sorted(dict1.values()) # Sort the values +sorted_dict = {} + +for i in sorted_values: + for k in dict1.keys(): + if dict1[k] == i: + sorted_dict[k] = dict1[k] + break +a = sorted_dict +print(sorted(a)) +b = sorted(a, reverse = True) + +print(b) +""" + +""" +import operator + +dict1 = {"one": 10000, "two": 30000, "three": 15000, "four": 25000, "five": 20000} +sorted_tuples = sorted(dict1.items(), key=operator.itemgetter(1)) +print(sorted_tuples) # [(1, 1), (3, 4), (2, 9)] +sorted_dict = {k: v for k, v in sorted_tuples} + +print(sorted_dict) # {1: 1, 3: 4, 2: 9} +a = sorted(dict1, reverse=True) +print(a) # +""" + +D = {"one": 10000, "two": 30000, "three": 15000, "four": 25000, "five": 20000} +my_max_val = 0 +for k,v in D.items(): + if v > my_max_val: + my_max_val=v + my_max_key=k + +print(my_max_key) +# Сложность О(n) +# Задание выполнил насколько смог. Много время потратил. Видимо, для меня пока не под силу решать подобные задачи. From d8bddd5aa08f4110eb08f453556005c95eab976e Mon Sep 17 00:00:00 2001 From: european Date: Sat, 1 May 2021 19:35:55 +0700 Subject: [PATCH 02/29] new --- .../task_1.py" | 45 ++++++------- .../task_2.py" | 27 ++++++-- .../task_3.py" | 63 +++++++++++++++++-- 3 files changed, 99 insertions(+), 36 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 835c283b..84e6e8ff 100644 --- "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -1,15 +1,12 @@ """ Задание 1. - Для каждой из трех задач выполнить следующее: - 1) для каждой инструкции рядом в комментарии определите сложность этой инструкции 2) определите сложность алгоритма в целом - укажите сложность непосредственно в этом файле точки, где нужно поработать вам, отмечены знаком '!!!' - -Примечание: +Не забудтье оценить итоговую сложность каждого из трех алгоритмов. +Примечание Если у вас возникают сложности, постарайтесь подумать как можно решить задачу, а не писать "мы это не проходили)". Алгоритмизатор должен развивать мышление, а это прежде всего практика. @@ -22,49 +19,45 @@ ############################################################################################# def check_1(lst_obj): """Функция должна создать множество из списка. - Алгоритм 3: Создать множество из списка - - Сложность: !!!. + Сложность: !!!. O(n) -- из-за количества элементов массива """ - lst_to_set = set(lst_obj) # !!! - return lst_to_set + lst_to_set = set(lst_obj) # !!! O(n) + return lst_to_set # !!! O(1) ############################################################################################# def check_2(lst_obj): """Функция должная вернуть True, если все элементы списка различаются. - Алгоритм 1: Проходимся по списку и для каждого элемента проверяем, что такой элемент отстутствует в оставшихся справа элементах - - Сложность: !!!. + Сложность: !!!. O(n) """ - for j in range(len(lst_obj)): # !!! - if lst_obj[j] in lst_obj[j+1:]: # !!! - return False # !!! - return True # !!! + for j in range(len(lst_obj)): # !!! O(n) + if lst_obj[j] in lst_obj[j+1:]: # !!! O(n) - срез + in: + # O(n) + O(n) = O(n) + return False # !!! O(1) + return True # !!! o(1) ############################################################################################# def check_3(lst_obj): """Функция должная вернуть True, если все элементы списка различаются. - Алгоритм 2: Вначале выполним для списка сортировку, далее, сравниваем элементы попарно Если присутствуют дубли, они будут находиться рядом. - - Сложность: !!! + Сложность: !!! O(n log n) """ - lst_copy = list(lst_obj) # !!! - lst_copy.sort() # !!! - for i in range(len(lst_obj) - 1): # !!! - if lst_copy[i] == lst_copy[i+1]: # !!! - return False # !!! - return True # !!! + lst_copy = list(lst_obj) # !!! O(n) + lst_copy.sort() # !!! O(n log n) - встроенная + # сортировка (алгоритм Timsort) + for i in range(len(lst_obj) - 1): # !!! O(n) + if lst_copy[i] == lst_copy[i+1]: # !!! O(1) + return False # !!! O(1) + return True # !!! O(1) ############################################################################################# diff --git "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 3a5eabbc..b0b1f6e3 100644 --- "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -1,19 +1,36 @@ """ Задание 2. - Реализуйте два алгоритма. - Первый, в виде функции, должен обеспечивать поиск минимального значения для списка. В основе алгоритма должно быть сравнение каждого числа со всеми другими элементами списка. Сложность такого алгоритма: O(n^2) - квадратичная. - Второй, в виде функции, должен обеспечивать поиск минимального значения для списка. Сложность такого алгоритма: O(n) - линейная. - +Не забудьте указать где какая сложность. Примечание: -Построить список можно через генератор списка. +Построить список можно через списковое включение. Если у вас возникают сложности, постарайтесь подумать как можно решить задачу, а не писать "мы это не проходили)". Алгоритмизатор должен развивать мышление, а это прежде всего практика. А без столкновения со сложностями его не развить. """ +# Квадратичная сложность +def alg_1 (lst_obj): + + l_list_obj = list(lst_obj) + l_first = l_list_obj[1] + for idx in range(len(l_list_obj)): + for idx1 in idx: + if l_first < l_list_obj[idx]: + l_first = l_list_obj[idx] + return l_first + +# Линейная сложность +def alg_2 (lst_obj): + + l_list_obj = list(lst_obj) + l_first = l_list_obj[1] + for idx in range(len(l_list_obj)): + if l_first < l_list_obj[idx]: + l_first = l_list_obj[idx] + return l_first diff --git "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index e52aafcb..2e2104e6 100644 --- "a/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 1. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -1,11 +1,9 @@ """ Задание 3. - Для этой задачи: -1) придумайте 1-3 решения (желательно хотя бы два) +1) придумайте 2-3 решения (не менее двух) 2) оцените сложность каждого решения в нотации О-большое 3) сделайте вывод, какое решение эффективнее и почему - Примечание: Без выполнения пунктов 2 и 3 задание считается нерешенным. Пункты 2 и 3 можно выполнить через строки документации в самом коде. @@ -13,8 +11,6 @@ а не писать "мы это не проходили)". Алгоритмизатор должен развивать мышление, а это прежде всего практика. А без столкновения со сложностями его не развить. - - Сама задача: Имеется хранилище с информацией о компаниях: название и годовая прибыль. Для реализации хранилища можно применить любой подход, @@ -22,3 +18,60 @@ Реализуйте поиск трех компаний с наибольшей годовой прибылью. Выведите результат. """ + +# Линейная сложность — O(n) +# Функция схожа с линейной сложностью, так как идет перебор массива для поиска 3 максимальных значений. Количество шагов = количеству элементов в массиве. +# O(n) - в нотации О-большое +def var_1 (dict_obj): + l_result_dict = {'Первая кампания': 0, 'Вторая кампания': 0, 'Третья кампания': 0} + + for idx in dict_obj: #O(n) + if l_result_dict.get('Первая кампания') == 0 : + l_result_dict.update({'Первая кампания': idx}) + continue + if l_result_dict.get('Вторая кампания') == 0 : + l_result_dict.update({'Вторая кампания': idx}) + continue + if l_result_dict.get('Третья кампания') == 0 : + l_result_dict.update({'Третья кампания': idx}) + continue + + if dict_obj.get(idx) > dict_obj.get(l_result_dict.get('Первая кампания')): + l_result_dict.update({'Третья кампания': l_result_dict.get('Вторая кампания')}) + l_result_dict.update({'Вторая кампания': l_result_dict.get('Первая кампания')}) + l_result_dict.update({'Первая кампания': idx}) + continue + elif dict_obj.get(idx) > dict_obj.get(l_result_dict.get('Вторая кампания')): + l_result_dict.update({'Третья кампания': l_result_dict.get('Вторая кампания')}) + l_result_dict.update({'Вторая кампания': idx}) + continue + elif dict_obj.get(idx) > dict_obj.get(l_result_dict.get('Третья кампания')): + l_result_dict.update({'Третья кампания': idx}) + continue + + return l_result_dict +# Квадратичная сложность — O(n2) +# Функция схожа с Квадратичной сложностью, так как идет цикл в цикле, из-за этого O(n2) +# O(n2) - в нотации О-большое +def var_2 (dict_obj): + l_result_dict = {'Первая кампания': 0, 'Вторая кампания': 0, 'Третья кампания': 0} + + for idx in dict_obj: #Один Цикл + for idx1 in reversed(l_result_dict): #Второй цикл внутри первого + if l_result_dict.get(idx1) == 0: + l_result_dict.update({idx1: dict_obj.get(idx)}) + + if l_result_dict.get(idx1) < dict_obj.get(idx): + continue + else: + l_result_dict.update({idx1: dict_obj.get(idx)}) + + return l_result_dict + +d = {'NKP1': 1000000000, 'NKP2': 2000000, 'NKP3': 123456778, 'NKP4': 6789034546} + +print(var_1(d)) +print(var_2(d)) + +# Как итог, две функции возвращают одинаковое значение кампаний. +# Эффективным решением считаю 2, оно более гибкое, и не настроена на перебор как в первом случае. From 470393777b042d90b46025d89938d459f86a8d20 Mon Sep 17 00:00:00 2001 From: european Date: Sat, 1 May 2021 19:53:40 +0700 Subject: [PATCH 03/29] new --- .../task_1.py" | 131 ++++++++++++++++-- .../task_2.py" | 31 ++++- .../task_3.py" | 47 ++++++- .../task_4.py" | 30 +++- .../task_5.py" | 18 ++- .../task_6.py" | 21 ++- .../task_7.py" | 70 +++++++++- 7 files changed, 319 insertions(+), 29 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index eaea0088..de7ebe66 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -6,18 +6,12 @@ в качестве знака операции. Если пользователь вводит неверный знак (не '0', '+', '-', '*', '/'), то программа должна сообщать ему об ошибке и снова запрашивать знак операции. - Также сообщать пользователю о невозможности деления на ноль, если он ввел 0 в качестве делителя. - Подсказка: Вариант исполнения: -- условие рекурсивного вызова - введена операция +, -, *, / -- условие завершения рекурсии - введена операция 0 - -Решите через рекурсию. Решение через цикл не принимается. -Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 - +- условие рекурсивного вызова - введена операция +, -, *, / - ШАГ РЕКУРСИИ +- условие завершения рекурсии - введена операция 0 - БАЗОВЫЙ СЛУЧАЙ Пример: Введите операцию (+, -, *, / или 0 для выхода): + Введите первое число: 214 @@ -27,4 +21,125 @@ Введите первое число: вп Вы вместо трехзначного числа ввели строку (((. Исправьтесь Введите операцию (+, -, *, / или 0 для выхода): +Решите через рекурсию. Решение через цикл не принимается. +Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 """ + +import operator, math + +# Доступные операторы +# Поддерживаются только односимвольные +OPS = { + '-': operator.sub, + '+': operator.add, + '*': operator.mul, + '/': operator.truediv, +} +# Доступные функции +FUNCS = { + 'sin': math.sin, + 'cos': math.cos, +} + + +def calc(token): + try: + # Парсим одно число + return float(token) + + except ValueError: + begin = token.find('(') + if begin == 0 and token[-1] == ')': + # Парсим просто выражение в скобках + return parse(token[1:-1]) + + elif begin > 0 and token[-1] == ')': + # Парсим функцию + name = token[0:begin] + if name not in FUNCS: + raise ValueError('Unknown function %s' % name) + # TODO: можно парсить много аргументов умно разделяя по запятой + arg0 = parse(token[begin+1:-1]) + result = FUNCS[name](arg0) + # print('%s = %s' % (token, result)) + return result + + else: + # Неизвестный токен + # TODO: можно встроить константы/переменные + raise ValueError('Unknown token %s' % repr(token)) + + +def parse(txt): + # Рассчитывает выражение и возвращает числовой результат + # TODO: нет приоритета операторов + # Текущий токен + token = '' + # Уровень вложенности + # Вложненые выражения рассчитываются рекурсивно + depth = 0 + # Текущий оператор + op = None + # Итоговое значение + current_value = None + + def close_token(): + # Эта функция закрывает текущий токен + # и сразу производит вычисления + nonlocal token, op, current_value + if token != '': + if current_value is None: + # Первый токен, его просто сохраняем + current_value = calc(token) + else: + # Применяем оператор + current_value = OPS[op](current_value, calc(token)) + # Обнуляем оператор + op = None + print(op, token, current_value) + token = '' + if len(txt) == 1 and txt == '0': + close_token() + return current_value + + # Обрабатываем выражение посимвольно + for c in txt: + if depth > 0: + # Если внутри скобок + if c == ' ': + # Пробелы не нужны + continue + token += c + if c == ')': + # Возвращаемся на уровень выше + depth -= 1 + close_token() + + elif c == '(': + # Удём внутрь скобок + if token == '': + # Это для фунций – имя функции и скобки + # должны идти единым токеном + close_token() + depth += 1 + token += c + + else: + # Парсим токен + if c == ' ': + # Пробелы не нужны + continue + elif c in OPS: + # Если встретился оператор + close_token() + op = c + else: + token += c + + close_token() + return current_value + +result = parse('7 - sin(3.141592 * 0.75) + cos(2.718281)') +# Можете сравнить с корректным результатом, всё 1-в-1: +# result = 7 - math.sin(3.141592 * 0.75) + math.cos(2.718281) +print('Result:', result) diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index c0840774..677b6991 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -2,17 +2,38 @@ 2. Посчитать четные и нечетные цифры введенного натурального числа. Например, если введено число 34560, то у него 3 четные цифры (4, 6 и 0) и 2 нечетные (3 и 5). - Подсказка: На каждом шаге вам нужно 'доставать' из числа очередную цифру и смотреть является ли она четной или нечетной. При этом увеличиваем соответствующий счетчик Пока все числа не извлечены рекурсивные вызовы продолжаем Условие завершения рекурсии - все числа извлечены - -Решите через рекурсию. Решение через цикл не принимается. -Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 - +Используем операции % //, НЕ ИСПОЛЬЗУЕМ ОПЕРАЦИИ ВЗЯТИЯ ЭЛЕМЕНТА ПО ИНДЕКСУ Пример: Введите число: 123 Количество четных и нечетных цифр в числе равно: (1, 2) +Решите через рекурсию. Решение через цикл не принимается. +Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 """ +def recur_method(numb, even=0, odd=0): + # Рекурсия + # Все цифры, числа извлечены + if numb == 0: + return even, odd + else: + # извлекаем очередную цифру числах + cur_n = numb % 10 + # Число, естественно становится короче + numb = numb // 10 + # Проверка: цифра чётная или нечётная + if cur_n % 2 == 0: + even += 1 + else: + odd += 1 + return recur_method(numb, even, odd) + + +try: + NUMB = int(input("Введите натуральное число:")) + print(f"Количество чётных и нечетных цифр в числе: {recur_method(NUMB)}") +except ValueError: + print("Вы вместо числа ввели строку") diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index a3f170d6..00c1000c 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -2,16 +2,51 @@ 3. Сформировать из введенного числа обратное по порядку входящих в него цифр и вывести на экран. Например, если введено число 3486, то надо вывести число 6843. - Подсказка: На каждом шаге вам нужно 'доставать' из числа очередную цифру Пока все числа не извлечены рекурсивные вызовы продолжаем -Условие завершения рекурсии - все числа извлечены - -Решите через рекурсию. Решение через цикл не принимается. -Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 - +Условие завершения рекурсии - все цифры извлечены +Используем операции % //, НЕ ИСПОЛЬЗУЕМ ОПЕРАЦИИ ВЗЯТИЯ ЭЛЕМЕНТА ПО ИНДЕКСУ Пример: Введите число, которое требуется перевернуть: 123 Перевернутое число: 321 +Не забудьте проверить и на числах, заканчивающихся нулем. +Пример: +Введите число, которое требуется перевернуть: 1230 +Перевернутое число: 0321 +Решите через рекурсию. Решение через цикл не принимается. +Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 +""" + """ +# Рабочий вариант №1 +def rev_num(num, index=-1): + try: + print(num[index], end='') + except IndexError: + return + else: + index -= 1 + rev_num(num, index) +rev_num('1230') +""" + + +def revers_number(numb): + # Рекурсия + rest_numb, numeral = divmod(numb, 10) + if rest_numb == 0: + return str(numeral) + else: + return str(numeral) + str(revers_number(rest_numb)) + + +number = int(input("Введите число, которое требуется перевернуть:")) +print(f'Перевёрнутое число: {revers_number(number)}') + + +# Вариант в одну строку: + + +def revers_number(num): + return str(num) if num < 10 else str(num % 10) + revers_number(num // 10) diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" index 83482bdd..4a228cda 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" @@ -1,11 +1,35 @@ """ 4. Найти сумму n элементов следующего ряда чисел: 1 -0.5 0.25 -0.125 ... Количество элементов (n) вводится с клавиатуры. - Пример: Введите количество элементов: 3 -Количество элементов - 3, их сумма - 0.75 - +Количество элементов: 3, их сумма: 0.75 +Подсказка: +Каждый очередной элемент в 2 раза меньше предыдущего и имеет противоположный знак Решите через рекурсию. Решение через цикл не принимается. Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 """ + + +def recur_method(i, numb, n_count, common_sum): + # Рекурсия + if i == n_count: + print(f"Количество элементов - {n_count}, их сумма - {common_sum}") + elif i < n_count: + return recur_method(i + 1, numb / 2 * -1, n_count, common_sum + numb) + + +try: + N_COUNT = int(input("Введите количество элементов: ")) + recur_method(0, 1, N_COUNT, 0) +except ValueError: + print("Вы вместо числа ввели строку. Исправьте ошибку") + +""" +def recur_method(elem): + return 0 if elem == 0 else 1 + recur_method(elem - 1) / -2 # Решение в одну строку + + +N_COUNT = int(input('Введите количество элементов: ')) +print(f'Количество элементов: {N_COUNT}, их сумма: {recur_method(N_COUNT)}') +""" diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" index 89942335..0ea9516d 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" @@ -2,7 +2,6 @@ 5. Вывести на экран коды и символы таблицы ASCII, начиная с символа под номером 32 и заканчивая 127-м включительно. Вывод выполнить в табличной форме: по десять пар "код-символ" в каждой строке. - Пример: 32 - 33 - ! 34 - " 35 - # 36 - $ 37 - % 38 - & 39 - ' 40 - ( 41 - ) 42 - * 43 - + 44 - , 45 - - 46 - . 47 - / 48 - 0 49 - 1 50 - 2 51 - 3 @@ -14,7 +13,22 @@ 102 - f 103 - g 104 - h 105 - i 106 - j 107 - k 108 - l 109 - m 110 - n 111 - o 112 - p 113 - q 114 - r 115 - s 116 - t 117 - u 118 - v 119 - w 120 - x 121 - y 122 - z 123 - { 124 - | 125 - } 126 - ~ 127 -  - +Подсказка: +Допускается исп-е встроенных ф-ций, в частности, chr() Решите через рекурсию. Решение через цикл не принимается. Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 """ + + +def chr_row(ascii_val=32): + # Рекурсия + if ascii_val == 128: + return True + print(f' {ascii_val} - {chr(ascii_val)}', end=' ') + if (ascii_val - 31) % 10 == 0: + print('\n') + + chr_row(ascii_val + 1) + + +chr_row() diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_6.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_6.py" index 5d5f0035..7d7b9c35 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_6.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_6.py" @@ -4,8 +4,25 @@ неудачной попытки должно сообщаться больше или меньше введенное пользователем число, чем то, что загадано. Если за 10 попыток число не отгадано, то вывести загаданное число. - +Подсказка: +Базовый случай здесь - угадали число или закончились попытки Решите через рекурсию. Решение через цикл не принимается. Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 -Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 """ +def recur_method(count, numb): + # Рекурсия + print(f"Попытка №{count}") + answer = int(input("Введите число от 0 до 100: ")) + if count == 10 or answer == numb: + if answer == numb: + print("Верно") + print(f"Загаданное число: {numb}") + else: + if answer > numb: + print(f"Загаданное число меньше, чем {numb}") + else: + print(f"Загаданное число больше, чем {numb}") + recur_method(count + 1, numb) + + +recur_method(1, random.randint(0, 100)) diff --git "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_7.py" "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_7.py" index 7bd6493a..1b3d5c74 100644 --- "a/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_7.py" +++ "b/\320\243\321\200\320\276\320\272 2. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_7.py" @@ -1,8 +1,72 @@ """ 7. Напишите программу, доказывающую или проверяющую, что для множества натуральных чисел выполняется равенство: 1+2+...+n = n(n+1)/2, - где n - любое натуральное число. - - Решите через рекурсию. Решение через цикл не принимается. +где n - любое натуральное число. +Рекурсия вам нужна для решения левой части выражения. +Полученный результат нужно просто сравнить с результатом в правой. +Пример: +для n = 5 +1+2+3+4+5 = 5(5+1)/2 +Подсказка: +Правой части в рекурсии быть не должно. Необходимо сравнить результат, который даст рекурсивная ф-ция +со значением, полученным в правой части (здесь нужно просто подставить n и подсчитать) +Решите через рекурсию. Решение через цикл не принимается. Для оценки Отлично в этом блоке необходимо выполнить 5 заданий из 7 """ + + +def get_sum(lst_obj): + """Простая рекурсия""" + # базовый случай!!! + if len(lst_obj) == 1: + return lst_obj[0] + else: + # шаг рекурсии + return lst_obj[0] + get_sum(lst_obj[1:]) + + +print(get_sum([1, 2, 3])) +print(get_sum([1, 2, 3, 4, 5])) +print(get_sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) +print(get_sum([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])) + +a = 1 + 2 + 3 +b = 1 + 2 + 3 + 4 + 5 +c = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 +d = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + +A = 3 * (3 + 1) / 2 +B = 5 * (5 + 1) / 2 +C = 10 * (10 + 1) / 2 +D = 15 * (15 + 1) / 2 + +print(a, A) +print(b, B) +print(c, C) +print(d, D) + +""" +def recur_method(numb): + if numb == 1: + return numb + else: + return recur_method(numb - 1) + numb + + +try: + NUMB = int(input("Введите число: ")) + if recur_method(NUMB) == NUMB * (NUMB + 1) / 2: # Правая часть вынесена из рекурсии + print('Равенство верно') +except ValueError: + print("Вы вместо числа ввели строку (((. Исправьтесь") + +""" +""" +def get_sum_of_set(base): + return base if base == 1 else base + get_sum_of_set(base - 1) + + +n = 3 +print(f'Is 1+2+...+{n} = {n}({n}+1/2? \nAnswer: ' + f'{get_sum_of_set(n) == n * (n + 1) / 2} (Sum = {get_sum_of_set(n)})') +""" From e3b84cf18b5f0aaf681e46704c68296389e5b93e Mon Sep 17 00:00:00 2001 From: european Date: Sat, 1 May 2021 20:00:00 +0700 Subject: [PATCH 04/29] new --- .../task_1.py" | 38 ++++- .../task_2.py" | 138 +++++++++++++++++- .../task_3.py" | 58 +++++++- 3 files changed, 226 insertions(+), 8 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 55755352..d3dd8efd 100644 --- "a/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -1,12 +1,44 @@ """ Задание 1. - Реализуйте заполнение списка и словаря, сделайте замеры и сделайте выводы, обоснуйте результат. Сделайте несколько операций с каждым из объектов, сделайте замеры и сделайте выводы, обоснуйте результат. - Подсказка: для замеров воспользуйтесь модулем time (см. примеры урока 1) - Примечание: eсли вы уже знаете, что такое декоратор и как его реализовать, то реализуйте ф-цию-декоратор и пусть она считает время И примените ее к двум своим функциям. """ +from random import sample + +list = sample(range(-10, 11), 20) + +print(list) + +import timeit + +code_to_test = """ +a = range(100000) +b = [] +for i in a: + b.append(i*2) +""" + +elapsed_time = timeit.timeit(code_to_test, number=100) / 100 +print(elapsed_time) + +for a in range(20): + k = str(a + 1) + ' ' + 'may' + d = {k: a} + print(d) +print('Весь словарь имеет вид: ', d) + +import timeit + +code_to_test = """ +a = range(100000) +b = [] +for i in a: + b.append(i*2) +""" + +elapsed_time = timeit.timeit(code_to_test, number=100) / 100 +print(elapsed_time) diff --git "a/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 7877a7df..2f5b5569 100644 --- "a/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -4,14 +4,148 @@ Для этого пароля вам нужно получить хеш, используя функцию sha256 Для генерации хеша обязательно нужно использовать криптографическую соль Обязательно выведите созданный хеш - Далее программа должна запросить пароль повторно Вам нужно проверить, совпадает ли пароль с исходным Для проверки необходимо сравнить хеши паролей - ПРИМЕР: Введите пароль: 123 В базе данных хранится строка: 555a3581d37993843efd4eba1921f1dcaeeafeb855965535d77c55782349444b Введите пароль еще раз для проверки: 123 Вы ввели правильный пароль """ +import hashlib +import os + +users = {} # Простое демо хранилище + +# Add a user +username = 'Brent' # Имя пользователя +password = 'mypassword' # Пароль пользователя + +salt = os.urandom(32) # Новая соль для данного пользователя +key = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) +users[username] = { # Хранение ключа и соли + 'salt': salt, + 'key': key +} + +# Попытка проверки 1 (неправильный пароль) +username = 'Brent' +password = 'notmypassword' + +salt = users[username]['salt'] # Получение соли +key = users[username]['key'] # Получение правильного ключа +new_key = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) + +assert key != new_key # Ключи не совпадают, следовательно, пароли не совпадают + +# Попытка проверки 2 (правильный пароль) +username = 'Brent' +password = 'mypassword' + +salt = users[username]['salt'] +key = users[username]['key'] +new_key = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) + +assert key == new_key # Ключи совпадают, следовательно, и пароли совпадают + +# Добавление нового пользователя +username = 'Jarrod' +password = 'my$ecur3p@$$w0rd' + +salt = os.urandom(32) # Новая соль для данного пользователя +key = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) +users[username] = { + 'salt': salt, + 'key': key +} + +# Проверяем правильно ли введен пароль +username = 'Jarrod' +password = 'my$ecur3p@$$w0rd' + +salt = users[username]['salt'] +key = users[username]['key'] +new_key = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) + +assert key == new_key # Ключи совпадают, поэтому совпадают пароли и у этого пользователя + +""" +# -*- coding: utf-8 -*- +import re + +login = input('123') +password =input('123') + +test = True + +def main(): + if test == True: + print ('Привет {}'.format(login)) + else: print ('Кто-то пытался притвориться пользователем {}, но в пароле допустил ошибку:{}.'.format(login, name_error)) + + +def askPassword(success, failure): + global test + global name_error + vowels = ('e', 'y', 'u', 'i', 'o', 'a') + kolvo_vowels = 0 + for i in vowels: + kolvo_vowels += int(failure.count(i)) + + if kolvo_vowels > 2: + consonants = int(len(re.findall(r'\w', failure))) - int(len(re.findall(r'\d', failure))) - kolvo_vowels + if consonants == kolvo_vowels: + if consonants > 2: + return success + main() + else: + test = False + name_error = str('Wrong consonants').upper() + main() + print ('{} Wrong consonants'.format(success)) + return failure + else: + test = False + name_error = str(Everything is wrong).upper() + main() + print ('{} Everything is wrong'.format(success)) + return failure + else: + test = False + print ('{} Wrong number of vowels'.format(success)) + name_error = str('Wrong number of vowels').upper() + main() + return failure + +askPassword(login, password) +""" + +""" +vowels = set('aeiouy') +consonants = set(chr(n) for n in range(ord('a'), ord('z') + 1) if chr(n) not in vowels) +messages = ['', 'Wrong number of vowels', 'Wrong consonants', 'Everything is wrong'] + +def check_passord(login, password): + def filter_consonants(s): + return [c for c in s if c in consonants] + r1 = 0 if sum(1 for c in password if c in vowels) == 3 else 1 + r2 = 0 if filter_consonants(login) == filter_consonants(password) else 2 + return messages[r1 + r2] + +def askPassword(success, failure): + login = input().lower() + password = input().lower() + message = check_password(login, password) + if message: + failure(login, message) + else: + success(login) + +def main(): + def say_hello(login): + print(f'Привет {login}') + def report_error(login, message): + print(f'Кто-то пытался притвориться пользователем {login}, но в пароле допустил ошибку: {message}.') + askPassword(say_hello, report_error) +""" diff --git "a/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index ca72e990..1a97d68d 100644 --- "a/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 3. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -2,11 +2,8 @@ Задание 3. Определить количество различных подстрок с использованием хеш-функции. Дана строка S длиной N, состоящая только из строчных латинских букв. - Подсказка: примените хеши и множества - рара: - рар ра ар @@ -14,3 +11,58 @@ р а """ + +x = 26 + +mod = 3001 + + +# Функция для поиска необходимого количества + +def CntSubstr(s, l): + # Переменная в хеш + + hash = 0; + + # Нахождение хеша подстроки + + # (0, l-1) с использованием случайного числа x + + for i in range(l): + hash = (hash * x + (ord(s[i]) - 97)) % mod; + + # Вычисление х ^ (л-1) + + pow_l = 1; + + for i in range(l - 1): + pow_l = (pow_l * x) % mod; + + # Неупорядоченный набор для добавления значений хеша + + result = set(); + + result.add(hash); + + # Генерация всех возможных значений хеша + + for i in range(l, len(s)): + hash = ((hash - pow_l * (ord(s[i - l]) - 97) + + + 2 * mod) * x + (ord(s[i]) - 97)) % mod; + + result.add(hash); + + # Распечатать результат + + print(len(result)); + + +# Код водителя + +if __name__ == "__main__": + s = "abcba"; + + l = 2; + + CntSubstr(s, l); From e5a52f694504fb048e3eb4bd528827bae96228b6 Mon Sep 17 00:00:00 2001 From: european Date: Sat, 1 May 2021 20:08:42 +0700 Subject: [PATCH 05/29] new --- .../task_1.py" | 28 ++++++++++++++--- .../task_2.py" | 6 ++-- .../task_3.py" | 29 ++++++++++++++--- .../task_4.py" | 31 ++++++++++++++++--- 4 files changed, 78 insertions(+), 16 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index f6ffb4b9..5eeac5d2 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -1,18 +1,26 @@ """ Задание 1. - Приведен код, который позволяет сохранить в массиве индексы четных элементов другого массива - Сделайте замеры времени выполнения кода с помощью модуля timeit - Попробуйте оптимизировать код, чтобы снизить время выполнения Проведите повторные замеры - Добавьте аналитику: что вы сделали и почему """ from timeit import timeit +from timeit import Timer +import random + + +# Добавили новую функцию, которая бегает по циклу через enumerate, enumerate уже сам строит индексы массива +# И нам не нужно выбирать этот индекс самостоятельно из листа nums. +def func_2(nums): + new_arr = [] + for i, num in enumerate(nums, start=0): + if num % 2 == 0: + new_arr.append(i) + return new_arr def func_1(nums): @@ -21,3 +29,15 @@ def func_1(nums): if nums[i] % 2 == 0: new_arr.append(i) return new_arr + + +# l = [1,2,4,7,8,10,22] + +l = random.randint(0, 10000000000) + +t = Timer("func_1", "from __main__ import func_1") +t1 = Timer("func_2", "from __main__ import func_2") + +# При больших объемах, через функцию enumerate, работает быстрее. Что показывает статистика func1= 0.0165083 func2= 0.0164659 + +print("func1=", t.timeit(number=1000000), "func2=", t1.timeit(number=1000000)) diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 307657c8..8915cbe0 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -1,12 +1,10 @@ """ Задание 2. - Приведен код, который формирует из введенного числа обратное по порядку входящих в него цифр. Задача решена через рекурсию Выполнена попытка оптимизировать решение через мемоизацию. Сделаны замеры обеих реализаций. - Сделайте аналитику, нужна ли здесь мемоизация или нет и почему? Если у вас есть идеи, предложите вариант оптимизации. """ @@ -79,3 +77,7 @@ def recursive_reverse_mem(number): 'recursive_reverse_mem(num_10000)', setup='from __main__ import recursive_reverse_mem, num_10000', number=10000)) + + +# Так как, замеры показывают явное ускорение работы кода, то я делаю вывод, +# что код оптимизирован удачно и мемоизация нужна. diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index 696f5ec1..ae609b54 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -1,12 +1,9 @@ """ Задание 3. - Приведен код, формирующий из введенного числа обратное по порядку входящих в него цифр и вывести на экран. - Сделайте профилировку каждого алгоритма через cProfile и через timeit - Сделайте вывод, какая из трех реализаций эффективнее и почему """ @@ -20,7 +17,6 @@ def revers(enter_num, revers_num=0): enter_num //= 10 revers(enter_num, revers_num) - def revers_2(enter_num, revers_num=0): while enter_num != 0: num = enter_num % 10 @@ -28,9 +24,32 @@ def revers_2(enter_num, revers_num=0): enter_num //= 10 return revers_num - def revers_3(enter_num): enter_num = str(enter_num) revers_num = enter_num[::-1] return revers_num +from cProfile import run +from time import sleep + +def fast(): + print("Я быстрая функция") + + +def slow(): + sleep(3) + print("Я очень медленная функция") + + +def medium(): + sleep(0.5) + print("Я средняя функция...") + + +def main(): + fast() + slow() + medium() + + +run('main()') diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" index a852f43c..d1c7ff03 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" @@ -1,17 +1,33 @@ """ Задание 4. - Приведены два алгоритма. В них определяется число, которое встречается в массиве чаще всего. - Сделайте профилировку каждого алгоритма через timeit - Попытайтесь написать третью версию, которая будет самой быстрой. Сделайте замеры и опишите, получилось ли у вас ускорить задачу. """ +from timeit import timeit +from timeit import Timer array = [1, 3, 1, 3, 4, 5, 1] +# Создадим 3 функцию. В которой цикл будет идти по уникальным значениям списка. А не по всем, и даже тем, которые +# повторяются. При длинных списках это сократит время подсчета. При коротких разница не велика. +def func_3(): + # Создадим свой список с уникальными значениями входного списка + uniq_array = list(set(array)) + + m = 0 + num = 0 + + # И проверяем каждое уникальное значение на количество его вхождения в исходном списке. + for i in uniq_array: + count = array.count(i) + if count > m: + m = count + num = i + return f'Чаще всего встречается число {num}, ' \ + f'оно появилось в массиве {m} раз(а)' def func_1(): m = 0 @@ -37,5 +53,10 @@ def func_2(): f'оно появилось в массиве {max_2} раз(а)' -print(func_1()) -print(func_2()) +t1 = Timer("func_1","from __main__ import func_1") +t2 = Timer("func_2","from __main__ import func_2") +t3 = Timer("func_3","from __main__ import func_3") + +print(func_1(),t1.timeit(number=1000000)) +print(func_2(),t2.timeit(number=1000000)) +print(func_3(),t3.timeit(number=1000000)) From bc4788fde3a944396c0763d1b29900c0beac2ea6 Mon Sep 17 00:00:00 2001 From: european Date: Sat, 8 May 2021 23:34:23 +0700 Subject: [PATCH 06/29] new --- .../task_5.py" | 23 ++++++++++++++++++- .../task_1.py" | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" index 4e4f58b2..e807511f 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" @@ -14,8 +14,11 @@ Подумайте и по возможности определите сложность каждого алгоритма """ +import timeit + def simple(i): + # O(n**2) """Без использования «Решета Эратосфена»""" count = 1 n = 2 @@ -35,5 +38,23 @@ def simple(i): return n +def eratosfen(i): + # O(n log(log n)) +""" Используй алгоритм "Решето Эратосфена" """ + n = 2 + 1 = 10000 + sieve = [x for x in range(1)] + sieve[1] = 0 + while n < 1: + if sieve[n] != 0: + m = n * 2 + while m < 1: + sieve[m] = 0 + m += n + n += 1 + return [p for p in sieve if p != 0][i - 1] + + i = int(input('Введите порядковый номер искомого простого числа: ')) -print(simple(i)) \ No newline at end of file +print(timeit.timeit("simple(i)", globals=globals(), number=100)) +print(timeit.timeit("eratosfen(i)", globals=globals(), number=100)) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 82b46bcf..4307d822 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -25,3 +25,6 @@ Предприятия, с прибылью ниже среднего значения: Копыта """ + + + From 5beac5764642c6eceac2aaf77fbf54a2fad9fbe6 Mon Sep 17 00:00:00 2001 From: european Date: Sat, 8 May 2021 23:38:25 +0700 Subject: [PATCH 07/29] new --- .../task_5.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" index e807511f..4427a74e 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" @@ -40,7 +40,7 @@ def simple(i): def eratosfen(i): # O(n log(log n)) -""" Используй алгоритм "Решето Эратосфена" """ + # Используй алгоритм "Решето Эратосфена" n = 2 1 = 10000 sieve = [x for x in range(1)] From a435aba73049876518fa47817e1cd81c5075d2c6 Mon Sep 17 00:00:00 2001 From: european Date: Sat, 8 May 2021 23:52:34 +0700 Subject: [PATCH 08/29] new --- .../task_5.py" | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" index 4427a74e..994261a7 100644 --- "a/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" +++ "b/\320\243\321\200\320\276\320\272 4. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_5.py" @@ -42,13 +42,13 @@ def eratosfen(i): # O(n log(log n)) # Используй алгоритм "Решето Эратосфена" n = 2 - 1 = 10000 - sieve = [x for x in range(1)] - sieve[1] = 0 - while n < 1: + l = 10000 + sieve = [x for x in range(l)] + sieve[l] = 0 + while n < l: if sieve[n] != 0: m = n * 2 - while m < 1: + while m < l: sieve[m] = 0 m += n n += 1 From faccf4f969a4c1a132ca96503299bc5b7369a434 Mon Sep 17 00:00:00 2001 From: european Date: Sun, 9 May 2021 16:50:15 +0700 Subject: [PATCH 09/29] new --- .../task_1.py" | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 4307d822..d364ea15 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -25,6 +25,48 @@ Предприятия, с прибылью ниже среднего значения: Копыта """ +from collections import Counter +l_cnt_cmp = int(input("Введите количество предприятий для подсчета: ")) +l_obj = Counter() +l_obj_f = Counter() +for i in range(l_cnt_cmp): + l_cmp_name = str(input("Введите название Компании: ")) + l_cmp_fund = str() + for ifunds in range(4): + l_cmp_fund = l_cmp_fund + ' ' + str(input("Введите прибыль за " + str(ifunds+1) + "квартал для " + l_cmp_name + " = ")) + l_obj[l_cmp_name] += 1 + l_obj_f[l_cmp_name] += 1 + l_cmp_fund = l_cmp_fund[1:] + l_obj[l_cmp_name] = l_cmp_fund +for i_cmp in l_obj: + l_sum_cmp = l_obj[i_cmp].split(" ") + l_sum_cmp_f = int(0) + for i_sum_cmp in range(len(l_sum_cmp)): + l_v = int(l_sum_cmp[i_sum_cmp]) + l_sum_cmp_f = l_v + l_sum_cmp_f + l_obj_f[i_cmp] = l_sum_cmp_f + +l_cmp_avg_f = int(0) +for i_cmp_avg_f in l_obj_f: + l_cmp_avg_f = l_obj_f[i_cmp_avg_f] + l_cmp_avg_f + +l_cmp_avg_f = l_cmp_avg_f / len(l_obj) + +print("Средняя годовая прибыль компаний = " + str(l_cmp_avg_f)) + +l_cmp_name_max = str("Компании с годовой прибылью больше средней - ") +for i_max_f in l_obj_f: + if l_obj_f[i_max_f] > l_cmp_avg_f: + l_cmp_name_max = l_cmp_name_max + i_max_f + +print(l_cmp_name_max) + +l_cmp_name_min = str("Компании с годовой прибылью меньше средней - ") +for i_min_f in l_obj_f: + if l_obj_f[i_min_f] < l_cmp_avg_f: + l_cmp_name_min = l_cmp_name_min + " " + i_min_f + +print(l_cmp_name_min) From 83e99c17d5e60facf9579ee1fa27aa812edd2f03 Mon Sep 17 00:00:00 2001 From: european Date: Sun, 9 May 2021 19:21:01 +0700 Subject: [PATCH 10/29] new --- .../task_3.py" | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index dd1c82f3..d374c54d 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -9,4 +9,58 @@ Выполните различные операции с каждым из объектов. Сделайте замеры и оцените, насколько информация в документации соответствует дейстивтельности. -""" \ No newline at end of file +""" + +from collections import deque +from timeit import timeit +# Создаем лист +l_list = ['Nornikel','VTB','GPB','SBERB','ROGA I KOPYTA'] +# Создаем deque с таким же набором данных как и в l_list +l_deque = deque(l_list) +# Создадим такие же объекты для 2 теста +l_list2 = ['Nornikel','VTB','GPB','SBERB','ROGA I KOPYTA'] +l_deque2 = deque(l_list2) +# Первая операция - Добавление элемента в начало +# в list +def addelem_list (): + l_list.insert(len(l_list), 'ROSBANK') # O(1) +# в Deque +def addelem_deq (): + l_deque.appendleft('ROSBANK') # O(1) + +#Вторая операция - Добавление элемента в середину +# в list +def addelem_list2(): + # Определим середину. + l_avg = int(len(l_list2)/2) + # И вставим в середину. + l_list2.insert(l_avg, 'VEB-RF') +# в deque +def addelem_deq2(): + # Определим середину + l_avg_d = len(l_deque2) + l_deque2.insert(l_avg_d,'VEB_RF') + +print("------------------Первый тест--------------------") +print(len(l_list)) +print(len(l_deque)) +addelem_list() +addelem_deq() +print('addelem_list',timeit(f'addelem_list()',globals=globals())) +print('addelem_deq',timeit(f'addelem_deq()',globals=globals())) +print(len(l_list)) +print(len(l_deque)) +print("------------------Конец первого теста--------------------") +# Вывод: как на практике так и в документации, при одинаковой операции (Добавление элемента в начало списка) метод из deque +# показывает себя быстрее, на кокнкретном примере 0.20 против 0.12 При этом сложность алгоритмов - одинаковая. +print("------------------Второй тест--------------------") +print(len(l_list2)) +print(len(l_deque2)) +addelem_list2() +addelem_deq2() +print('addelem_list2', timeit(f'addelem_list2()', globals = globals())) +print('addelem_deq2', timeit(f'addelem_deq2()', globals = globals())) +print(len(l_list2)) +print(len(l_deque2)) +print("------------------Конец второго теста--------------------") +# Вывод: как на практике так и в документации, вставка с помощью метода insert в deque работает очень долго, по сравнению с вставкой в list. From 92fbd949901696e91f4a414b9cef6aea214ee7ee Mon Sep 17 00:00:00 2001 From: european Date: Sun, 9 May 2021 19:51:18 +0700 Subject: [PATCH 11/29] new --- .../task_4.py" | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" index 13ec157f..df61713e 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_4.py" @@ -3,4 +3,31 @@ Поработайте с обычным словарем и OrderedDict. Выполните различные операции с каждым из объектов и сделайте замеры. Опишите полученные результаты, сделайте выводы. -""" \ No newline at end of file +""" +from collections import OrderedDict +from timeit import timeit +l_od = OrderedDict() +l_od['3'] = 'a' +l_od['1'] = 'b' +l_od['2'] = 'c' + +l_d = dict() +l_d['3'] = 'a' +l_d['2'] = 'b' +l_d['1'] = 'c' + +def add_elem_od(): + l_od['4'] = 'c' + +def add_elem_d(): + l_d['4'] = 'c' + +print(l_od) +print(l_d) +add_elem_d() +add_elem_od() +print('add_elem_d',timeit(f'add_elem_d()',globals=globals())) +print('add_elem_od',timeit(f'add_elem_od()',globals=globals())) + +# Вывод: при одинаковой операции (Добавление пары Ключ = значение) идентичным методом, Ordinary Dict по времени равен обычному словарю. 0.11 против 0.11 +# Но при этом Ordinary Dict сохранил порядок вставки. From 6c321ffe6644b12ee29701c8827200ad4d702cf8 Mon Sep 17 00:00:00 2001 From: european Date: Mon, 10 May 2021 17:45:33 +0700 Subject: [PATCH 12/29] new --- .../task_2.py" | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 35add0f1..df4b6785 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -11,3 +11,41 @@ Также попробуйте решить задачу вообще без collections и применить только ваши знания по ООП (в частности по перегрузке методов) """ +first = str(input("Введите первое число в Шестнадцатеричной системе счисления= ")) +second = str(input("Введите второе число в Шестнадцатеричной системе счисления= ")) + +list_of_numbers = [str(i) for i in range(10)] + ['A', 'B', 'C', 'D', 'E', 'F'] + +if len(first) > len(second): + first, second = second, first + +second = second[::-1] +third = [] + +j = -1 +k = 0 +for i in second: + one = list_of_numbers.index(i) + two = list_of_numbers.index(first[j]) + third.append(list_of_numbers[(one + two + k) % 16]) + if (one + two) >= 15: + k = 1 + else: + k = 0 + j -= 1 + if j == -len(first)-1: + break + +diff = len(second) - len(first) + +if diff: + for i in second[-diff:]: + third.append(list_of_numbers[(list_of_numbers.index(second[-diff]) + k) % 16]) + if list_of_numbers.index(second[-diff]) + 1 >= 15: + k = 1 + else: + k = 0 +if k == 1: + third.append('1') + +print(third[::-1]) From e373b4d45785ea68ae0e4df0eace7b3c30b4cad6 Mon Sep 17 00:00:00 2001 From: european Date: Thu, 13 May 2021 10:45:35 +0700 Subject: [PATCH 13/29] new --- .../task_1.py" | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index d364ea15..223f3bdd 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -70,3 +70,44 @@ l_cmp_name_min = l_cmp_name_min + " " + i_min_f print(l_cmp_name_min) +""" +from collections import namedtuple + + +def calc(): + my_var - "company" + n = int(input("Введите количество предприятий: ")) + companies = namedtuple( + my_var, + " name_period_1 period_2 period_3 period_4") + profit_aver = {} + + for i in range(n): + company = companies( + name=input("Введите название предприятия: "), period_1=int( + input("Введите прибыль за первый квартал: ")), period_2=int( + input("Введите прибыль за второй квартал: ")), period_3=int( + input("Введите прибыль за третий квартал: ")), period_4=int( + input("Введите прибыль за четвёртый квартал: "))) + + profit_aver[company.name] = ( + company.period_1 + company.period_2 + + company.period_3 + company.period_4) / 4 + + total_aver = 0 + for value in profit_aver.values(): + total_aver += value + total_aver = total_aver / n + + for key, value in profit_aver.items(): + if value > total_aver: + print(f"{key} - прибыль выше среднего") + elif value < total_aver: + print(f"{key} - прибыль ниже среднего") + elif value == total_aver: + print(f"{key} - прибыль средняя") + +calc() +# Выше пример кода от преподавателя. + +""" \ No newline at end of file From 5b37b86ce6d11220eb59d1471d0979cddd6e819a Mon Sep 17 00:00:00 2001 From: european Date: Thu, 13 May 2021 13:08:55 +0700 Subject: [PATCH 14/29] new --- .../task_2.py" | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index df4b6785..abcfd0b1 100644 --- "a/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 5. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -49,3 +49,27 @@ third.append('1') print(third[::-1]) + +""" +def calc(): + nums = collections.defaultdict(list) + + # defaultdict(, + # {'1-A2': ['A', '2'], '2-C4F': ['C', '4', 'F']}) + for d in range(2): + n = input(f"Введите {d+1}-e натуральное шестнадцатеричное число: ") + nums[f"{d+1}-{n}"] = list(n) + print(nums) + + # 16-указываем с числами какой системы делаем операции + sum_res = sum([int(''.join(i), 16) for i in nums.values()]) + print(sum_res) + # '%X' Число в шестнадцатиричной системе счисления + + print("Сумма: ", list('%X' % sum_res)) + # f'{15:x}' -> f + mul_res = functools.reduce(lambda a, b: a * b, + [int(''.join(i), 16) for i in nums.values()]) + print("Произведение: ", list('%X' % mul_res)) + +""" \ No newline at end of file From b4f94967e7578aa1134a44191a2dbafd82690ec4 Mon Sep 17 00:00:00 2001 From: european Date: Thu, 13 May 2021 15:15:27 +0700 Subject: [PATCH 15/29] new --- .../task_1.py" | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 6. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 6. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 4bfb8a82..c8615028 100644 --- "a/\320\243\321\200\320\276\320\272 6. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 6. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -13,3 +13,63 @@ ВНИМАНИЕ: ЗАДАНИЯ, В КОТОРЫХ БУДУТ ГОЛЫЕ ЦИФРЫ ЗАМЕРОВ (БЕЗ АНАЛИТИКИ) БУДУТ ПРИНИМАТЬСЯ С ОЦЕНКОЙ УДОВЛЕТВОРИТЕЛЬНО """ + + +import copy +from memory_profiler import profile +from sys import getrefcount + + +# Найти сумму элементов следующего ряда чисел: 1 -0,5 0,25 -0,125 0,0625 ... +# Количество элементов(n) вводится с клавиатуры + +length = 900 + +# До + + +@profile +def for_in(length_val): + elem = 1 + amount = 0 + for i in range(length_val): + amount += elem + elem = -elem / 2 + print(f'Сумма последовательности из {length_val} элементов равна {amount}') + + +for_in(length) + +# После + + +@profile +def recursion(length): + def sum_series_numbers(n, elem=1): + if n <= 0: + return 0 + return elem + sum_series_numbers(n-1, -elem / 2) + print( + f'Сумма последовательности из {length} элементов равна: ' + f'{sum_series_numbers(length)}' + ) + + +recursion(length) +""" + + +def recur_method(i, numb, n_count, common_sum): + # Рекурсия + if i == n_count: + print(f"Количество элементов - {n_count}, их сумма - {common_sum}") + elif i < n_count: + return recur_method(i + 1, numb / 2 * -1, n_count, common_sum + numb) + + +try: + N_COUNT = int(input("Введите количество элементов: ")) + recur_method(0, 1, N_COUNT, 0) +except ValueError: + print("Вы вместо числа ввели строку. Исправьте ошибку") +""" From 4bcb3214707f8a7bcf24553545a0780922388f18 Mon Sep 17 00:00:00 2001 From: european Date: Mon, 17 May 2021 23:42:46 +0700 Subject: [PATCH 16/29] new --- .../task_1.py" | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 72a810e8..d6de79d6 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -12,3 +12,44 @@ Подсказка: обратите внимание, сортируем не по возрастанию, как в примере, а по убыванию """ +import timeit +import random + + +def bubble_sort(lst_obj): + n = 1 + while n < len(lst_obj): + for i in range(len(lst_obj)-n): + if lst_obj[i] > lst_obj[i+1]: + lst_obj[i], lst_obj[i+1] = lst_obj[i+1], lst_obj[i] + n += 1 + return lst_obj + + +orig_list = [random.randint(-100, 100) for _ in range(10)] + +# замеры 10 +print( + timeit.timeit( + "bubble_sort(orig_list[:])", + globals=globals(), + number=1000)) + +orig_list = [random.randint(-100, 100) for _ in range(100)] + +# замеры 100 +print( + timeit.timeit( + "bubble_sort(orig_list[:])", + globals=globals(), + number=1000)) + +orig_list = [random.randint(-100, 100) for _ in range(1000)] + +# замеры 1000 +print( + timeit.timeit( + "bubble_sort(orig_list[:])", + globals=globals(), + number=1000)) +print(orig_list) From 1bb63e1d46a04744f8e80ab4c5c48f9306240793 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 00:12:51 +0700 Subject: [PATCH 17/29] new --- .../task_1.py" | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index d6de79d6..136c0544 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -20,8 +20,8 @@ def bubble_sort(lst_obj): n = 1 while n < len(lst_obj): for i in range(len(lst_obj)-n): - if lst_obj[i] > lst_obj[i+1]: - lst_obj[i], lst_obj[i+1] = lst_obj[i+1], lst_obj[i] + if lst_obj[i] < lst_obj[i-1]: + lst_obj[i], lst_obj[i-1] = lst_obj[i-1], lst_obj[i] n += 1 return lst_obj @@ -53,3 +53,4 @@ def bubble_sort(lst_obj): globals=globals(), number=1000)) print(orig_list) +print(list) From a54e1f8eabb79c85a1f443bda20e2da1469638e0 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 00:20:41 +0700 Subject: [PATCH 18/29] new --- .../task_1.py" | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 136c0544..2f3a6348 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -26,7 +26,8 @@ def bubble_sort(lst_obj): return lst_obj -orig_list = [random.randint(-100, 100) for _ in range(10)] +orig_list = [random.randint(-100, 100) for _ in range(100)] +a = sorted(orig_list) # замеры 10 print( @@ -53,4 +54,4 @@ def bubble_sort(lst_obj): globals=globals(), number=1000)) print(orig_list) -print(list) +print(a) From 6804c2ffdb675e63ed4fe8d7bcd305cecfc26d74 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 00:27:50 +0700 Subject: [PATCH 19/29] new --- .../task_1.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 2f3a6348..3683b29d 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -27,7 +27,7 @@ def bubble_sort(lst_obj): orig_list = [random.randint(-100, 100) for _ in range(100)] -a = sorted(orig_list) +a = sorted(orig_list, reverse=True) # замеры 10 print( From 3372fdf6a9eee162e0e04f0a72ff5333fcb50e02 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 00:44:04 +0700 Subject: [PATCH 20/29] new --- .../task_2.py" | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 73d3dfb6..90a4227d 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -8,3 +8,69 @@ Исходный - [46.11436617832828, 41.62921998361278, 18.45859540989644, 12.128870723745806, 8.025098788570562] Отсортированный - [8.025098788570562, 12.128870723745806, 18.45859540989644, 41.62921998361278, 46.11436617832828] """ +import timeit +import random + + +def merge_sort(lst_obj): + if len(lst_obj) > 1: + center = len(lst_obj) // 2 + left = lst_obj[:center] + right = lst_obj[center:] + + merge_sort(left) + merge_sort(right) + + # перестали делить + # выполняем слияние + i, j, k = 0, 0, 0 + + while i < len(left) and j < len(right): + if left[i] < right[j]: + lst_obj[k] = left[i] + i += 1 + else: + lst_obj[k] = right[j] + j += 1 + k += 1 + + while i < len(left): + lst_obj[k] = left[i] + i += 1 + k += 1 + + while j < len(right): + lst_obj[k] = right[j] + j += 1 + k += 1 + return lst_obj + + +orig_list = [random.randint(0, 50) for _ in range(5)] +a = sorted(orig_list) + +# замеры 10 +print( + timeit.timeit( + "merge_sort(orig_list[:])", + globals=globals(), + number=1000)) + +orig_list = [random.randint(0, 50) for _ in range(50)] +# замеры 100 +print( + timeit.timeit( + "merge_sort(orig_list[:])", + globals=globals(), + number=1000)) + +orig_list = [random.randint(0, 50) for _ in range(500)] + +# замеры 1000 +print( + timeit.timeit( + "merge_sort(orig_list[:])", + globals=globals(), + number=1000)) +print(orig_list) +print(a) From c0bd2c997b254ef5dd1a6234c6230a7a9048fd16 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 01:03:32 +0700 Subject: [PATCH 21/29] new --- .../task_3.py" | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index cf5789f5..9acb5e7c 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -2,7 +2,7 @@ 3. Массив размером 2m + 1, где m – натуральное число, заполнен случайным образом. Найдите в массиве медиану. Медианой называется элемент ряда, делящий его на две равные части: в одной находятся элементы, которые не меньше медианы, -в другой – не больше медианы. + в другой – не больше медианы. Задачу можно решить без сортировки исходного массива. @@ -13,3 +13,80 @@ arr[m] from statistics import median """ + + +def select(a, left, right, n): + while True: + if left == right: + return left + + pivotIndex = pivot(a, left, right) + pivotIndex = partition(a, left, right, pivotIndex, n) + if n == pivotIndex: + return n + elif n < pivotIndex: + right = pivotIndex - 1 + else: + left = pivotIndex + 1 + + +def partition(a, left, right, pivot_index, n): + pivot_value = a[pivot_index] + # a[pivot_index], a[right] == a[right], a[pivot_index] + store_index = left + + for i in range(left, right - 1): + if a[i] < pivot_value: + a[store_index], a[i] = a[i], a[store_index] + store_index += 1 + store_index_eq = store_index + for i in range(store_index, right - 1): + if a[i] == pivot_value: + a[store_index_eq], a[i] = a[i], a[store_index] + store_index_eq += 1 + a[right], a[store_index_eq] = a[store_index_eq], a[right] + + if n < store_index: + return store_index + if n <= store_index_eq: + return n + return store_index_eq + + +def partition_5(a, left, right): + i = left + 1 + while i <= right: + j = i + while j > left and a[j - 1] > a[j]: + a[j - 1], a[j] = a[j], a[j - 1] + j -= 1 + i += 1 + return (left + right) // 2 + + +def pivot(a, left, right): + if right - left < 5: + return partition_5(a, left, right) + + for i in range(left, right, 5): + sub_right = i + 4 + if sub_right > right: + sub_right = right + median_5 = partition_5(a, i, sub_right) + a[median_5], a[left + (i - left) // 5] = a[left + (i - left) // 5], a[median_5] + + mid = (right - left) / 10 + left + 1 + return select(a, left, left + (right - left) // 5, mid) + + +if __name__ == '__main__': + m = 6 + a = [10, 90, 31, 96, 74, 56, 7, 11, 91, 73, 86, 62, 22] + print(a) + + left = 0 + right = len(a) - 1 + med_ind = pivot(a, left, right) + + print(f'медиана массива: {a[med_ind]}') + print(sorted(a)) From 04cddd079c587b6098a79c0798d746d255c8f280 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 01:05:05 +0700 Subject: [PATCH 22/29] new --- .../task_3.py" | 1 - 1 file changed, 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index 9acb5e7c..7320e1fc 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -32,7 +32,6 @@ def select(a, left, right, n): def partition(a, left, right, pivot_index, n): pivot_value = a[pivot_index] - # a[pivot_index], a[right] == a[right], a[pivot_index] store_index = left for i in range(left, right - 1): From 2a5fef1a28abd0906e5faeb6dc20a0e3ceac9a63 Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 01:07:20 +0700 Subject: [PATCH 23/29] new --- .../task_3.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index 7320e1fc..7d675331 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -80,7 +80,7 @@ def pivot(a, left, right): if __name__ == '__main__': m = 6 - a = [10, 90, 31, 96, 74, 56, 7, 11, 91, 73, 86, 62, 22] + a = [12, 90, 31, 94, 75, 56, 7, 11, 91, 73, 88, 62, 23] print(a) left = 0 From 9a21164e2ca7e6b415507a846c5a4012b8830def Mon Sep 17 00:00:00 2001 From: european Date: Tue, 18 May 2021 01:09:37 +0700 Subject: [PATCH 24/29] new --- .../task_3.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" index 7d675331..bbee4ae0 100644 --- "a/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" +++ "b/\320\243\321\200\320\276\320\272 7. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_3.py" @@ -80,7 +80,7 @@ def pivot(a, left, right): if __name__ == '__main__': m = 6 - a = [12, 90, 31, 94, 75, 56, 7, 11, 91, 73, 88, 62, 23] + a = [12, 90, 31, 94, 75, 56, 7, 11, 91, 73, 88, 57, 23] print(a) left = 0 From aff19b95dab4df315bb66299dc060f42ff947088 Mon Sep 17 00:00:00 2001 From: european Date: Fri, 21 May 2021 19:52:08 +0700 Subject: [PATCH 25/29] new --- .../task_1.py" | 95 +++++++++++++++++++ .../task_2.py" | 16 +++- 2 files changed, 110 insertions(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index d46ad997..990ad461 100644 --- "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -12,3 +12,98 @@ ВНИМАНИЕ: примеры заданий будут размещены в последний день сдачи. Но постарайтесь обойтись без них. """ +"""Хаффман через коллекции""" + + +from collections import Counter, deque + + +def haffman_tree(s): + # Считаем уникальные символы. + # Counter({'e': 4, 'b': 3, 'p': 2, ' ': 2, 'o': 2, 'r': 1, '!': 1}) + count = Counter(s) + # Сортируем по возрастанию количества повторений. + # deque([('r', 1), ('!', 1), ('p', 2), (' ', 2), ('o', 2), ('b', 3), ('e', 4)]) + sorted_elements = deque(sorted(count.items(), key=lambda item: item[1])) + # Проверка, если строка состоит из одного повторяющего символа. + if len(sorted_elements) != 1: + # Цикл для построения дерева + while len(sorted_elements) > 1: + # далее цикл объединяет два крайних левых элемента + # Вес объединенного элемента (накопленная частота) + # веса - 2, 4, 4, 7, 8, 15 + weight = sorted_elements[0][1] + sorted_elements[1][1] + # Словарь из 2 крайних левых элементов, попутно вырезаем их + # из "sorted_elements" (из очереди). + # comb - объединенный элемент + ''' + {0: 'r', 1: '!'} + {0: {0: 'r', 1: '!'}, 1: 'p'} + {0: ' ', 1: 'o'} + {0: 'b', 1: {0: ' ', 1: 'o'}} + {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'} + {0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}} + ''' + comb = {0: sorted_elements.popleft()[0], + 1: sorted_elements.popleft()[0]} + + # Ищем место для ставки объединенного элемента + for i, _count in enumerate(sorted_elements): + if weight > _count[1]: + continue + else: + # Вставляем объединенный элемент + sorted_elements.insert(i, (comb, weight)) + break + else: + # Добавляем объединенный корневой элемент после + # завершения работы цикла + + sorted_elements.append((comb, weight)) + ''' + deque([({0: 'r', 1: '!'}, 2), ('p', 2), (' ', 2), ('o', 2), ('b', 3), ('e', 4)]) + deque([(' ', 2), ('o', 2), ('b', 3), ({0: {0: 'r', 1: '!'}, 1: 'p'}, 4), ('e', 4)]) + deque([('b', 3), ({0: ' ', 1: 'o'}, 4), ({0: {0: 'r', 1: '!'}, 1: 'p'}, 4), ('e', 4)]) + deque([({0: {0: 'r', 1: '!'}, 1: 'p'}, 4), ('e', 4), ({0: 'b', 1: {0: ' ', 1: 'o'}}, 7)]) + deque([({0: 'b', 1: {0: ' ', 1: 'o'}}, 7), ({0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}, 8)]) + deque([({0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}}, 15)]) + ''' + else: + # приравниваемыем значение 0 к одному повторяющемуся символу + weight = sorted_elements[0][1] + comb = {0: sorted_elements.popleft()[0], 1: None} + sorted_elements.append((comb, weight)) + # sorted_elements - deque([({0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}}, 15)]) + # {0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}} + # словарь - дерево + return sorted_elements[0][0] + + +code_table = dict() + +# tree - {0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}} +def haffman_code(tree, path=''): + # Если элемент не словарь, значит мы достигли самого символа + # и заносим его, а так же его код в словарь (кодовую таблицу). + if not isinstance(tree, dict): + code_table[tree] = path + # Если элемент словарь, рекурсивно спускаемся вниз + # по первому и второму значению (левая и правая ветви). + else: + haffman_code(tree[0], path=f'{path}0') + haffman_code(tree[1], path=f'{path}1') + + +# строка для кодирования +s = "beep boop beer!" + +# функция заполняет кодовую таблицу (символ-его код) +# {'b': '00', ' ': '010', 'o': '011', 'r': '1000', '!': '1001', 'p': '101', 'e': '11'} +haffman_code(haffman_tree(s)) + +# code_table - {'b': '00', ' ': '010', 'o': '011', 'r': '1000', '!': '1001', 'p': '101', 'e': '11'} + +# выводим коды для каждого символа +for i in s: + print(code_table[i], end=' ') +print() diff --git "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 45e81f9c..8581667d 100644 --- "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -65,11 +65,17 @@ def set_root_val(self, obj): def get_root_val(self): return self.root + Try: + for left_child in left_child >= root_obj + + except: + print("Левый потомок не должен быть больше,либо равен своему предку") + print("Исправьте!") r = BinaryTree(8) print(r.get_root_val()) print(r.get_left_child()) -r.insert_left(4) +r.insert_left(10) print(r.get_left_child()) print(r.get_left_child().get_root_val()) r.insert_right(12) @@ -77,3 +83,11 @@ def get_root_val(self): print(r.get_right_child().get_root_val()) r.get_right_child().set_root_val(16) print(r.get_right_child().get_root_val()) +""" +try: + for i in range(3): + print(3/i) +except: + print("Деление на 0") + print("Исключение было обработано") +""" From db7db1f8236693844e20ada801d18bb57d58948b Mon Sep 17 00:00:00 2001 From: european Date: Fri, 21 May 2021 19:53:03 +0700 Subject: [PATCH 26/29] new --- .../task_2.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 8581667d..db2d6e3e 100644 --- "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -75,7 +75,7 @@ def get_root_val(self): r = BinaryTree(8) print(r.get_root_val()) print(r.get_left_child()) -r.insert_left(10) +r.insert_left(4) print(r.get_left_child()) print(r.get_left_child().get_root_val()) r.insert_right(12) From fc9dfdef56d90e213325faf5523d1b761b65831e Mon Sep 17 00:00:00 2001 From: european Date: Fri, 21 May 2021 19:56:34 +0700 Subject: [PATCH 27/29] new --- .../task_2.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index db2d6e3e..502ebe32 100644 --- "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -68,7 +68,7 @@ def get_root_val(self): Try: for left_child in left_child >= root_obj - except: + except TypeError: print("Левый потомок не должен быть больше,либо равен своему предку") print("Исправьте!") From 40815c108f80faf9d77254267e4bf47f13694ad2 Mon Sep 17 00:00:00 2001 From: european Date: Sun, 23 May 2021 16:41:47 +0700 Subject: [PATCH 28/29] new --- .../task_2.py" | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" index 502ebe32..21ca8a48 100644 --- "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" +++ "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_2.py" @@ -21,19 +21,28 @@ def __init__(self, root_obj): # добавить левого потомка def insert_left(self, new_node): - # если у узла нет левого потомка - if self.left_child == None: - # тогда узел просто вставляется в дерево - # формируется новое поддерево - self.left_child = BinaryTree(new_node) - # если у узла есть левый потомок - else: - # тогда вставляем новый узел - tree_obj = BinaryTree(new_node) - # и спускаем имеющегося потомка на один уровень ниже - tree_obj.left_child = self.left_child - self.left_child = tree_obj + try: + + if new_node >= self.get_root_val(): + raise Exception + + # если у узла нет левого потомка + if self.left_child == None: + # тогда узел просто вставляется в дерево + # формируется новое поддерево + self.left_child = BinaryTree(new_node) + # если у узла есть левый потомок + else: + # тогда вставляем новый узел + tree_obj = BinaryTree(new_node) + # и спускаем имеющегося потомка на один уровень ниже + tree_obj.left_child = self.left_child + self.left_child = tree_obj + except Exception: + print("Левый потомок не должен быть больше,либо равен своему предку " + str(new_node) + " >= " + str(self.get_root_val())) + print("Исправьте!") + raise # добавить правого потомка def insert_right(self, new_node): # если у узла нет правого потомка @@ -65,12 +74,7 @@ def set_root_val(self, obj): def get_root_val(self): return self.root - Try: - for left_child in left_child >= root_obj - except TypeError: - print("Левый потомок не должен быть больше,либо равен своему предку") - print("Исправьте!") r = BinaryTree(8) print(r.get_root_val()) @@ -78,6 +82,9 @@ def get_root_val(self): r.insert_left(4) print(r.get_left_child()) print(r.get_left_child().get_root_val()) +r.insert_left(10) +print(r.get_left_child()) +print(r.get_left_child().get_root_val()) r.insert_right(12) print(r.get_right_child()) print(r.get_right_child().get_root_val()) From 5f4fd394921392b9fa65ba905ba7116ce7b3bce7 Mon Sep 17 00:00:00 2001 From: european Date: Sun, 23 May 2021 18:36:45 +0700 Subject: [PATCH 29/29] new --- .../task_1.py" | 156 ++++++++---------- 1 file changed, 68 insertions(+), 88 deletions(-) diff --git "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" index 990ad461..9c03fe35 100644 --- "a/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" +++ "b/\320\243\321\200\320\276\320\272 8. \320\237\321\200\320\260\320\272\321\202\320\270\321\207\320\265\321\201\320\272\320\276\320\265 \320\267\320\260\320\264\320\260\320\275\320\270\320\265/task_1.py" @@ -18,92 +18,72 @@ from collections import Counter, deque -def haffman_tree(s): - # Считаем уникальные символы. - # Counter({'e': 4, 'b': 3, 'p': 2, ' ': 2, 'o': 2, 'r': 1, '!': 1}) - count = Counter(s) - # Сортируем по возрастанию количества повторений. - # deque([('r', 1), ('!', 1), ('p', 2), (' ', 2), ('o', 2), ('b', 3), ('e', 4)]) - sorted_elements = deque(sorted(count.items(), key=lambda item: item[1])) - # Проверка, если строка состоит из одного повторяющего символа. - if len(sorted_elements) != 1: - # Цикл для построения дерева - while len(sorted_elements) > 1: - # далее цикл объединяет два крайних левых элемента - # Вес объединенного элемента (накопленная частота) - # веса - 2, 4, 4, 7, 8, 15 - weight = sorted_elements[0][1] + sorted_elements[1][1] - # Словарь из 2 крайних левых элементов, попутно вырезаем их - # из "sorted_elements" (из очереди). - # comb - объединенный элемент - ''' - {0: 'r', 1: '!'} - {0: {0: 'r', 1: '!'}, 1: 'p'} - {0: ' ', 1: 'o'} - {0: 'b', 1: {0: ' ', 1: 'o'}} - {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'} - {0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}} - ''' - comb = {0: sorted_elements.popleft()[0], - 1: sorted_elements.popleft()[0]} - - # Ищем место для ставки объединенного элемента - for i, _count in enumerate(sorted_elements): - if weight > _count[1]: - continue +class HuffmanClass: + + def __init__(self, user_string): + self.user_string = user_string + self.code_table = dict() + self.huffman_code(self.get_tree()) + + def get_counter_symbol(self): + return Counter(self.user_string) + + def sort_counter_value(self): + return deque(sorted(self.get_counter_symbol().items(), + key=lambda item: item[1])) + + def get_tree(self): + sort_value = self.sort_counter_value().copy() + if len(sort_value) != 1: + while len(sort_value) > 1: + weight = sort_value[0][1] + sort_value[1][1] + new_elem = {0: sort_value.popleft()[0], + 1: sort_value.popleft()[0]} + for i, _count in enumerate(sort_value): + if weight > _count[1]: + continue + else: + sort_value.insert(i, (new_elem, weight)) + break else: - # Вставляем объединенный элемент - sorted_elements.insert(i, (comb, weight)) - break - else: - # Добавляем объединенный корневой элемент после - # завершения работы цикла - - sorted_elements.append((comb, weight)) - ''' - deque([({0: 'r', 1: '!'}, 2), ('p', 2), (' ', 2), ('o', 2), ('b', 3), ('e', 4)]) - deque([(' ', 2), ('o', 2), ('b', 3), ({0: {0: 'r', 1: '!'}, 1: 'p'}, 4), ('e', 4)]) - deque([('b', 3), ({0: ' ', 1: 'o'}, 4), ({0: {0: 'r', 1: '!'}, 1: 'p'}, 4), ('e', 4)]) - deque([({0: {0: 'r', 1: '!'}, 1: 'p'}, 4), ('e', 4), ({0: 'b', 1: {0: ' ', 1: 'o'}}, 7)]) - deque([({0: 'b', 1: {0: ' ', 1: 'o'}}, 7), ({0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}, 8)]) - deque([({0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}}, 15)]) - ''' - else: - # приравниваемыем значение 0 к одному повторяющемуся символу - weight = sorted_elements[0][1] - comb = {0: sorted_elements.popleft()[0], 1: None} - sorted_elements.append((comb, weight)) - # sorted_elements - deque([({0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}}, 15)]) - # {0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}} - # словарь - дерево - return sorted_elements[0][0] - - -code_table = dict() - -# tree - {0: {0: 'b', 1: {0: ' ', 1: 'o'}}, 1: {0: {0: {0: 'r', 1: '!'}, 1: 'p'}, 1: 'e'}} -def haffman_code(tree, path=''): - # Если элемент не словарь, значит мы достигли самого символа - # и заносим его, а так же его код в словарь (кодовую таблицу). - if not isinstance(tree, dict): - code_table[tree] = path - # Если элемент словарь, рекурсивно спускаемся вниз - # по первому и второму значению (левая и правая ветви). - else: - haffman_code(tree[0], path=f'{path}0') - haffman_code(tree[1], path=f'{path}1') - - -# строка для кодирования -s = "beep boop beer!" - -# функция заполняет кодовую таблицу (символ-его код) -# {'b': '00', ' ': '010', 'o': '011', 'r': '1000', '!': '1001', 'p': '101', 'e': '11'} -haffman_code(haffman_tree(s)) - -# code_table - {'b': '00', ' ': '010', 'o': '011', 'r': '1000', '!': '1001', 'p': '101', 'e': '11'} - -# выводим коды для каждого символа -for i in s: - print(code_table[i], end=' ') -print() + sort_value.append((new_elem, weight)) + else: + weight = sort_value[0][1] + new_elem = {0: sort_value.popleft()[0], 1: None} + sort_value.append((new_elem, weight)) + return sort_value[0][0] + + def huffman_code(self, tree, path=''): + if not isinstance(tree, dict): + self.code_table[tree] = path + else: + self.huffman_code(tree[0], path=f'{path}0') + self.huffman_code(tree[1], path=f'{path}1') + + def get_user_string_code(self): + res = '' + for symbol in self.user_string: + res += self.code_table[symbol] + return res + + def decoding(self, code_string): + res = '' + i = 0 + codes_dict = self.code_table + while i < len(code_string): + for code in codes_dict: + if code_string[i:].find(codes_dict[code]) == 0: + res += code + i += len(codes_dict[code]) + return res + + +user_string = input("Введите строку: ") +a_1 = HuffmanClass(user_string) +print(f"Исходная строка:\n'{user_string}'") + +tree_1 = a_1.get_tree() + +code_user_string = a_1.get_user_string_code() +print(f"Строка кода после кодирования:\n{code_user_string}") +print(f"Декодированная строка:\n'{a_1.decoding(code_user_string)}'") \ No newline at end of file