diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c71e4f69 --- /dev/null +++ b/.gitignore @@ -0,0 +1,126 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +#Files +settings.py \ No newline at end of file diff --git a/dict_sorting_additional.py b/dict_sorting_additional.py new file mode 100644 index 00000000..51d1fa66 --- /dev/null +++ b/dict_sorting_additional.py @@ -0,0 +1,50 @@ +''' +Дополнительное задание: +Посчитать число буквв слове и вывести начиная с самой часто встречающейся и дльше по убыванию. + Если несколько букв встречаются в слове одинаковое число раз, + то вывести вперед ту что раньше в алфавите. Написать три решения - использую просто словарь, defaultdict и Counter. +''' +from collections import defaultdict, Counter +import string +import random + +def letter_counter_dict(word): #решение 1 через словарь + #word_list = sorted(list(word)) #переводим в стисок и сортируем чтобы при одинкаовых количесвах буквы бли в алфавитном порядке + letter_dict = {} + for letter in word: #формируем словарь через get + letter_dict[letter] = letter_dict.get(letter, 0) + 1 + + result1 = sorted(letter_dict.items(), key=lambda item: item[0]) #сортировка по алфафиту после подсчета + result2 = sorted(result1, key=lambda item: item[1], reverse=True) #обратная сортировка по значению + for (key, value) in result2: + print(key, value, end=' ') + +def letter_counter_dict_2(word): #решение 2 через defaultdict + #word_list = sorted(list(word)) + letter_dict = defaultdict(lambda: 0) #задаем дефолное значения ключа + for letter in word: #формируем словарь + letter_dict[letter] += 1 + + result1 = sorted(letter_dict.items(), key=lambda item: item[0]) #сортировка по алфафиту после подсчета + result2 = sorted(result1, key=lambda item: item[1], reverse=True) #обратная сортировка по значению + for (key, value) in result2: + print(key, value, end=' ') + +def letter_counter_dict_3(word): #решение 3 через Counter + word_list = sorted(list(word)) + letter_dict = Counter(word_list) + result = letter_dict.most_common() + for (key, value) in result: + print(key, value, end=' ') + + +if __name__ == '__main__': + + random_string = 'pnbalkpanactlnca' + #test_string = ''.join(random.choices(string.ascii_letters, k=100000)) + print('Способ 1') + letter_counter_dict(random_string) + print ('\nСпособ 2') + letter_counter_dict_2(random_string) + print ('\nСпособ 3') + letter_counter_dict_3(random_string) \ No newline at end of file diff --git a/ephem2_bot.py b/ephem2_bot.py new file mode 100644 index 00000000..3649d233 --- /dev/null +++ b/ephem2_bot.py @@ -0,0 +1,82 @@ +''' +Изменени: +1.Добавлена команда для получении информации о дате следующего полнолуния: +Реализуйте в боте команду, которая отвечает на вопрос “Когда ближайшее полнолуние?” + Например /next_full_moon 2019-01-01. Чтобы узнать, когда ближайшее полнолуние, используйте ephem.next_full_moon(ДАТА) + +2. убрана реализация выбора объекта класса через eval - заменено на getattr() +3. унифицировано форматирование дат при выводе сообщения пользователю +''' + +import ephem +import logging +import settings +from telegram.ext import Updater, CommandHandler, MessageHandler, Filters +from datetime import date, datetime + +logging.basicConfig(format='%(name)s - %(levelname)s - %(message)s', + level=logging.INFO, + filename='bot.log') + + +def greet_user(update, context): + text = 'Вызван /start \n введите /planet объект ДД/MM/ГГГГ,\ + или только объект, если хотите узнать про сегодня \ + или введите /next_moon (ДАТА), чтобы узнать дату следующего полнолуния' + print(text) + update.message.reply_text(text) + +# для нижеописанной функции если через date.today() то форматирование значения по умолчанию не работает в боте\ +# , решил не связываться с престановкой вызваных атрибутов в f-string при return + +def constellation (planet, user_date): + try: + planet_type = getattr(ephem, planet.capitalize()) + planet_time = planet_type(user_date) + #planet_time = eval(f'ephem.{planet.capitalize()}("{user_date}")') + #planet_time = onvertion = exec(f'ephem.{planet}("{date}")') #это почему то не работает + return f'Планета {planet.capitalize()} на дату {user_date} проходит в созвездии {ephem.constellation(planet_time)[1]}' + except (TypeError, AttributeError): + return 'Вы выбрали не зодиакальный объект' + +def user_moon(user_date): + full_moon_date = ephem.next_full_moon(user_date) + return f'Следующее полнолуние будет {full_moon_date}' + +def user_request_const(update, context): + user_text = update.message.text.split() + print(user_text) + if len(user_text) >= 3: + user_date = user_text[2] + elif len(user_text) == 2: + user_date = datetime.now().strftime('%d/%m/%y') + update.message.reply_text(constellation(user_text[1], user_date)) + +def user_request_moon(update, context): + user_text = update.message.text.split() + print(user_text) + if len(user_text) >= 2: + user_date = user_text[2] + elif len(user_text) == 1: + user_date = datetime.now().strftime('%d/%m/%y') + update.message.reply_text(user_moon(user_date)) + + + + +def main(): + mybot = Updater(settings.TOKEN_ephem, use_context=True) + + dp = mybot.dispatcher + dp.add_handler(CommandHandler("start", greet_user)) + dp.add_handler(CommandHandler("planet", user_request_const)) + dp.add_handler(CommandHandler("next_moon", user_request_moon)) + dp.add_handler(MessageHandler(Filters.text, user_request_const)) + dp.add_handler(MessageHandler(Filters.text, user_request_moon)) + + mybot.start_polling() + mybot.idle() + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/for_challenges.py b/for_challenges.py index 997754da..156ea424 100644 --- a/for_challenges.py +++ b/for_challenges.py @@ -2,7 +2,8 @@ # Необходимо вывести имена всех учеников из списка с новой строки names = ['Оля', 'Петя', 'Вася', 'Маша'] -# ??? +for person in names: + print(person) # Задание 2 @@ -12,7 +13,8 @@ # Петя: 4 names = ['Оля', 'Петя', 'Вася', 'Маша'] -# ??? +for person in names: + print(f'{person}: {len(person)}') # Задание 3 @@ -25,7 +27,9 @@ 'Маша': False, } names = ['Оля', 'Петя', 'Вася', 'Маша'] -# ??? +for person in names: + print(f'{person}: {"M" if is_male[person] else "Ж"}') + # Задание 4 @@ -40,7 +44,9 @@ ['Вася', 'Маша', 'Саша', 'Женя'], ['Оля', 'Петя', 'Гриша'], ] -# ??? +print(f'Всего {len(groups)} группы') +for i in range (len(groups)): + print(f'Группа {i+1}: {len(groups[i])} ученика') # если бы не частынй случай то нужно было делать функцию которая бы меняла окончания слов # Задание 5 @@ -54,4 +60,5 @@ ['Оля', 'Петя', 'Гриша'], ['Вася', 'Маша', 'Саша', 'Женя'], ] -# ??? \ No newline at end of file +for i in range (len(groups)): + print(f'Группа {i+1}: {", ".join(map(str, groups[i]))}') \ No newline at end of file diff --git a/for_dict_challenges.py b/for_dict_challenges.py index 96062ebc..fc6f3070 100644 --- a/for_dict_challenges.py +++ b/for_dict_challenges.py @@ -12,8 +12,15 @@ {'first_name': 'Маша'}, {'first_name': 'Петя'}, ] -# ??? - +first_name_dict = {} +for person in students: + if person['first_name'] in first_name_dict: + first_name_dict[person['first_name']] +=1 + else: + first_name_dict[person['first_name']] = 1 + +for k,v in first_name_dict.items(): + print(f'{k}: {v}') # Задание 2 # Дан список учеников, нужно вывести самое часто повторящееся имя @@ -26,8 +33,21 @@ {'first_name': 'Маша'}, {'first_name': 'Оля'}, ] -# ??? +def name_counter(students): + name_dict = {} + for person in students: + if person['first_name'] in name_dict: + name_dict[person['first_name']] +=1 + else: + name_dict[person['first_name']] = 1 + maximal = max(name_dict.values()) #чтобы не связываться с сортирокой словаря + for (k, v) in name_dict.items(): + if v == maximal: + print(k, end=' ') #печать а не return на случай если несколько имен с одинаковой встерчаемостьб, и чтобы не формирововать лишний раз список + print('\n') #возвращаем каретку в начало +print('Самое чаcтое имя: ', end='') +name_counter(students) # Задание 3 # Есть список учеников в нескольких классах, нужно вывести самое частое имя в каждом классе. @@ -51,7 +71,10 @@ {'first_name': 'Саша'}, ], ] -# ??? +for i in range(len(school_students)): + print (f'Самое распространненое имя в классе {i+1}: ', end='' ) + name_counter(school_students[i]) #использовал функцию из задачи 2 + # Задание 4 @@ -72,7 +95,18 @@ 'Миша': True, 'Даша': False, } -# ??? + +def gender_count(pupil): + genders = {'male':0, 'female':0} + for person in pupil: + if is_male.get(person['first_name']): + genders['male'] += 1 + else: + genders['female'] += 1 + return genders + +for clas in school: + print(f'Класс {clas["class"]}: девочки {gender_count(clas["students"])["female"]}, мальчики {gender_count(clas["students"])["male"]}') # Задание 5 @@ -91,5 +125,19 @@ 'Олег': True, 'Миша': True, } -# ??? + +count_dict = {} +boys, girls = 0, 0 +for clas in school: + count_dict[clas['class']] = gender_count(clas["students"]) + if count_dict[clas['class']]['male'] > boys: + boys = count_dict[clas['class']]['male'] + max_boys = clas['class'] + if count_dict[clas['class']]['female'] > girls: + girls = count_dict[clas['class']]['female'] + max_girls = clas['class'] + + +print(f'Больше всего мальчиков в классе {max_boys} \nБольше всего девочек в классе {max_girls}') + diff --git a/for_dict_challenges_bonus.py b/for_dict_challenges_bonus.py index 9f35a0a0..a5b872e2 100644 --- a/for_dict_challenges_bonus.py +++ b/for_dict_challenges_bonus.py @@ -37,6 +37,7 @@ import lorem + def generate_chat_history(): messages_amount = random.randint(200, 1000) users_ids = list( @@ -66,5 +67,91 @@ def generate_chat_history(): return messages + + +def max_count(users_dict): #здесь функция чтобы делать список элементов с максимальными значениями(на случай если не один ключ с максимальным значением) + users = [] + max_value = max(users_dict.values()) #ищем максимальное число сообщений + for (key, value) in users_dict.items(): #ищем ключт у которых одинаковое и максимальное число + if value == max_value: + users.append(key) + return " ".join(map(str, users)) + + +def user_of_max (lst): #пользователь снаибольшим количеством сообщений + users_dict = {} #создем словарь для подсчета + for mesange in lst: + users_dict[mesange['sent_by']] = users_dict.get(mesange['sent_by'], 0) + 1 + result = max_count(users_dict) + return f'Пользователь(ли) написавшие наибольшее количество сообщений: {result}' + + +def max_reply(lst): #максимально цитируемые пользоатели + reply_dict = {} + user_dict = {} + for message in lst: #словарь реплаев + if message['reply_for']: + reply_dict[message['reply_for']] = reply_dict.get(message['reply_for'], 0) + 1 + for message in lst: #еще раз проходимся по списку и сверяем id со ключами словаря реплаев + if message['id'] in reply_dict: #если сообщение потом реплаится то пользователь отправившие его добавляется в словарь + user_dict[message['sent_by']] = user_dict.get(message['sent_by'], 0) + reply_dict[message['id']] #жобавляется количесвто реплаей конкретного сообщение пользовтаелся + result = max_count(user_dict) + return f'Пользователь(ли) сообщения которого больше всего реплаили {result}' + + +def max_reply_2(lst): + rewritten_list = {} + user_dict = {} + for message in lst: + rewritten_list[message['id']] = message #перезаписываем список в словарь + intial_id = message['reply_for'] + if intial_id: + user = rewritten_list[intial_id]['sent_by'] + user_dict[user] = user_dict.get(user, 0)+1 + result = max_count(user_dict) + return f'Пользователь(ли) сообщения которого больше всего реплаили {result}' + + + +def max_seen(lst): #максимально просматриваемые пользователи + user_dict = {} + for message in lst: + user_dict[message['sent_by']] = user_dict.get(message['sent_by'], 0) + len(message['seen_by']) + result = max_count(user_dict) + return f'Наиболее просматриваемый пользователь(ли): {result}' + + +def max_time(lst): + morning, day, evening = 0, 0, 0 + for message in lst: + if message['sent_at'].hour < 12: + morning += 1 + elif 12 <= message['sent_at'].hour <=18: + day += 1 + else: + evening += 1 + return f'Больше всего сообщений в чате {"утром" if morning>day and morning>evening else "днем" if day>morning and day>evening else "вечером"}' + +count = {'deep':0} +def max_tread (lst): #првоерка глубины треда c помощью рекурсии + reply_list = [] + for message in lst: + if message['reply_for']: + id = message['reply_for'] + reply_list.append(id) + if len(reply_list) == 0: + return f'Максимальная длина треда: {count["deep"]}' + else: + count['deep'] += 1 + new_lst = [message for message in lst if message['id'] in reply_list] #создаем который содержит родительские сообщения для реплаев на этом же шаге + return max_tread(new_lst) + + if __name__ == "__main__": - print(generate_chat_history()) + message_list = generate_chat_history() + print(user_of_max(message_list)) + print(max_reply(message_list)) + print(max_reply_2(message_list)) + print(max_seen(message_list)) + print(max_time(message_list)) + print(max_tread(message_list)) \ No newline at end of file diff --git a/string_challenges.py b/string_challenges.py index 856add2d..c84d50e0 100644 --- a/string_challenges.py +++ b/string_challenges.py @@ -1,28 +1,35 @@ # Вывести последнюю букву в слове word = 'Архангельск' -# ??? +print(word[-1]) # Вывести количество букв "а" в слове word = 'Архангельск' -# ??? +print(word.lower().count('а')) # Вывести количество гласных букв в слове word = 'Архангельск' -# ??? +vowels ='аеёиоуэюыя' +count = 0 +for letter in word.lower(): + if letter in vowels: + count += 1 +print(count) # Вывести количество слов в предложении sentence = 'Мы приехали в гости' -# ??? +print(len(sentence.split())) # Вывести первую букву каждого слова на отдельной строке sentence = 'Мы приехали в гости' -# ??? +for word in sentence.split(): + print(word[0]) # Вывести усреднённую длину слова в предложении sentence = 'Мы приехали в гости' -# ??? \ No newline at end of file +sentence_1 = sentence.replace(' ', '') +print (len(sentence_1)/len(sentence.split())) \ No newline at end of file diff --git a/wordcounter_bot.py b/wordcounter_bot.py new file mode 100644 index 00000000..a222fb98 --- /dev/null +++ b/wordcounter_bot.py @@ -0,0 +1,52 @@ +''' +Реализуйте в боте команду /wordcount которая считает слова в присланной фразе. Например на запрос /wordcount Привет как дела бот должен ответить: 3 слова. Не забудьте: + +Добавить проверки на пустую строку +Как можно обмануть бота, какие еще проверки нужны? +''' +import re +import logging +import settings +from telegram.ext import Updater, CommandHandler, MessageHandler, Filters + +logging.basicConfig(format='%(name)s - %(levelname)s - %(message)s', + level=logging.INFO, + filename='bot.log') + + +def greet_user(update, context): + text = 'Введите /wordcount b напишите какую-нибудь фразу, а я посчитаю колличество слов в ней' + print(text) + update.message.reply_text(text) + +#проверки - числа, знаки препинаия, разденеие знаками препинания без пробела +def text_check (text): + pattern = r'[\d\W_]+' + new_text = re.sub(pattern, ' ', text) #далее удаляем альтернативные разделители вместо пробела + return new_text + +def user_request(update, context): + user_text = text_check(update.message.text[10:]) + print(user_text) + txt = user_text.split() + if len(txt) == 0: + update.message.reply_text('Вы ввели пустую строку') #проверка на пустую строку + else: + update.message.reply_text(f'Количсетво слов в строке: {len(txt)}') + + + +def main(): + mybot = Updater(settings.TOKEN_wordcount, use_context=True) + + dp = mybot.dispatcher + dp.add_handler(CommandHandler("start", greet_user)) + dp.add_handler(CommandHandler('wordcount', user_request)) + dp.add_handler(MessageHandler(Filters.text, user_request)) + + mybot.start_polling() + mybot.idle() + + +if __name__ == "__main__": + main() \ No newline at end of file