Last active
January 19, 2025 20:25
-
-
Save Ruthenus/c951cf4b1a990d0636cdf1bcb3961a5b to your computer and use it in GitHub Desktop.
Week 5 Homework in IT STEP Academy (string tasks)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import string | |
import re | |
import secrets | |
# Завдання на strings (бажано всі 9 задач, але вистачить 5): | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 1\n") | |
# Підрахувати середню довжину слова у введеному реченні. | |
paragraph = input("Напишіть речення або навіть цілий абзац в один рядок: ") | |
# А якщо в тексті присутні escape-послідовності? Як працює тоді input()? | |
# Цікаво працює... Овва, практика на регулярні вирази! | |
pattern = r"\\n|\\t|\\f|\\v|\\r|\\a|\\b|\\\\|\\'|\\\"" | |
modified_paragraph = re.sub(pattern, " ", paragraph) | |
# Таблиця відображення для видалення знаків пунктуації та можливих чисел, | |
# не охоплених шаблоном регулярного виразу: | |
mapping_table = str.maketrans("", "", string.digits + string.punctuation) | |
# Застосовуємо отриману таблицю відображення: | |
modified_paragraph = modified_paragraph.translate(mapping_table) | |
# Розбиваємо текст на слова, підраховуємо загальну кількість букв | |
# та середню довжину слова: | |
words = modified_paragraph.split() | |
# print(words) | |
if len(words) > 0: | |
sum_words_length = sum(len(each_word) for each_word in words) | |
avg_word_length = sum_words_length / len(words) | |
print(f"Кількість букв у слові {avg_word_length:.2f} у середньому.") | |
else: | |
print("Без слів та жадного зітхання.") | |
# І.М. Кульчицький, НУ "Львівська політехніка" | |
# Дослідження довжини речення та слова у творах Романа Іваничука | |
# https://science.lpnu.ua/sites/default/files/journal-paper/2018/jun/13011/ilovepdfcom-139-148.pdf | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 2\n") | |
# Підрахувати, скільки разів певне слово міститься в рядку тексту. | |
sentence = input("Напишіть хоч рядок тексту: ") | |
word = input("Скільки разів зустрічається слово... Яке? ") | |
# Метод count() є чутливим до регістру! | |
word_counter = sentence.casefold().count(word.casefold()) | |
print("Відповідь: " + str(word_counter) + " раз(и)(ів).") | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 3\n") | |
# Напишіть програму, яка генерує пароль вказаної довжини. | |
# https://docs.python.org/3.13/library/secrets.html#module-secrets | |
difficulty = int(input("Зазначте довжину пароля: ")) | |
alphabet = string.ascii_letters + string.digits + string.punctuation | |
# Створення пароля з принаймні однією великою літерою, принаймні однією | |
# малою літерою та принаймні однією цифрою: | |
if difficulty >= 10: | |
while True: | |
gaslo = "".join(secrets.choice(alphabet) for i in range(difficulty)) | |
if (any(a.isupper() for a in gaslo) | |
and any(a.islower() for a in gaslo) | |
and any(c.isdecimal() for c in gaslo) | |
): | |
break | |
print("Ваш надійний пароль: {}".format(gaslo)) | |
else: | |
print("Довжина пароля має бути не менше 10 символів.") | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 4\n") | |
# Визначити, яка буква в тексті зустрічається найчастіше. | |
text = input("Введіть однорядковий текст: ").casefold() | |
# Список малих українських літер: | |
abetka = ['а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'ї', | |
'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', | |
'ц', 'ч', 'ш', 'щ', 'ь', 'ю', 'я' | |
] | |
# Множини унікальних елементів, одначе, не гарантують їх порядок! | |
# Словник для підрахунку частоти букв у тексті: | |
letter_frequency = {letter: [0, 0] for letter in abetka} | |
# Перевіряємо кожен символ у тексті, оновлюємо кількість букв: | |
for symbol in text: | |
if symbol in letter_frequency.keys(): | |
letter_frequency[symbol][0] += 1 | |
# Знаходимо загальну кількість букв: | |
sum_letters = sum(values[0] for values in letter_frequency.values()) | |
# Визначаємо відносну частоту букв у тексті: | |
for letter in letter_frequency.keys(): | |
if sum_letters > 0: | |
letter_frequency[letter][1] = round( | |
(letter_frequency[letter][0] / sum_letters) * 100, 1 | |
) | |
# Пришвидшений курс Python. Практичний, проєктно-орієнтований вступ до | |
# програмування: Ерік Маттес; перекл. з англ. Ольги Бєлової. – Львів: | |
# Видавництво Старого Лева, 2021. – С. 97-120. | |
print() | |
for letter in abetka: | |
frequency = letter_frequency[letter] | |
if frequency[0] > 0: | |
print(f"\tБуква '{letter}': {frequency[0]} раз., {frequency[1]}%") | |
# Визначаємо букву, яка зустрічається в тексті найчастіше: | |
max_frequency_letter = "" | |
max_count = 0 | |
for letter, frequency in letter_frequency.items(): | |
if frequency[0] > max_count: | |
max_count = frequency[0] | |
max_frequency_letter = letter | |
if max_count > 0: | |
print(f"\nОтже, буква '{max_frequency_letter}' зустрічається найчастіше.") | |
else: | |
print("У тексті немає букв з української абетки.") | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 5\n") | |
# Написати програму, яка перевіряє коректність email, | |
# вказаного з клавіатури. | |
email = input("Введіть адресу електронної пошти: ") | |
# Широко розповсюджений регулярний вираз для валідації email: | |
pattern = r"^[a-zA-Z0-9._+-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$" | |
# За мотивами Request for Comments: 5321 @ Simple Mail Transfer Protocol | |
# https://www.rfc-editor.org/rfc/rfc5321?form=MG0AV3 | |
# Перевірка основного шаблону регулярного виразу: | |
if re.match(pattern, email): | |
# Заборонені символи | |
forbidden_chars = r"[()<>,;:[]\ ]" # ER7 якщо не змінити шаблон | |
# Спеціальні символи, дозволені у локальній частині | |
special_chars = r"[!#$%&'*+/=?^_`{|}~]" # ER7 якщо не змінити шаблон | |
if re.search(forbidden_chars, email): | |
print("\n\tER1 Адреса електронної пошти не коректна.") | |
else: | |
# Розділення на локальну та доменну частини | |
local, domain = email.rsplit("@", 1) | |
# Перевірка довжини локальної та доменної частин | |
if len(local) > 64 or len(domain) > 255: | |
print("\n\tER2 Адреса електронної пошти не коректна.") | |
# Додаткові перевірки локальної частини | |
elif ".." in local or local.startswith(".") or local.endswith("."): | |
print("\n\tER3 Адреса електронної пошти не коректна.") | |
elif re.search(special_chars, domain): | |
print("\n\tER4 Адреса електронної пошти не коректна.") | |
else: # перевірятимемо доменну частину... частинами | |
domain_parts = domain.split(".") | |
valid = True | |
# Перевірка відсутності порожніх частин | |
if "" in domain_parts: # коли дві крапки підряд | |
valid = False | |
# Додаткові перевірки кожної частини домену | |
for part in domain_parts: | |
if part.startswith("-") or part.endswith("-") or \ | |
"--" in part or len(part) < 2 or len(part) > 63: | |
valid = False | |
break | |
# Перевірка домену верхнього рівня | |
if not re.match(r"^[a-zA-Z]{2,}$", domain_parts[-1]): | |
valid = False | |
if valid: | |
print("\n\tER5 Адреса електронної пошти – коректна!") | |
else: | |
print("\n\tER6 Адреса електронної пошти не коректна.") | |
else: | |
print("\n\tER7 Адреса електронної пошти не коректна.") | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 6\n") | |
# Написати програму, яка підраховує кількість слів, а також голосних і | |
# приголосних літер у рядку, введеному користувачем. Додатково вивести | |
# кількість знаків пунктуації, цифр та інших символів. Урахувати, що | |
# між словами (а також до і після слів) може бути більше одного пробілу. | |
paragraph = input("Напишіть речення або навіть цілий абзац в один рядок: ") | |
# Видаляємо всі символи, крім літер, пробілів та апострофа: | |
# https://en.wikipedia.org/wiki/Cyrillic_script_in_Unicode | |
modified_paragraph = re.sub(r"[^a-zA-Zа-щА-ЩЄєІіЇїЬьЮюЯяҐґ'\s]", "", paragraph) | |
# Кількість слів | |
words = len(modified_paragraph.split()) | |
# print(modified_paragraph.split()) # не друкувало українські букви Іі | |
# Визначаємо кількість голосних літер: | |
ukrainian_vowels = r"[АаЕеЄєИиІіОоУуЮюЯя]" | |
english_vowels = r"[AaEeIiOoUu]" | |
vowels_pattern = f"({ukrainian_vowels}|{english_vowels})" | |
vowels = len(re.findall(vowels_pattern, paragraph)) | |
# Визначаємо кількість приголосних літер: | |
ukrainian_consonants = r"[БбВвГ㥴ДдЖжЗзКкЛлМмНнПпРрСсТтФфХхЦцЧчШшЩщ]" | |
# Я вирішив не здіймати прапор re.IGNORECASE | |
english_consonants = r"[BbCcDdFfGgHhJjKkLlMmNnPpQqRrSsTtVvXxZz]" | |
consonants_pattern = f"({ukrainian_consonants}|{english_consonants})" | |
consonants = len(re.findall(consonants_pattern, paragraph)) | |
# А також | |
either_type_letters = len(re.findall(r"[ЇїЙйЬьYyWw]", paragraph)) | |
# Підраховуємо знаки пунктуації відповідно до українського правопису: | |
# http://newpravopys.mova.info/pravopys.aspx?SectionID=4198 | |
punctuation_pattern = r"[.?!,;:—()\[\]<>/\"«»]" | |
punctuation_marks = len(re.findall(punctuation_pattern, paragraph)) | |
# Найлегше підрахувати цифри та пробіли | |
digits = len(re.findall(r"\d", paragraph)) | |
spaces = len(re.findall(r"\s", paragraph)) | |
# Загальна кількість символів | |
total_characters = len(paragraph) | |
# Решта якихось инших символів, окрім вищезазначених: | |
other_characters = total_characters - (vowels + consonants + | |
either_type_letters + | |
punctuation_marks + digits + spaces) | |
print(f"\nЗагалом символів у рядку тексту – {total_characters}, з них:") | |
print(f"\tслів — {words};") | |
print(f"\tголосних літер — {vowels};") | |
print(f"\tприголосних літер — {consonants};") | |
print(f"\tінших типів літер — {either_type_letters};") | |
print(f"\tзнаків пунктуації — {punctuation_marks};") | |
print(f"\tцифр — {digits};") | |
print(f"\tпробілів — {spaces};") | |
print(f"\tрешти символів — {other_characters}.") | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# ПОЧАТОК КОДУ ЗАДАЧІ | |
print("\tЗАВДАННЯ 7\n") | |
# Напишіть програму, яка буде друкувати ромбоподібний малюнок | |
# на основі введеного рядка (максимальна довжина – 50 символів). | |
testing = input("Напишіть рядок, який треба викласти ромбом: ") | |
length = len(testing) | |
if 1 < length <= 50: | |
print() | |
# Верхня частина ромба | |
for i in range(length): | |
print("\t" + " " * (length-i-1) + testing[:i+1]) | |
# Нижня частина ромба | |
for i in range(length-1): | |
print("\t" + testing[-length+i+1:]) | |
else: | |
print("Щира порада: довжина рядка має бути від 2 до 50 символів.") | |
print("–" * 80 + "\n") | |
# КІНЕЦЬ КОДУ ЗАДАЧІ | |
# Практика на регулярні вирази | |
# Знайти в тексті час у форматі «ЧЧ:ММ» | |
text = "25 січня схід 07:28, захід 16:50" | |
pattern = r"\b([01]?\d|2[0-3]):([0-5]\d)\b" | |
time = re.findall(pattern, text) | |
for hour, minute in time: | |
print(f"{hour}:{minute}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment