Шестая неделя посвящена языку Python. В практических заданиях предлагается реализовать собственные варианты кода, написанные в предыдущих занятиях на языке C. При этом необходимо сохранить индивидуальную логику построения кода. Кроме уже известных заданий, одно из них новое (Bleep), для решения которой понадобится более вдумчивое самостоятельное изучение структуры Python.
Для выполнения задач недели вам понадобится CS50 IDE. 1.Используя CS50 IDE, выполните задание Hello на Python. 2.Используя CS50 IDE, выполните одно из следующих заданий: • Mario (простой вариант) на Python. • Mario (сложный вариант) на Python. 3.Используя CS50 IDE, выполните одно из следующих заданий: • Cash на Python. • Credit на Python. 4.Используя CS50 IDE, выполните одно из следующих заданий: • Caesar на Python. • Vigenère на Python. 5.Используя CS50 IDE, выполните задание Crack на Python. 6.Используя CS50 IDE, выполните задание Bleep на Python.
Hello
Нужно создать программу, которая выводит простое приветствие пользователя:
$ python hello.py
What is your name?
John
hello, John
Реализация:
from cs50 import get_string s = get_string("What is your name?\n") print(f"hello, {s}")
Mario легкий
Условия задачи известны. Реализуем тот же алгоритм ,что и в задании из первой недели.
Важно! Используя CS50 IDE, есть возможность импортировать библиотеку cs50.
Вариант реализации на Python:
import cs50 def main(): while True: print("Height: ", end = "") height = cs50.get_int() if height >=1 and height <= 8: break for i in range(height): for j in range(height - i - 1): print(" ", end = "") for k in range(i+1): print("#", end = "") print("") if __name__ == "__main__": main()
Mario сложный
import cs50 def main(): while True: print("Height: ", end = "") height = cs50.get_int() j = height if height >=1 and height <= 8: break for i in range(1, height + 1): hashes = i spaces = j - hashes print(" " * spaces, end="") print("#" * hashes, end="") print(" ", end="") print("#" * hashes) if __name__ == "__main__": main()
Caesar
import sys from cs50 import get_string def main(): if len(sys.argv) != 2: print("Usage: ./caesar k") sys.exit(1) k = int(sys.argv[1]) plaintext = get_string("plaintext: ") print("ciphertext: ", end="") for ch in plaintext: if not ch.isalpha(): print(ch, end="") continue ascii_offset = 65 if ch.isupper() else 97 pi = ord(ch) - ascii_offset ci = (pi + k) % 26 print(chr(ci + ascii_offset), end="") print() return 0 if __name__ == "__main__": main()
Vigenere
import sys from cs50 import get_string def is_valid(k): for ch in k: if not ch.isalpha(): return False return True def main(): if len(sys.argv) != 2 or not is_valid(sys.argv[1]): print("Usage: python vigenere.py k") sys.exit(1) k = sys.argv[1] plaintext = get_string("plaintext: ") j = 0 print("ciphertext: ", end="") for ch in plaintext: if not ch.isalpha(): print(ch, end="") continue ascii_offset = 65 if ch.isupper() else 97 pi = ord(ch) - ascii_offset kj = ord(k[j % len(k)].upper()) - 65 ci = (pi + kj) % 26 j += 1 print(chr(ci + ascii_offset), end="") print() return 0 if __name__ == "__main__": main()
Cash
from cs50 import get_float from math import floor def main(): while True: dollars_owed = get_float("Change owed: ") cents_owed = floor(dollars_owed * 100) if cents_owed > 0: break quarters = cents_owed // 25 dimes = (cents_owed % 25) // 10 nickels = ((cents_owed % 25) % 10) // 5 pennies = ((cents_owed % 25) % 10) % 5 print(f"{quarters + dimes + nickels + pennies}") if __name__ == "__main__": main()
Credit
from cs50 import get_int from math import floor def main(): digit1 = 0 digit2 = 0 num_digits = 0 sum_of_double_odds = 0 sum_of_evens = 0 cc_number = get_int("Number: ") while cc_number > 0: digit2 = digit1 digit1 = cc_number % 10 if num_digits % 2 == 0: sum_of_evens += digit1 else: multiple = 2 * digit1 sum_of_double_odds += (multiple // 10) + (multiple % 10) cc_number //= 10 num_digits += 1 is_valid = (sum_of_evens + sum_of_double_odds) % 10 == 0 first_two_digits = (digit1 * 10) + digit2 if digit1 == 4 and num_digits >= 13 and num_digits <= 16 and is_valid: print("VISA\n") elif first_two_digits >= 51 and first_two_digits <= 55 and num_digits == 16 and is_valid: print("MASTERCARD\n") elif (first_two_digits == 34 or first_two_digits == 37) and num_digits == 15 and is_valid: print("AMEX\n") else: print("INVALID\n") if __name__ == "__main__": main()
Crack
Это задание необязательное, но для получения дополнительных знаний и возможности изучить алгоритмы шифрования (а тем более их реализацию на разных языках программирования), выполнить эту задачу стоит.
import sys import crypt def main(): if len(sys.argv) != 2: print("Usage: crack <hash>") sys.exit(1) ahash = sys.argv[1] salt = ahash[0:2] letters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" for fifth in letters: for fourth in letters: for third in letters: for second in letters: for first in letters[1:]: candidate = f"{first}{second}{third}{fourth}{fifth}".strip() if crypt.crypt(candidate, salt) == ahash: print(candidate) sys.exit(0) if __name__ == "__main__": main()
Bleep
Эта задача оказалось сложной, с подводными камнями. Для успешного прохождения этого этапа, нужно внимательно прочитать спецификацию к заданию и рекомендации.
Суть задания следующая:
Создайте программу, которая подвергает цензуре сообщения, содержащие слова, указанные в списке «запрещенных слов». $ Python bleep.py banned.txt What message would you like to censor? What the heck What the **** $ Python bleep.py banned.txt What message would you like to censor? gosh darn it **** **** it
Для тестирования понадобится небольшой словарик .txt.
Эта программа определяет исключительно одну функцию, main, которая вызывается для последней строки файла. В рамках main. Это огромный TODO.
Спецификация
Завершите bleep.py следующим образом:
- Примите как единственный аргумент командной строки имя (или путь к) словаря запрещенных слов (то есть текстового файла).
- Откройте и прочитайте из этого файла список сохраненных слов по одному на строку и сохраните каждое в структуре данных в Python для дальнейшего доступа. Хотя list в Python для вас сработает, еще может пригодиться set.
- Если ни один аргумент командной строки (то есть, banned.txt) не предоставлен, убедитесь, что программа завершится с кодом выхода 1 с помощью exit.
- Вы можете принять, что любой текстовый файл (!!!) в проверках команды курса будет иметь по одному слову на строку (каждая строка завершается \ n), и любые буквенные символы в этих словах написаны в нижнем регистре.
- Пригласите пользователя предоставить сообщения.
- Токенизируйте сообщение в отдельные компоненты из слов с использованием метода split для предоставленной строки. Затем итеруйте через list (список) токенов (слов), который возвращается вызовом split, проверив, есть ли совпадения по токенами, независимо от регистра, любых слов из списка запрещенных.
- Опять выведите сообщение, которое предоставил пользователь. Если в нем были запрещены слова, каждый из символов такого слова должен быть заменен на *.
- Например, gosh должно быть заменено четырьмя символами *, а fudge — пятью символами.
- Не нужно цензурировать слова, содержащие части запрещенных слов. Например, если bar — запрещено слово в данном списке, тогда ни barns, crowbar или wheelbarrow не должно цензуре.
- Вы ни в коем случае не должны поддерживать введение строк, содержащих пунктуационные знаки. Каждое слово должно быть отделено от другого только пробелом.
Так должна вести себя программа.
$ python bleep.py
Usage: python bleep.py dictionary
$ python bleep.py list1.txt list2.txt list3.txt
Usage: python bleep.py dictionary
$ python bleep.py banned.txt
What message would you like to censor?
hello world
hello world
$ python bleep.py banned.txt
What message would you like to censor?
what the heck
what the ****
$ python bleep.py banned.txt
What message would you like to censor?
gosh darn it
**** **** it
Важно! Для правильной реализации кода, необходимо сделать так, чтобы программа принимала любой текстовый файл, содержащий словарь из запрещенных слов. Поэтому не нужно привязываться к исходному banned.txt, а открывать любой словарь argv[1].
Пример реализации:
from cs50 import get_string from sys import argv while True: if len(argv) == 2: f = open(argv[1], "r") break else: print("Useage: python bleep.py dictionary") exit(1) if f.mode == 'r': contents = f.read() message = input("What message would you like to censor?\n") words = message.split(" ") for word in words: low_word = word.lower() length = len(word) if low_word in contents: print(length*"*", end=" ") else: print(word, end=" ") print()
Читайте больше по теме:
У меня с bleep были проблемы при сдаче. В выводах фигурируют какие-то кошки и собаки, хотя в исходном текстовом словаре таких слов нет. Оказывается, нужно реализовать загрузку любого словаря. Они там, видно, так и делают. Вот откуда кошки-собаки. Спасибо. Не догадался бы никогда.