Задачи для подготовки к контрольной работе №1
Задача №1
Напишите функцию, которая принимает на вход список чисел и возвращает среднее этих чисел.
Рассуждения:
- Среднее в математике - сумма чисел делить на количество
- Если список пустой, то количество чисел - 0, а на ноль делить нельзя. Нужно это обработать.
Решение:
def avg(numbers):
if not numbers:
return 0
return sum(numbers) / len(numbers)
Задача №2
Найдите среди всех слов из частотного словаря слово, которое имеет самую близкую к средней частоте частоту.
Оформите решение в виде нескольких функций.
Частотный словарь можно скачать по ссылке
Рассуждения
- Сперва нам нужно прочитать файл с частотным словарем. Так как в задаче просят работать только со словами и их частотами, преобразуем содержимое файла в 2 списка - список слов и список частот.
- Напишем функцию, которая по списку частот вычислит среднюю частоту.
- Напишем функцию, которая вычислит индекс слова, которое имеет наиболее близкую частоту к средней.
Решение:
def read_dict(filename):
words = []
freqs = []
with open(filename, encoding='utf-8') as file:
for line in file:
word, _, freq = line.split('|')
freq = float(freq)
words.append(word)
freqs.append(freq)
return words, freqs
def avg(numbers):
if not numbers:
return 0
return sum(numbers) / len(numbers)
def find_closest(freqs, avg_freq):
index = -1
min_dist = 1000000 # это больше, чем любое значение из списка freqs
for i in range(len(freqs)):
dist = abs(freqs[i] - avg_freq)
if dist < min_dist:
index = i
min_dist = dist
return index
А вот так можно воспользоваться написанными функциями:
>>> words, freqs = read_dict('freq_dict.txt')
>>> closest = find_closest(freqs, avg(freqs))
>>> print('Word found:', words[closest], freqs[closest])
Word found: велосипед 28.34
Задача №3
Вам дан частотный словарь слов русского языка. Частотный словарь можно скачать по ссылке
Реализуйте функцию retrieve(filename, lte=None, gte=None, gender=None).
Функция должна проходить по всем строкам файла filename и отбирать те слова вместе с частотой и морфологической информацией, которые подпадают под критерии.
lte- частота слова должна быть меньше или равна значениюlte. ЕслиlteравенNone, то этот параметр фильтрации учитывать не нужно.gte- частота слова должна быть больше или равна значенияgte. Еслиgteне указан (то есть равенNone), то этот параметр фильтрации учитывать ну нужно.gender- слово должно принадлежать указанному вgenderроду. Еслиgenderне указано (то есть равноNone), то учитывать этот параметр при фильтрации не нужно.
Примеры
Если в файл содержит следующие строки:
абитуриент|сущ одуш ед муж им|1.47
абонемент|сущ неод ед муж им|1.1
абонент|сущ одуш ед муж им|3.43
абориген|сущ одуш ед муж им|10.53
аборт|сущ неод ед муж им|9.79
абразив|сущ неод ед муж им|4.35
абракадабра|сущ неод ед жен им|1.22
абрек|сущ одуш ед муж им|3.86
абрикос|сущ неод ед муж им|4.84
абрикосовый|прл ед муж им|1.53
абсолют|сущ неод ед муж им|1.35
То функция должна работать следующим образом:
# Без аргументов
retrieve(filename)
[('абитуриент', 'сущ одуш ед муж им', 1.47),
('абонемент', 'сущ неод ед муж им', 1.1),
('абонент', 'сущ одуш ед муж им', 3.43),
('абориген', 'сущ одуш ед муж им', 10.53),
('аборт', 'сущ неод ед муж им', 9.79),
('абразив', 'сущ неод ед муж им', 4.35),
('абракадабра', 'сущ неод ед жен им', 1.22),
('абрек', 'сущ одуш ед муж им', 3.86),
('абрикос', 'сущ неод ед муж им', 4.84),
('абрикосовый', 'прл ед муж им', 1.53),
('абсолют', 'сущ неод ед муж им', 1.35)]
# Только женский род
retrieve(filename, gender='жен')
[('абракадабра', 'сущ неод ед жен им', 1.22)]
# Мужской рож с частотой больше 5
retrieve(s, gender='муж', gte=5)
[('абориген', 'сущ одуш ед муж им', 10.53),
('аборт', 'сущ неод ед муж им', 9.79)]
Обратите внимание на то, что возвращает функция - это список кортежей, состоящих каждый из 3 элементов.
Решение:
def retrieve(filename, lte=None, gte=None, gender=None):
output = []
with open(filename, encoding='utf-8') as file:
for line in file:
word, morph, freq = line.split('|')
freq = float(freq)
if lte is not None and freq > lte:
continue
if gte is not None and freq < gte:
continue
if gender is not None and gender not in morph:
continue
output.append((word, morph, freq))
return output
Задача №4
Напишите функцию, которая принимает два аргумента: первый – произвольная строка, второй – опциональный (по умолчанию равен пустой строке)
Второй аргумент может принимать значения "longest", "alphanumerically_last", "same_vowels".
Если значение второго аргумента – "longest", нужно найти в строке – первом аргументе – максимальную последовательность из одинаковых букв и вернуть её.
Если значение второго аргумента – "alphanumerically_last", нужно найти в строке – первом аргументе – символ, порядковый номер которого в алфавите больше, чем у всех остальных, и вернуть его.
Если значение второго аргумента – "same_vowels", нужно проверить, есть ли в строке – первом аргументе – последовательность символов, среди которых несколько гласных, причём все гласные одинаковы. Если такая последовательность есть, нужно вернуть True, иначе – False.
Если значение второго аргумента – пустая строка, то нужно выдать в ответ тройку – результат для аргумента "longest", результат для аргумента "alphanumerically_last", результат для аргумента "same_vowels".
def longest(my_str):
if not my_str:
return ''
maximal_subseq_found = my_str[0]
for letter_pos, letter in enumerate(my_str[:-1]):
subseq = ''
for subseq_letter in my_str[letter_pos:]:
if subseq_letter == letter:
subseq += letter
else:
break
if len(subseq) > len(maximal_subseq_found):
maximal_subseq_found = subseq
return maximal_subseq_found
def alphanumerically_last(my_str):
if not my_str:
return ''
alphabet = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
for letter in my_str:
if letter.isalpha() and letter.lower() not in alphabet:
print(f"ERROR! passed string {my_str} with unknown letter {letter}")
return ''
alnum_last_letter = my_str[0]
for letter in my_str:
if not letter.isalpha():
continue
if alphabet.index(letter.lower()) > alphabet.index(alnum_last_letter.lower()):
alnum_last_letter = letter
return alnum_last_letter
def contains_same_vowels(my_str):
if not my_str:
return False
vowels = "аеёиоуыэюя"
my_str_vowels = ''
for letter in my_str:
if letter.lower() in vowels:
my_str_vowels += letter.lower()
harmonic_subsequence_present = False
for idx in range(1, len(my_str_vowels[1:])):
vowel = my_str_vowels[idx]
if my_str_vowels[idx - 1] == vowel:
harmonic_subsequence_present = True
break
return harmonic_subsequence_present
def foo(my_str, my_param=''):
if my_param == "longest":
return longest(my_str)
elif my_param == "alphanumerically_last":
return alphanumerically_last(my_str)
elif my_param == "same_vowels":
return contains_same_vowels(my_str)
elif my_param == "":
return longest(my_str), alphanumerically_last(my_str), contains_same_vowels(my_str)
print(foo("парам пам пурум"))
print(foo("парам пам пурум", "longest"))
print(foo("парам пам пурум", "alphanumerically_last"))
print(foo("парам пам пурум", "same_vowels"))
print(foo("кот ехал ехал и уехал"))
print(foo("ПЫТАЙТЕСБ ЧТОТ0 N3МЕНИТЬ!"))
print(foo(""))
Задача №5
Реализовать функции my_append, my_extend, my_remove.
my_append принимает на вход список и элемент произволной природы, возвращает список, равный исходному, продолженному переданным элементом. (Короче, то, что бы сделал аппенд этого элемента к списку) Использовать метод append и extend нельзя
my_extend принимает на вход два списка и возвращает список, полученный конкатенацией переданных. Использовать extend нельзя, за использование append штраф 1 балл.
my_remove принимает на вход список и число, i число может быть позицией любого элемента в списке. Возвращает копию исходного списка, из которой удалён i-тый элемент. Использовать стандартные методы удаления элементов из списка нельзя.
def my_append(my_li, elem):
result_li = [elem] * (len(my_li) + 1)
for my_elem_idx, my_elem in enumerate(my_li):
result_li[my_elem_idx] = my_elem
return result_li
def my_extend(my_li1, my_li2):
result_li = my_li1
for elem in my_li2:
result_li = my_append(result_li, elem)
return result_li
def my_remove(my_li, my_idx):
result_li = my_extend(my_li[:my_idx], my_li[my_idx+1:])
return result_li
print(my_append([2,3], True))
print(my_append([2], True))
print(my_append([], True))
print(my_append([], []))
print(my_extend([2,3], [4,5]))
print(my_extend([2], [3, 4,5]))
print(my_extend([], [2,3,4,5]))
print(my_extend([2,3,4,5], []))
print(my_extend([[]], [[4,5]]))
print(my_extend([], []))
print(my_remove([1,2,3,4], 0))
print(my_remove([1,2,3,4], 1))
print(my_remove([1,2,3,4], 3))
print(my_remove([1,2,3,4], 6))
print(my_remove([1,2,3,4], -8))
print(my_remove([], 1))
Задача №6
Напишите функцию, принимающую на вход имя файла (это будет имя файла с субтитрами к Рику и МОрти, скачать для тренировки можно тут ). Функция должна записать два файла – один с репликами рика, другой – с репликами морти. имена созданных файлов с объяснением, какой про что, нужно вывести на экран. За удаление одного-двух ругательств из реплик добавляется дополнительный балл.
def foo(src_filename, blacklist = ["fuck", "morning"]):
rick_fn = "rick.txt"
morty_fn = "morty.txt"
with open(src_filename, 'r', encoding="utf-8") as src_f:
rick_f = open(rick_fn, 'w', encoding="utf-8")
morty_f = open(morty_fn, 'w', encoding="utf-8")
for line in src_f:
line_masked = line
for blacklisted_word in blacklist:
line_masked = line_masked.replace(blacklisted_word,
"*" * len(blacklisted_word))
if line.startswith("rick:"):
rick_f.write(line_masked)
elif line.startswith("morty:"):
morty_f.write(line_masked)
rick_f.close()
morty_f.close()
print(f"morty replics written to {morty_fn}")
print(f"rick replics written to {rick_fn}")
# change the path to the one that fits for you
foo("all_subtitles.txt")