From eca0cf1cb36c7b6af2c9b9b05f91e39e89c1ad8c Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Sat, 13 May 2023 15:48:00 +0300 Subject: [PATCH 1/9] first commit --- for_challenges.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/for_challenges.py b/for_challenges.py index 997754da..c720c013 100644 --- a/for_challenges.py +++ b/for_challenges.py @@ -2,7 +2,8 @@ # Необходимо вывести имена всех учеников из списка с новой строки names = ['Оля', 'Петя', 'Вася', 'Маша'] -# ??? +for name in names: + print(name) # Задание 2 From c1ffe7430c18fdf42b574be0dc23192a8a3af498 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Thu, 18 May 2023 17:44:18 +0300 Subject: [PATCH 2/9] ex. 1 --- for_challenges.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/for_challenges.py b/for_challenges.py index c720c013..1bd448b3 100644 --- a/for_challenges.py +++ b/for_challenges.py @@ -5,7 +5,6 @@ for name in names: print(name) - # Задание 2 # Необходимо вывести имена всех учеников из списка, рядом с именем показать количество букв в нём # Пример вывода: @@ -13,8 +12,8 @@ # Петя: 4 names = ['Оля', 'Петя', 'Вася', 'Маша'] -# ??? - +for name in names: + print(f'{name}: {len(name)}') # Задание 3 # Необходимо вывести имена всех учеников из списка, рядом с именем вывести пол ученика @@ -26,8 +25,12 @@ 'Маша': False, } names = ['Оля', 'Петя', 'Вася', 'Маша'] -# ??? - +for name in names: + if is_male[name]: + gender = 'м' + else: + gender = 'ж' + print(f'{name}: {gender}') # Задание 4 # Даны группу учеников. Нужно вывести количество групп и для каждой группы – количество учеников в ней @@ -41,18 +44,21 @@ ['Вася', 'Маша', 'Саша', 'Женя'], ['Оля', 'Петя', 'Гриша'], ] -# ??? - +print(f'Всего {len(groups)} группы.') +for n in range(1, len(groups) + 1): + print(f'Группа {n}: {len(groups[n - 1])} ученика.') # Задание 5 # Для каждой пары учеников нужно с новой строки перечислить учеников, которые в неё входят # Пример вывода: # Группа 1: Вася, Маша -# Группа 2: Оля, Петя, Гриша +# Группа 2: Оля, Петя, Гри groups = [ ['Вася', 'Маша'], ['Оля', 'Петя', 'Гриша'], ['Вася', 'Маша', 'Саша', 'Женя'], ] -# ??? \ No newline at end of file +for n in range(1, len(groups) + 1): + print(f'Группа {n}:', end=' ') + print(*groups[n - 1], sep=", ") From 68476ce9ca0aa1c3c09e44441f35e6accb1ae866 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Fri, 19 May 2023 17:51:12 +0300 Subject: [PATCH 3/9] for_dict_challenges --- .gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e69de29b From 096794d30c30fb402722aae0b4d21af2b939af22 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Fri, 19 May 2023 17:58:58 +0300 Subject: [PATCH 4/9] 'for_dict_challenges' --- .gitignore | 1 + for_dict_challenges.py | 91 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index e69de29b..62c89355 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/for_dict_challenges.py b/for_dict_challenges.py index 96062ebc..efb6cb20 100644 --- a/for_dict_challenges.py +++ b/for_dict_challenges.py @@ -12,8 +12,14 @@ {'first_name': 'Маша'}, {'first_name': 'Петя'}, ] -# ??? +names = set([x['first_name'] for x in students]) +for name in names: + name_count = 0 + for student in students: + if name == student['first_name']: + name_count += 1 + print(f'{name}: {name_count}') # Задание 2 # Дан список учеников, нужно вывести самое часто повторящееся имя @@ -25,9 +31,26 @@ {'first_name': 'Маша'}, {'first_name': 'Маша'}, {'first_name': 'Оля'}, + {'first_name': 'Оля'} ] -# ??? +names = set([x['first_name'] for x in students]) +names_freq_dict = dict() + +for name in names: + name_count = 0 + for student in students: + if name == student['first_name']: + name_count += 1 + names_freq_dict[name] = name_count + +max_freq = max(names_freq_dict.values()) +max_freq_names_positions = [index for index, value in enumerate(list(names_freq_dict.values())) + if value == max_freq] +max_freq_names = [list(names_freq_dict.keys())[pos] for pos in max_freq_names_positions] +max_freq_names_str = ', '.join(max_freq_names) + +print(f'Чаще всего встречаются имена: {max_freq_names_str} ({max_freq} раз(a))') # Задание 3 # Есть список учеников в нескольких классах, нужно вывести самое частое имя в каждом классе. @@ -44,15 +67,36 @@ {'first_name': 'Маша'}, {'first_name': 'Маша'}, {'first_name': 'Оля'}, - ],[ # это – третий класс + ], [ # это – третий класс {'first_name': 'Женя'}, {'first_name': 'Петя'}, {'first_name': 'Женя'}, {'first_name': 'Саша'}, ], ] -# ??? +print('Самые частые имена по классам / число повторений:') +for num, group in enumerate(school_students): + # формирую частотный словарь имён в классе {имя: частота} + students = [student['first_name'] for student in group] + student_unique_names = set(students) + student_names_freq_dict = {name: students.count(name) for name in student_unique_names} + + # считаю, какое имя чаще всего встречается + max_freq = max(student_names_freq_dict.values()) # нахожу максимальное значение частоты + + # создаю список позиций (индексов) элементов с максимальной частотой в частотном словаре имён + max_freq_names_positions = [ + index + for index, value in enumerate(list(student_names_freq_dict.values())) + if value == max_freq + ] + + # формирую список самых частых имён + max_freq_names = [list(student_names_freq_dict.keys())[pos] for pos in max_freq_names_positions] + max_freq_names_str = ', '.join(max_freq_names) + + print(f'\t№{num + 1}: {max_freq_names_str} / {max_freq}') # Задание 4 # Для каждого класса нужно вывести количество девочек и мальчиков в нём. @@ -72,8 +116,20 @@ 'Миша': True, 'Даша': False, } -# ??? +for group in school: + group_name = group['class'] + gender_composition = { + 'ж': 0, + 'м': 0 + } + for student in group['students']: + if is_male[student['first_name']]: + gender_composition['м'] += 1 + if not is_male[student['first_name']]: + gender_composition['ж'] += 1 + + print(f'Класс {group_name}: девочки {gender_composition["ж"]}, мальчики {gender_composition["м"]}') # Задание 5 # По информации о учениках разных классов нужно найти класс, в котором больше всего девочек и больше всего мальчиков @@ -91,5 +147,28 @@ 'Олег': True, 'Миша': True, } -# ??? +school_gender_by_class = dict() +girls_by_class = dict() +boys_by_class = dict() + +for group in school: + class_name = group['class'] + boys = 0 + girls = 0 + for student in group['students']: + if is_male[student['first_name']]: + boys += 1 + if not is_male[student['first_name']]: + girls += 1 + girls_by_class[class_name] = girls + boys_by_class[class_name] = boys + +school_gender_by_class['девочек'] = girls_by_class +school_gender_by_class['мальчиков'] = boys_by_class + +for gender, breakdown in school_gender_by_class.items(): + max_gender_cnt = max(breakdown.values()) + classes_with_max_gender_cnt = [key for key, value in breakdown.items() if value == max_gender_cnt] + result = ', '.join(classes_with_max_gender_cnt) + print(f'Больше всего {gender} в классах: {result}') From 8d1b34c1dc32a941d386b661674de0ccceb58db7 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Fri, 19 May 2023 18:11:47 +0300 Subject: [PATCH 5/9] string_challenges --- string_challenges.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/string_challenges.py b/string_challenges.py index 856add2d..a0cca847 100644 --- a/string_challenges.py +++ b/string_challenges.py @@ -1,16 +1,23 @@ # Вывести последнюю букву в слове word = 'Архангельск' -# ??? +print(word[-1]) # Вывести количество букв "а" в слове word = 'Архангельск' -# ??? +word = word.lower() +print(word.count('а')) # Вывести количество гласных букв в слове +rus_vowels = 'аоуэыяёеюи' word = 'Архангельск' -# ??? +word_vowels_cnt = 0 +for letter in word.lower(): + if letter in rus_vowels: + word_vowels_cnt += 1 +print(f'Количество гласных букв в слове "{word}": {word_vowels_cnt}') + # Вывести количество слов в предложении @@ -20,9 +27,11 @@ # Вывести первую букву каждого слова на отдельной строке sentence = 'Мы приехали в гости' -# ??? +print(len(sentence.split())) # Вывести усреднённую длину слова в предложении sentence = 'Мы приехали в гости' -# ??? \ No newline at end of file +words_lengths = [len(word) for word in sentence.split()] +avg_word_length = sum(words_lengths) / len(words_lengths) +print(avg_word_length) From 008c0882a2f3863e5fcf17edd3d30950c84f0061 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Fri, 19 May 2023 18:17:31 +0300 Subject: [PATCH 6/9] string_challenges missed exercise --- string_challenges.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/string_challenges.py b/string_challenges.py index a0cca847..58ac830a 100644 --- a/string_challenges.py +++ b/string_challenges.py @@ -22,12 +22,14 @@ # Вывести количество слов в предложении sentence = 'Мы приехали в гости' -# ??? +print(len(sentence.split())) # Вывести первую букву каждого слова на отдельной строке sentence = 'Мы приехали в гости' -print(len(sentence.split())) +words = sentence.split() +for word in words: + print(word[0]) # Вывести усреднённую длину слова в предложении From 1bd56e86f08670ec638c7a9e11f3f567615f8ad0 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Tue, 23 May 2023 13:48:46 +0300 Subject: [PATCH 7/9] corrections made --- for_challenges.py | 18 ++++--- for_dict_challenges.py | 115 ++++++++++++++++++----------------------- string_challenges.py | 10 ++-- 3 files changed, 67 insertions(+), 76 deletions(-) diff --git a/for_challenges.py b/for_challenges.py index 1bd448b3..b0e466ae 100644 --- a/for_challenges.py +++ b/for_challenges.py @@ -1,6 +1,7 @@ # Задание 1 # Необходимо вывести имена всех учеников из списка с новой строки +print('Задание 1') names = ['Оля', 'Петя', 'Вася', 'Маша'] for name in names: print(name) @@ -11,6 +12,7 @@ # Оля: 3 # Петя: 4 +print('\nЗадание 2') names = ['Оля', 'Петя', 'Вася', 'Маша'] for name in names: print(f'{name}: {len(name)}') @@ -18,6 +20,7 @@ # Задание 3 # Необходимо вывести имена всех учеников из списка, рядом с именем вывести пол ученика +print('\nЗадание 3') is_male = { 'Оля': False, # если False, то пол женский 'Петя': True, # если True, то пол мужской @@ -26,10 +29,7 @@ } names = ['Оля', 'Петя', 'Вася', 'Маша'] for name in names: - if is_male[name]: - gender = 'м' - else: - gender = 'ж' + gender = ("woman", "man")[is_male[name]] print(f'{name}: {gender}') # Задание 4 @@ -39,14 +39,15 @@ # Группа 1: 2 ученика. # Группа 2: 4 ученика. +print('\nЗадание 4') groups = [ ['Вася', 'Маша'], ['Вася', 'Маша', 'Саша', 'Женя'], ['Оля', 'Петя', 'Гриша'], ] print(f'Всего {len(groups)} группы.') -for n in range(1, len(groups) + 1): - print(f'Группа {n}: {len(groups[n - 1])} ученика.') +for n, group in enumerate(groups, start=1): + print(f'Группа {n}: {len(group)} ученика.') # Задание 5 # Для каждой пары учеников нужно с новой строки перечислить учеников, которые в неё входят @@ -54,11 +55,12 @@ # Группа 1: Вася, Маша # Группа 2: Оля, Петя, Гри +print('\nЗадание 5') groups = [ ['Вася', 'Маша'], ['Оля', 'Петя', 'Гриша'], ['Вася', 'Маша', 'Саша', 'Женя'], ] -for n in range(1, len(groups) + 1): +for n, group in enumerate(groups, start=1): print(f'Группа {n}:', end=' ') - print(*groups[n - 1], sep=", ") + print(*group, sep=", ") diff --git a/for_dict_challenges.py b/for_dict_challenges.py index efb6cb20..648f11c8 100644 --- a/for_dict_challenges.py +++ b/for_dict_challenges.py @@ -1,3 +1,15 @@ +def make_freq_dict(students_list): + names_list = list([x['first_name'] for x in students_list]) + freq_dict = {name: names_list.count(name) for name in set(names_list)} + return freq_dict + + +def find_max_freq_items(freq_dict): + max_freq = max(freq_dict.values()) + max_freq_names = [name for name, freq in freq_dict.items() if freq == max_freq] + return ', '.join(max_freq_names), max_freq + + # Задание 1 # Дан список учеников, нужно посчитать количество повторений каждого имени ученика # Пример вывода: @@ -5,6 +17,8 @@ # Маша: 2 # Петя: 2 +print('Задание 1') + students = [ {'first_name': 'Вася'}, {'first_name': 'Петя'}, @@ -12,19 +26,18 @@ {'first_name': 'Маша'}, {'first_name': 'Петя'}, ] -names = set([x['first_name'] for x in students]) -for name in names: - name_count = 0 - for student in students: - if name == student['first_name']: - name_count += 1 - print(f'{name}: {name_count}') +name_freq_dict = make_freq_dict(students) +for name, freq in name_freq_dict.items(): + print(f'{name}: {freq}') # Задание 2 # Дан список учеников, нужно вывести самое часто повторящееся имя # Пример вывода: # Самое частое имя среди учеников: Маша + +print('\nЗадание 2') + students = [ {'first_name': 'Вася'}, {'first_name': 'Петя'}, @@ -34,23 +47,9 @@ {'first_name': 'Оля'} ] -names = set([x['first_name'] for x in students]) -names_freq_dict = dict() - -for name in names: - name_count = 0 - for student in students: - if name == student['first_name']: - name_count += 1 - names_freq_dict[name] = name_count - -max_freq = max(names_freq_dict.values()) -max_freq_names_positions = [index for index, value in enumerate(list(names_freq_dict.values())) - if value == max_freq] -max_freq_names = [list(names_freq_dict.keys())[pos] for pos in max_freq_names_positions] -max_freq_names_str = ', '.join(max_freq_names) - -print(f'Чаще всего встречаются имена: {max_freq_names_str} ({max_freq} раз(a))') +names_freq_dict = make_freq_dict(students) +result = find_max_freq_items(names_freq_dict) +print(f'Чаще всего встречаются имена: {result[0]} ({result[1]} раз(a))') # Задание 3 # Есть список учеников в нескольких классах, нужно вывести самое частое имя в каждом классе. @@ -58,6 +57,8 @@ # Самое частое имя в классе 1: Вася # Самое частое имя в классе 2: Маша +print('\nЗадание 3') + school_students = [ [ # это – первый класс {'first_name': 'Вася'}, @@ -76,27 +77,10 @@ ] print('Самые частые имена по классам / число повторений:') -for num, group in enumerate(school_students): - # формирую частотный словарь имён в классе {имя: частота} - students = [student['first_name'] for student in group] - student_unique_names = set(students) - student_names_freq_dict = {name: students.count(name) for name in student_unique_names} - - # считаю, какое имя чаще всего встречается - max_freq = max(student_names_freq_dict.values()) # нахожу максимальное значение частоты - - # создаю список позиций (индексов) элементов с максимальной частотой в частотном словаре имён - max_freq_names_positions = [ - index - for index, value in enumerate(list(student_names_freq_dict.values())) - if value == max_freq - ] - - # формирую список самых частых имён - max_freq_names = [list(student_names_freq_dict.keys())[pos] for pos in max_freq_names_positions] - max_freq_names_str = ', '.join(max_freq_names) - - print(f'\t№{num + 1}: {max_freq_names_str} / {max_freq}') +for num, group in enumerate(school_students, start=1): + group_names_freq_dict = make_freq_dict(group) + result = find_max_freq_items(group_names_freq_dict) + print(f'\t№{num}: {result[0]} / {result[1]}') # Задание 4 # Для каждого класса нужно вывести количество девочек и мальчиков в нём. @@ -104,6 +88,8 @@ # Класс 2a: девочки 2, мальчики 0 # Класс 2б: девочки 0, мальчики 2 +print('\nЗадание 4') + school = [ {'class': '2a', 'students': [{'first_name': 'Маша'}, {'first_name': 'Оля'}]}, {'class': '2б', 'students': [{'first_name': 'Олег'}, {'first_name': 'Миша'}]}, @@ -120,16 +106,15 @@ for group in school: group_name = group['class'] gender_composition = { - 'ж': 0, - 'м': 0 + 'f': 0, + 'm': 0 } + for student in group['students']: - if is_male[student['first_name']]: - gender_composition['м'] += 1 - if not is_male[student['first_name']]: - gender_composition['ж'] += 1 + key = ('f', 'm')[is_male[student['first_name']]] + gender_composition[key] += 1 - print(f'Класс {group_name}: девочки {gender_composition["ж"]}, мальчики {gender_composition["м"]}') + print(f'Класс {group_name}: девочки {gender_composition["f"]}, мальчики {gender_composition["m"]}') # Задание 5 # По информации о учениках разных классов нужно найти класс, в котором больше всего девочек и больше всего мальчиков @@ -137,6 +122,7 @@ # Больше всего мальчиков в классе 3c # Больше всего девочек в классе 2a +print('\nЗадание 5') school = [ {'class': '2a', 'students': [{'first_name': 'Маша'}, {'first_name': 'Оля'}]}, {'class': '3c', 'students': [{'first_name': 'Олег'}, {'first_name': 'Миша'}]}, @@ -148,27 +134,26 @@ 'Миша': True, } + +def count_group_gender_composition(group, gender_name_dict): + gender_composition = [0, 0] + for student in group['students']: + gender_composition[gender_name_dict[student['first_name']]] += 1 + return gender_composition + + school_gender_by_class = dict() girls_by_class = dict() boys_by_class = dict() for group in school: class_name = group['class'] - boys = 0 - girls = 0 - for student in group['students']: - if is_male[student['first_name']]: - boys += 1 - if not is_male[student['first_name']]: - girls += 1 - girls_by_class[class_name] = girls - boys_by_class[class_name] = boys + girls_by_class[class_name], boys_by_class[class_name] = count_group_gender_composition(group, is_male) school_gender_by_class['девочек'] = girls_by_class school_gender_by_class['мальчиков'] = boys_by_class + for gender, breakdown in school_gender_by_class.items(): - max_gender_cnt = max(breakdown.values()) - classes_with_max_gender_cnt = [key for key, value in breakdown.items() if value == max_gender_cnt] - result = ', '.join(classes_with_max_gender_cnt) - print(f'Больше всего {gender} в классах: {result}') + result = find_max_freq_items(breakdown) + print(f'Больше всего {gender} в классах: {result[0]}') diff --git a/string_challenges.py b/string_challenges.py index 58ac830a..950a0c71 100644 --- a/string_challenges.py +++ b/string_challenges.py @@ -1,31 +1,34 @@ # Вывести последнюю букву в слове +print('Задание 1') word = 'Архангельск' print(word[-1]) # Вывести количество букв "а" в слове +print('\nЗадание 2') word = 'Архангельск' word = word.lower() print(word.count('а')) # Вывести количество гласных букв в слове +print('\nЗадание 3') rus_vowels = 'аоуэыяёеюи' word = 'Архангельск' word_vowels_cnt = 0 for letter in word.lower(): - if letter in rus_vowels: - word_vowels_cnt += 1 + word_vowels_cnt += letter in rus_vowels print(f'Количество гласных букв в слове "{word}": {word_vowels_cnt}') - # Вывести количество слов в предложении +print('\nЗадание 4') sentence = 'Мы приехали в гости' print(len(sentence.split())) # Вывести первую букву каждого слова на отдельной строке +print('\nЗадание 5') sentence = 'Мы приехали в гости' words = sentence.split() for word in words: @@ -33,6 +36,7 @@ # Вывести усреднённую длину слова в предложении +print('\nЗадание 6') sentence = 'Мы приехали в гости' words_lengths = [len(word) for word in sentence.split()] avg_word_length = sum(words_lengths) / len(words_lengths) From 889660f0ef2a83af25eaf0f0133231297b0f25ef Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Tue, 23 May 2023 13:59:30 +0300 Subject: [PATCH 8/9] few corrections made --- for_dict_challenges.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/for_dict_challenges.py b/for_dict_challenges.py index 648f11c8..7a73d453 100644 --- a/for_dict_challenges.py +++ b/for_dict_challenges.py @@ -4,7 +4,7 @@ def make_freq_dict(students_list): return freq_dict -def find_max_freq_items(freq_dict): +def find_items_with_max_values(freq_dict): max_freq = max(freq_dict.values()) max_freq_names = [name for name, freq in freq_dict.items() if freq == max_freq] return ', '.join(max_freq_names), max_freq @@ -48,7 +48,7 @@ def find_max_freq_items(freq_dict): ] names_freq_dict = make_freq_dict(students) -result = find_max_freq_items(names_freq_dict) +result = find_items_with_max_values(names_freq_dict) print(f'Чаще всего встречаются имена: {result[0]} ({result[1]} раз(a))') # Задание 3 @@ -79,7 +79,7 @@ def find_max_freq_items(freq_dict): print('Самые частые имена по классам / число повторений:') for num, group in enumerate(school_students, start=1): group_names_freq_dict = make_freq_dict(group) - result = find_max_freq_items(group_names_freq_dict) + result = find_items_with_max_values(group_names_freq_dict) print(f'\t№{num}: {result[0]} / {result[1]}') # Задание 4 @@ -155,5 +155,5 @@ def count_group_gender_composition(group, gender_name_dict): for gender, breakdown in school_gender_by_class.items(): - result = find_max_freq_items(breakdown) + result = find_items_with_max_values(breakdown) print(f'Больше всего {gender} в классах: {result[0]}') From c7718d35ec2914e41a07a03554419605423f5354 Mon Sep 17 00:00:00 2001 From: AlexandraPoturaeva Date: Thu, 25 May 2023 11:53:18 +0300 Subject: [PATCH 9/9] for_dict_challenges_bonus.py done --- for_dict_challenges_bonus.py | 199 ++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 1 deletion(-) diff --git a/for_dict_challenges_bonus.py b/for_dict_challenges_bonus.py index 9f35a0a0..7270e598 100644 --- a/for_dict_challenges_bonus.py +++ b/for_dict_challenges_bonus.py @@ -35,6 +35,7 @@ import datetime import lorem +from typing import Dict, Tuple, List def generate_chat_history(): @@ -66,5 +67,201 @@ def generate_chat_history(): return messages +def make_freq_dict_by_key(messages_list: List[Dict], key: str) -> Dict: + """ + Принимает список словарей с информацией по сообщениям в чате + и ключ, по которому необходимо осуществить подбор данных. + Например, если передать ключ "sent_by", + то функуия сначала создаст список, сотоязий из id пользователей, кто написал каждое сообщение, + а потом создаст частотный словарь, где ключами будут id пользователей, + а значениями - количество сообщений, написанных ими в чате. + :param messages_list: список словарей с информацией по сообщениям в чате + :param key: ключ, + по которому необходимо осуществить подбор данных по сообщениям + :return: частотный словарь + """ + some_list = [message[key] for message in messages_list if message[key]] + freq_dict = {value: some_list.count(value) for value in set(some_list)} + return freq_dict + + +def find_items_with_max_values(freq_dict: Dict) -> Tuple[List, int]: + """ + Функция определяет ключи с максимальным значением. + :param freq_dict: словарь, значения в котором являются целыми числами + :return: кортеж из двух элементов. + Первый элемент - список ключей с максимальным значением + Второй элемент - максимальное значение (целое число) + """ + max_freq = max(freq_dict.values()) + max_freq_items = [name for name, freq in freq_dict.items() if freq == max_freq] + return max_freq_items, max_freq + + +def users_wrote_max(messages_list: List[Dict]) -> Tuple[List, int]: + """ + Функция вычисляет пользователей, которые написали максимальное количество сообщений в чате + :param messages_list: список словарей с информацией по сообщениям в чате + :return кортеж из двух элементов. + Первый элемент - список id пользователей. + Второй элемент - максимальное число сообщений + """ + return find_items_with_max_values(make_freq_dict_by_key(messages_list, 'sent_by')) + + +def users_got_max_replies_by_one_message(messages_list: List[Dict]) -> Tuple[List, int]: + """ + Функция вычисляет пользователей, сообщения которых получили максимальное количество ответов + (к одному сообщению) + :param messages_list: список словарей с информацией по сообщениям в чате + :return: кортеж из двух элементов. + Первый элемент - список id пользователей + Второй элемент - максимальное число ответов на сообщение + """ + messages_with_max_replies = find_items_with_max_values(make_freq_dict_by_key(messages_list, 'reply_for')) + users_got_max_replies = [message['sent_by'] for message in messages_list if + message['id'] in messages_with_max_replies[0]] + max_replies_by_one_message = messages_with_max_replies[1] + return users_got_max_replies, max_replies_by_one_message + + +def users_got_max_replies_total(messages_list: List[Dict]) -> Tuple[List, int]: + """ + Функция вычисляет пользователей, + которые суммарно получили максимальное количество ответов на все свои сообщения + :param messages_list: список словарей с информацией по сообщениям в чате + :return: кортеж из двух элементов. + Первый элемент - список id пользователей + Второй элемент - максимальное число ответов + """ + replies_cnt_by_message = make_freq_dict_by_key(messages_list, 'reply_for') + messages_with_reply_info = dict() + for message_with_reply in replies_cnt_by_message.keys(): + message_info = dict() + for message in messages_list: + if message['id'] == message_with_reply: + message_info['sent_by'] = message['sent_by'] + message_info['replies_cnt'] = replies_cnt_by_message[message_with_reply] + messages_with_reply_info[message_with_reply] = message_info + + total_replies_cnt_by_users = dict() + for message in messages_with_reply_info.values(): + if message['sent_by'] in total_replies_cnt_by_users: + total_replies_cnt_by_users[message['sent_by']] += message['replies_cnt'] + else: + total_replies_cnt_by_users[message['sent_by']] = message['replies_cnt'] + + return find_items_with_max_values(total_replies_cnt_by_users) + + +def users_wrote_messages_seen_by_max_users(messages_list: List[Dict]) -> Tuple[List, int]: + """ + Функция вычисляет пользователей, + сообщения которых увидело максимальное количество уникальных пользователей + :param messages_list: список словарей с информацией по сообщениям в чате + :return: кортеж из двух элементов. + Первый элемент - список id пользователей + Второй элемент - максимальное число уникальных пользователей, увидевших сообщения + """ + sent_by_seen_by_dict = dict() + + for message in messages_list: + sent_by = message['sent_by'] + seen_by = message['seen_by'] + if sent_by not in sent_by_seen_by_dict: + sent_by_seen_by_dict[sent_by] = [] + if sent_by in sent_by_seen_by_dict: + sent_by_seen_by_dict[sent_by].extend(seen_by) + + for item in sent_by_seen_by_dict: + unique_ids = set(sent_by_seen_by_dict[item]) + sent_by_seen_by_dict[item] = len(unique_ids) + + return find_items_with_max_values(sent_by_seen_by_dict) + + +def count_messages_by_time_period(messages_list: List[Dict], start_hour: int, finish_hour: int) -> int: + """ + Функуия считает количество сообщений, написанных в определённые часы + :param messages_list: список словарей с информацией по сообщениям в чате + :param start_hour: час начала + :param finish_hour: час окончания + :return: количество сообщений, написанных в определённые часы + """ + count = len([message for message in messages_list if start_hour <= message['sent_at'].hour < finish_hour]) + return count + + +def find_prime_time_period(messages_list, *hours: int) -> str: + """ + Функуия определяет, в какой из периодов времени в сутках написано больше всего сообщений в чате + :param messages_list: список словарей с информацией по сообщениям в чате + :param hours: часы, определяющие временные границы периодов для подсчёта сообщений + :return: строка с информацией о периоде времени, когда написано максимальное количество сообщений + """ + time_periods = [] + time_periods.extend([(0, hours[0]), (hours[-1], 24)]) + for n in range(len(hours)): + if n < len(hours) - 1: + time_periods.append((hours[n], hours[n + 1])) + + messages_by_time_dict = {time_period: count_messages_by_time_period(messages_list, time_period[0], time_period[1]) + for time_period in time_periods} + prime_time_info = find_items_with_max_values(messages_by_time_dict) + + match prime_time_info[0][0]: + case (0, 12): + return 'утром (до 12 часов)' + case (12, 18): + return 'днём (12-18 часов)' + case (18, 24): + return 'вечером (после 18 часов)' + + return f'c {prime_time_info[0][0][0]} до {prime_time_info[0][0][1]} часов' + + +def messages_with_longest_threads(message_list: List[Dict]) -> Tuple[List, int]: + """ + Функция вычисляет сообщения, которые стали началом для самых длинных тредов (цепочек ответов) + :param message_list: список словарей с информацией по сообщениям в чате + :return: кортеж из двух элементов. + Первый элемент - список id сообщений + Второй элемент - максимальное число сообщений в треде + """ + reply_messages = [message for message in message_list if message['reply_for']] + reply_messages_ids = [message['id'] for message in reply_messages] + reply_chain_length_by_message = dict() + + for message in reply_messages: + count = 2 + parent_message_id = message['reply_for'] + while parent_message_id in reply_messages_ids: + count += 1 + parent_message_id = reply_messages[reply_messages_ids.index(parent_message_id)]['reply_for'] + reply_chain_length_by_message[parent_message_id] = count + + return find_items_with_max_values(reply_chain_length_by_message) + + if __name__ == "__main__": - print(generate_chat_history()) + messages = generate_chat_history() + + print(f'1. Пользователи с id {users_wrote_max(messages)[0]} написал(и) сообщений больше всех ' + f'({users_wrote_max(messages)[1]} шт.)') + + print(f'2а. Сообщения с максимальным количеством ответов были отправлены пользователями ' + f'с id {users_got_max_replies_by_one_message(messages)[0]} ' + f'({users_got_max_replies_by_one_message(messages)[1]} ответа(-ов))') + + print(f'2б. Больше всего ответов (суммарно на все свои сообщения)' + f' получили пользователи с id {users_got_max_replies_total(messages)[0]} ' + f'({users_got_max_replies_total(messages)[1]} ответа(-ов))') + + print(f'3. Id пользователей, сообщения которых видело больше всего уникальных пользователей: ' + f'{users_wrote_messages_seen_by_max_users(messages)[0]}') + + print(f'4. Больше всего сообщений в чате {find_prime_time_period(messages, 12, 18)}') + + print(f'5. Id сообщений, которые стали началом для самых длинных тредов ' + f'{list(map(str, messages_with_longest_threads(messages)[0]))} ' + f'(длина треда - {messages_with_longest_threads(messages)[1]} сообщений)') \ No newline at end of file