Начало разработки курсового проекта
45
code_of_future/part1_basic/final_test/README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
Итоговый проект к модулю
|
||||
|
||||
Цель:
|
||||
Написать свою игру “кликер” и воспользоваться AHK для автоматизации действия в игре
|
||||
|
||||
Что нужно сделать:
|
||||
|
||||
|
||||
Создать файл kliker.py и реализовать в нем следующие функции:
|
||||
|
||||
Вывести начальное количество рублей.
|
||||
Добавить картинку png при нажатии на которую будет увеличиваться количество рублей.
|
||||
Добавить счетчик времени который будет считать время с начала запуска программы.
|
||||
Добавить кнопку “Сброс” которая будет сбрасываться счетчик и таймер времени.
|
||||
Изменить цвет окна.
|
||||
Кнопка “Сброс” внизу экрана, картинка для нажатия в центре, счетчик денег вверху, таймер с левой стороны.
|
||||
|
||||
|
||||
Создать файл mouse.ahk и реализовать в нем следующие функции:
|
||||
|
||||
Скрипт запускается и останавливается при нажатии на клавишу Numpad1.
|
||||
Реализовать клик мышки при включении скрипта, мышь будет кликать до повторного нажатия Numpad1.
|
||||
|
||||
|
||||
Результат:
|
||||
|
||||
Рабочий кликер с автоматическим нажатием кнопки.
|
||||
|
||||
|
||||
|
||||
Советы и рекомендации по выполнению дз:
|
||||
Для выполнения задания, используйте полученные знания и навыки из предыдущих уроков.
|
||||
|
||||
|
||||
Критерии оценивания:
|
||||
|
||||
К1 - Проект создан и запускается
|
||||
|
||||
К2 - Проект создан и не полностью выполняется хотя бы одна задача из поставленных
|
||||
|
||||
К3 - Проект создан и выполняется одна задача из поставленных, без ошибок и сбоев
|
||||
|
||||
К4 - Проект создан и выполняется большая часть задач из поставленных, с небольшими ошибкам
|
||||
|
||||
К5 - Проект создан и выполняются все задач из поставленных, без сбоев и ошибок
|
182
code_of_future/part1_basic/final_test/app.py
Normal file
@@ -0,0 +1,182 @@
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
from subprocess import Popen
|
||||
from tkinter import (
|
||||
BOTH,
|
||||
LEFT,
|
||||
RAISED,
|
||||
RIGHT,
|
||||
TOP,
|
||||
Button,
|
||||
Frame,
|
||||
Label,
|
||||
PhotoImage,
|
||||
StringVar,
|
||||
Tk,
|
||||
mainloop,
|
||||
messagebox,
|
||||
)
|
||||
|
||||
|
||||
class ClickerGame:
|
||||
"""Перед запуском проверьте и исправьте место установки AHK
|
||||
Св-во класса AHK_PATH должно содержать полный путь до запускаемого файла,
|
||||
если приложение установлено не в папки по умолчанию
|
||||
"""
|
||||
|
||||
AHK_PATH = "<Введите сюда путь до приложения AutoHotKey>"
|
||||
|
||||
def __init__(self):
|
||||
# Поиск места установки AutoHotKey
|
||||
self.is_ahk_path_set = False
|
||||
if os.path.isfile(
|
||||
app_exe := os.path.join(
|
||||
Path.home(),
|
||||
"AppData",
|
||||
"Local",
|
||||
"Programs",
|
||||
"AutoHotkey",
|
||||
"UX",
|
||||
"AutoHotkeyUX.exe",
|
||||
)
|
||||
):
|
||||
self.AHK_PATH = app_exe
|
||||
self.is_ahk_path_set = True
|
||||
elif os.path.isfile(
|
||||
app_exe := os.path.join(
|
||||
r"c:\\", "Program Files", "AutoHotkey", "UX", "AutoHotkeyUX.exe"
|
||||
)
|
||||
):
|
||||
self.AHK_PATH = app_exe
|
||||
self.is_ahk_path_set = True
|
||||
else:
|
||||
messagebox.showerror(
|
||||
"Can't find AutoHotKey",
|
||||
"""Пропишите AHK_PATH До этого, автокликер работать не будет""",
|
||||
)
|
||||
|
||||
self.__root = Tk()
|
||||
self.__root.geometry("500x400")
|
||||
self.__root.minsize(500, 400)
|
||||
self.__root.title("Clicker Game")
|
||||
self.__root.bind("<Key>", self.key)
|
||||
|
||||
self.process = None
|
||||
|
||||
self.ahk_flag = False # Флаг запущен ли скрипт кликера
|
||||
self.frame = Frame(self.__root, relief=RAISED, borderwidth=5, bg="green")
|
||||
self.frame.pack(fill=BOTH, expand=True, padx=5, pady=5)
|
||||
self.label = Label(
|
||||
self.frame, text="Clicker Game", font=("Arial", 25), bg="green"
|
||||
)
|
||||
self.label.pack(side=TOP)
|
||||
|
||||
self.score = 0
|
||||
self.message = StringVar()
|
||||
self.message.set(f"Ваш счет: {self.score}")
|
||||
self.label2 = Label(
|
||||
self.frame, textvariable=self.message, font=("Arial", 15), bg="green"
|
||||
)
|
||||
self.label2.pack(side=TOP)
|
||||
|
||||
self.timer = 0
|
||||
self.start_time = time.time()
|
||||
self.timer_message = StringVar()
|
||||
self.timer_update()
|
||||
|
||||
self.label3 = Label(
|
||||
self.frame, textvariable=self.timer_message, font=("Arial", 12), bg="green"
|
||||
)
|
||||
self.label3.pack(side=LEFT)
|
||||
|
||||
self.img = PhotoImage(file=os.path.join(os.curdir, "img.png"))
|
||||
self.clicker = Button(
|
||||
self.frame, text="clickme", image=self.img, command=self.increment
|
||||
)
|
||||
self.clicker.place(relx=0.5, rely=0.5, anchor="center")
|
||||
|
||||
self.ahk_button = Button(
|
||||
self.__root, text="Запустить AHK", command=self.switcher_ahk
|
||||
)
|
||||
self.ahk_button.pack(side=LEFT, padx=10, pady=10)
|
||||
|
||||
self.close_button = Button(self.__root, text="Выход", command=self.quit)
|
||||
self.close_button.pack(side=RIGHT, padx=10, pady=10)
|
||||
|
||||
self.ahk_button = Button(
|
||||
self.__root, text="Сброс игры", command=self.clicker_reset
|
||||
)
|
||||
self.ahk_button.pack(side=RIGHT, padx=10, pady=10)
|
||||
|
||||
mainloop()
|
||||
|
||||
def __del__(self):
|
||||
"""Завершаем поток АНК ели он запущен при
|
||||
уничтожении игры.
|
||||
Можно было и в метод quit разместить, но
|
||||
правильнее добавить деструктор обекта"""
|
||||
if self.ahk_flag:
|
||||
self.switcher_ahk()
|
||||
|
||||
def key(self, event):
|
||||
"""Отлавливаем все event в игре, в т.ч и
|
||||
нажатия клавиш клавиатуры. Обрабатываем
|
||||
интересующие нас"""
|
||||
if event.keycode == 97:
|
||||
# Переключаем статус АНК по numpad1
|
||||
self.switcher_ahk()
|
||||
|
||||
if event.keycode == 73 or event.keycode == 17:
|
||||
# Инкремент счетчика по хот кею Ctrl-i или Ctrl-ш в RU раскладке
|
||||
self.increment()
|
||||
|
||||
def increment(self, keys=None):
|
||||
if keys is not None:
|
||||
"""Данный блок необходим, чтоб среда не ругалась на неиспользуемый
|
||||
аргумент keys. При связывании горячей клавиши методом bind, сюда
|
||||
передается инфо о нажатой комбинации. Тут она мне не нужна, поэтому
|
||||
ставим тупо заглушку"""
|
||||
pass
|
||||
|
||||
self.score += 1
|
||||
self.message.set(f"Ваш счет: {self.score}")
|
||||
|
||||
def switcher_ahk(self):
|
||||
"""Переключаем состояние кликера(вкл/выкл),
|
||||
если путь к нему установлен или выводим
|
||||
сообщение с предупреждением"""
|
||||
if not self.is_ahk_path_set:
|
||||
messagebox.showerror(
|
||||
"Can't find AutoHotKey",
|
||||
"""Не могу запустить автокликер. Не указан путь к AutoHotKey""",
|
||||
)
|
||||
elif self.ahk_flag:
|
||||
self.ahk_flag = False
|
||||
self.process.kill()
|
||||
else:
|
||||
self.ahk_flag = True
|
||||
self.process = Popen([self.AHK_PATH, "clicker.ahk"])
|
||||
|
||||
def timer_update(self):
|
||||
self.timer = int(time.time() - self.start_time)
|
||||
self.timer_message.set(
|
||||
f"Время игры:\n{self.timer // 60}мин. {self.timer % 60} сек."
|
||||
)
|
||||
self.__root.after(1000, self.timer_update)
|
||||
|
||||
def clicker_reset(self):
|
||||
if self.ahk_flag:
|
||||
self.switcher_ahk()
|
||||
self.score = 0
|
||||
self.message.set(f"Ваш счет: {self.score}")
|
||||
self.timer = 0
|
||||
self.start_time = time.time()
|
||||
self.timer_update()
|
||||
|
||||
def quit(self):
|
||||
self.__root.destroy()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = ClickerGame()
|
10
code_of_future/part1_basic/final_test/clicker.ahk
Normal file
@@ -0,0 +1,10 @@
|
||||
#Requires AutoHotkey v2.0
|
||||
|
||||
SetTimer Click, 200
|
||||
|
||||
Click()
|
||||
{
|
||||
if WinExist("Clicker Game")
|
||||
WinActivate ;
|
||||
Send "^i"
|
||||
}
|
BIN
code_of_future/part1_basic/final_test/img.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
35
code_of_future/part1_basic/lesson1/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
В качестве ДЗ предоставлена задача:
|
||||
|
||||
1. Создайте новый файл с расширением ".py" и назовите его "my_first_program".
|
||||
2. Напишите программу, которая выводит на экран приветствие и Ваше ФИО.
|
||||
3. Используйте F- строки для вывода информации.
|
||||
4. Добавьте комментарии в коде объясняющие ход работы программы.
|
||||
5. Выведите несколько человек.
|
||||
6. Добавьте город проживания.
|
||||
|
||||
|
||||
Критерии оценки:
|
||||
|
||||
1 балл - программа называется неправильно,
|
||||
вся информация выведена через print,
|
||||
без использования переменных и F-строк и комментариев.
|
||||
|
||||
2 балла - Программа называется как в задании,
|
||||
вся информация выведена через print,
|
||||
без использования переменных и F-строк.
|
||||
|
||||
3 балла - Программа называется как в задании,
|
||||
созданы переменные имени и возраста,
|
||||
переменные вставлены в вывод но без использования F-строк.
|
||||
|
||||
4 балла - Программа называется как в задании,
|
||||
созданы переменные имени и возраста,
|
||||
переменные вставлены в вывод с использованием F-строк.
|
||||
|
||||
5 баллов - Программа называется как в задании, созданы переменные имени и возраста, переменные вставлены в вывод с использованием F-строк.
|
||||
Добавлены однострочные комментарии объясняющие работу кода.
|
||||
Код оформлен красиво и четко.
|
||||
|
||||
Решение задачи оформлено в файле my_first_program.py
|
||||
|
||||
|
27
code_of_future/part1_basic/lesson1/my_first_program.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме
|
||||
"Введение в особенности программирования на языке Python"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
my_name = "Сергей Николаевич" # Создаем переменную
|
||||
my_age = 39 # еще какой-то бесполезный коментарий
|
||||
my_city = "Нарьян-Мар"
|
||||
|
||||
# Отделим строки кода пустыми строками для удобства чтения кода.
|
||||
his_name, his_age, his_city = "Васек 35 Зачаханск".split()
|
||||
her_name, her_age, her_city = "Сонька", 18, "Золоторуческ"
|
||||
|
||||
# как бы печатаем строчки
|
||||
print(f"Здрасте), Меня зовут {my_name}. Мне {my_age}лет")
|
||||
print(f"Я живу в {my_city}е\n")
|
||||
|
||||
print(f"Bonjour, je m'appelle {his_name}.", end=" ")
|
||||
print(f"Je traîne à {his_city} depuis {his_age} ans\n")
|
||||
|
||||
print(f"Менің атым {her_name}, мен {her_age} жастамын. Мен {her_city}іде тұрамын")
|
66
code_of_future/part1_basic/lesson10/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
Задание:
|
||||
|
||||
|
||||
Написать приложение пайтон, используя библиотеку Tkinter, которое будет выводить одно из рандомных определений из пайтона. К примеру (While - это ... ) и т.д. Сделайте дизайн приложения (к примеру- сделайте заголовок внутри окна). Измените цвет окна.
|
||||
|
||||
Давайте разберем его по шагам:
|
||||
|
||||
|
||||
Импорт библиотек.
|
||||
|
||||
В этом блоке импортируются библиотеки. tkinter используется для создания GUI-приложения, а random используется для выбора случайных определений.
|
||||
|
||||
|
||||
Определения Python:
|
||||
|
||||
definitions = {
|
||||
|
||||
"While": "Цикл 'while' используется для выполнения блока кода, пока условие истинно.",
|
||||
|
||||
"For": "Цикл 'for' используется для итерации по элементам последовательности (например, списку или строке).",
|
||||
|
||||
"If": "Условие 'if' позволяет выполнить определенный блок кода, если условие истинно.",
|
||||
|
||||
"Function": "Функция - это блок кода, который можно вызывать с определенными аргументами.",
|
||||
|
||||
"List": "Список - это упорядоченная коллекция элементов, которая может содержать разные типы данных."
|
||||
|
||||
}
|
||||
|
||||
|
||||
Функция show_random_definition():
|
||||
|
||||
Эта функция выбирает случайный ключ из словаря definitions, затем очищает текстовое поле definition_text и вставляет в него выбранное определение.
|
||||
|
||||
|
||||
Создание главного окна:
|
||||
|
||||
Этот блок создает главное окно приложения с заголовком "Определения Python".
|
||||
|
||||
|
||||
Изменим цвет фона окна на бирюзовый
|
||||
|
||||
root.configure(bg="#00FFFF")
|
||||
|
||||
|
||||
Создание заголовка.
|
||||
|
||||
Title label - в котором указывает заголовок окна.
|
||||
|
||||
|
||||
Создание текстового поля для определений:
|
||||
|
||||
Это текстовое поле, в котором будут отображаться определения.
|
||||
|
||||
|
||||
Создание кнопки "Показать определение":
|
||||
|
||||
Создается кнопка с названием "Показать определение", и ей назначается функция show_random_definition() для выполнения при нажатии на кнопку.
|
||||
|
||||
|
||||
Запуск главного цикла приложения:
|
||||
|
||||
Этот код запускает главный цикл приложения, который ожидает взаимодействия пользователя с GUI.
|
||||
|
||||
|
||||
Когда пользователь нажимает кнопку "Показать определение", случайное определение из словаря definitions отображается в текстовом поле при помощи функции show_random_definition().
|
65
code_of_future/part1_basic/lesson10/app.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "tkinter num2"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
from tkinter import *
|
||||
|
||||
|
||||
class PyZen:
|
||||
def __init__(self):
|
||||
self.__root = Tk()
|
||||
self.__root.title = "Определения Python"
|
||||
self.__root.configure(bg="#00FFFF")
|
||||
self.gen_zen()
|
||||
|
||||
self.label = Label(self.__root, text="Дзен Python")
|
||||
self.text = Text(self.__root, wrap=WORD)
|
||||
self.set_text()
|
||||
|
||||
self.btn_get = Button(
|
||||
self.__root, text="Получить мудрость старейшин", command=self.get_shit
|
||||
)
|
||||
self.btn_exit = Button(self.__root, text="Выйти", command=self.exit)
|
||||
|
||||
self.label.pack(padx=20, pady=20)
|
||||
self.text.pack(padx=20, pady=20)
|
||||
self.btn_get.pack()
|
||||
self.btn_exit.pack()
|
||||
mainloop()
|
||||
|
||||
def gen_zen(self):
|
||||
import contextlib
|
||||
import io
|
||||
|
||||
with contextlib.redirect_stdout(echo := io.StringIO()):
|
||||
import this
|
||||
|
||||
self.zen = (echo.getvalue()).split("\n")
|
||||
|
||||
def set_text(self, text=None):
|
||||
self.text.delete("1.0", END)
|
||||
if text is None:
|
||||
self.text.insert("1.0", "Познаватель Дзена\n")
|
||||
self.text.insert("2.0", "Нажмите кнопку и получите мудрость")
|
||||
else:
|
||||
self.text.insert("1.0", "Мудрость дня:\n")
|
||||
self.text.insert("2.0", "\n")
|
||||
self.text.insert("3.0", text + "\n\n")
|
||||
self.text.insert("5.0", "\u00a9" + self.zen[0])
|
||||
|
||||
def get_shit(self):
|
||||
import random
|
||||
|
||||
self.set_text(random.choice(self.zen[2:-1]))
|
||||
|
||||
def exit(self):
|
||||
self.__root.destroy()
|
||||
|
||||
|
||||
app = PyZen()
|
11
code_of_future/part1_basic/lesson2/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
Дз 2. Знакомство с переменными и базовыми функциями
|
||||
Создайте программу-калькулятор, которая будет выполнять простые математические операции: сложение, вычитание. Программа должна предложить пользователю выбрать операцию, затем ввести два числа и вывести результат операции.
|
||||
Шаги:
|
||||
Поприветствуйте пользователя и покажите список доступных операций: "+", "-"
|
||||
Попросите пользователя выбрать операцию, введя соответствующий символ.
|
||||
Затем попросите пользователя ввести первое число.
|
||||
Затем попросите пользователя ввести второе число.
|
||||
Выполните выбранную операцию над введенными числами.
|
||||
Выведите результат пользователю.
|
||||
Добавьте умножение.
|
||||
Добавьте деление.
|
79
code_of_future/part1_basic/lesson2/calculator.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме
|
||||
"Знакомство с переменными и базовые функции"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
from decimal import Decimal, DecimalException, DivisionByZero
|
||||
|
||||
MATH_SYMBOLS = ("+", "-", "*", "/")
|
||||
|
||||
|
||||
def get_num_from_str(string: str) -> int | Decimal | None:
|
||||
"""Функция валидации и преобразования строки в число.
|
||||
Проверяет коректность строки и определяет тип
|
||||
для преобразования строки в числовой тип.
|
||||
|
||||
Параметры:
|
||||
<string> - Число в строковом представлении
|
||||
|
||||
Возвращаемые значения:
|
||||
- num: int Вернет число типа int, если строка может быть
|
||||
преобразована в целое число
|
||||
- num: Decimal Если в строке есть точка или запятая
|
||||
- None Если строку нельзя преобразовать в число
|
||||
"""
|
||||
|
||||
string = string.replace(",", ".")
|
||||
try:
|
||||
num = int(string)
|
||||
return num
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
try:
|
||||
num = Decimal(string)
|
||||
return num
|
||||
except DecimalException:
|
||||
pass
|
||||
|
||||
return
|
||||
|
||||
|
||||
print("Привет, Пользователь. Это простой калькулятор")
|
||||
print("Вам доступны операции: ", *MATH_SYMBOLS)
|
||||
|
||||
symbol = input("Введите операцию: ")
|
||||
|
||||
while symbol not in MATH_SYMBOLS:
|
||||
symbol = input("Ошибка, введите коректную операцию: ")
|
||||
|
||||
while True:
|
||||
num1 = get_num_from_str(input("Введите первое число:\n"))
|
||||
if num1 is not None:
|
||||
break
|
||||
print("Ошибка ввода!\n")
|
||||
|
||||
while True:
|
||||
num2 = get_num_from_str(input("Введите второе число:\n"))
|
||||
if num2 is not None:
|
||||
break
|
||||
print("Ошибка ввода!\n")
|
||||
|
||||
match symbol:
|
||||
case "+":
|
||||
print("Сумма равна:", num1 + num2)
|
||||
case "-":
|
||||
print("Разница равна:", num1 - num2)
|
||||
case "*":
|
||||
print("Произведение равно:", num1 * num2)
|
||||
case "/":
|
||||
try:
|
||||
print("Частное равно", num1 / num2)
|
||||
except (DivisionByZero, ZeroDivisionError):
|
||||
print("Are you crazy, dumbass?\nDivision by Zero, E_P_T")
|
6
code_of_future/part1_basic/lesson3/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Напишите программу для кинотеатра.
|
||||
Пользователь вводит возраст, город, имя и
|
||||
наличие сопровождающего.
|
||||
Если возраст меньше 12 лет, программа выводит "Билет бесплатный".
|
||||
Если возраст от 12 до 18 лет и есть сопровождающий, программа выводит "Билет со скидкой".
|
||||
Во всех остальных случаях программа выводит "Полная стоимость билета".
|
101
code_of_future/part1_basic/lesson3/cinema.py
Normal file
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме
|
||||
"Логические и условные операторы"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def cls():
|
||||
os.system("cls" if os.name == "nt" else "clear")
|
||||
|
||||
|
||||
def get_ticket(**kwargs) -> str:
|
||||
rates = {
|
||||
0: "Полная стоимость билета",
|
||||
1: "Билет со скидкой",
|
||||
2: "Бесплатный билет",
|
||||
}
|
||||
rate = 0
|
||||
if kwargs.get("age") in range(0, 12):
|
||||
rate = 2
|
||||
elif kwargs.get("age") in range(12, 18) and kwargs.get("escort", False):
|
||||
rate = 1
|
||||
|
||||
return rates.get(rate, "Error")
|
||||
|
||||
|
||||
def add_buyer():
|
||||
cls()
|
||||
|
||||
print("#" * 25)
|
||||
print("#".ljust(23), "#")
|
||||
print("#", "\033[32m{}\033[0m ".format("Купить билет в кино").center(21), "#")
|
||||
print("#".ljust(23), "#")
|
||||
print("#" * 25)
|
||||
|
||||
name = input("Ваше имя?: ")
|
||||
city = input("Ваш город?: ")
|
||||
|
||||
try:
|
||||
age = int(input("Сколько вам полных лет?: "))
|
||||
if age not in range(0, 150):
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
print("Введен некорректный возраст. ")
|
||||
age = -1
|
||||
|
||||
if age <= 12:
|
||||
escort = True
|
||||
elif age < 18:
|
||||
escort = (
|
||||
True
|
||||
if input("Вы с сопровождающим? (Да/Нет): ") in ("д", "Д", "Да", "да")
|
||||
else False
|
||||
)
|
||||
else:
|
||||
escort = False
|
||||
|
||||
cls()
|
||||
print("#" * 30)
|
||||
for i in range(11):
|
||||
if i in (1, 3, 5, 7, 9):
|
||||
print("#".ljust(28), "#")
|
||||
if i == 0:
|
||||
print("#", "Билет".center(26), "#")
|
||||
if i == 2:
|
||||
print("#", name.ljust(26), "#")
|
||||
if i == 4:
|
||||
print("#", city.ljust(26), "#")
|
||||
if i == 6:
|
||||
print("#", ("Возраст: " + str(age)).ljust(26), "#")
|
||||
if i == 8:
|
||||
print(
|
||||
"#",
|
||||
("С сопровождающим" if escort else "Без сопровождения").ljust(26),
|
||||
"#",
|
||||
)
|
||||
|
||||
if i == 10:
|
||||
print(
|
||||
"#",
|
||||
get_ticket(name=name, city=city, age=age, escort=escort).center(26),
|
||||
"#",
|
||||
)
|
||||
print("#" * 30)
|
||||
|
||||
|
||||
add_buyer()
|
||||
|
||||
while True:
|
||||
if input("Купить еще билет? (Да/Нет): ") in ("д", "Д", "Да", "да"):
|
||||
add_buyer()
|
||||
else:
|
||||
break
|
12
code_of_future/part1_basic/lesson4/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
Напишите программу, которая запрашивает у пользователя его возраст
|
||||
и выводит сообщение "Вы совершеннолетний(я)" или "Вы несовершеннолетний(я)",
|
||||
в зависимости от значения возраста (18 и больше - совершеннолетие).
|
||||
|
||||
Напишите программу, которая запрашивает у пользователя два числа и
|
||||
выводит сообщение "Первое число больше второго", "Второе число больше первого"
|
||||
или "Оба числа равны", в зависимости от значений введенных чисел.
|
||||
|
||||
Напишите программу, которая запрашивает у пользователя его имя
|
||||
и выводит сообщение "Привет, [имя]!", если пользователь ввел имя,
|
||||
или сообщение "Вы не ввели имя.", если пользователь не ввел имя.
|
||||
|
29
code_of_future/part1_basic/lesson4/app.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме
|
||||
"Знакомство с условными конструкциями"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
# 1. Давайте не буду обрабатывать исключения с некорректными
|
||||
# введенными данными, а просто сделаю так и не буду усложнять:
|
||||
print(
|
||||
"Вы {}совершеннолетний".format(
|
||||
"не" if int(input("Ваш возраст: ")) in range(0, 18) else ""
|
||||
)
|
||||
)
|
||||
|
||||
# 2. Вывод немного не по тз, но проще(по моему)
|
||||
num1, num2 = map(int, input("Введите два числа через пробел: ").split())
|
||||
if num1 == num2:
|
||||
print("Оба числа равны")
|
||||
else:
|
||||
print("Первое число {} второго".format("больше" if num1 > num2 else "меньше"))
|
||||
|
||||
# 3.
|
||||
name = input("Введите ваше имя: ")
|
||||
print(f"Привет, {name}!" if name else "Вы не ввели имя🤨!")
|
26
code_of_future/part1_basic/lesson5/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
Задание 1: Работа с списками и срезами
|
||||
|
||||
Создайте список из 10 элементов с разными типами данных
|
||||
(строки, числа и булевы значения) и выведите его на экран.
|
||||
|
||||
Используя срезы, выведите на экран первые 5 элементов списка,
|
||||
последние 3 элемента списка и каждый второй элемент списка.
|
||||
|
||||
Измените 3 элемент списка на новое значение и выведите
|
||||
измененный список на экран.
|
||||
|
||||
|
||||
Задание 2: Работа с условиями и циклами
|
||||
Напишите программу, которая запрашивает у пользователя число.
|
||||
Проверьте, является ли это число четным или нечетным, и
|
||||
выведите соответствующее сообщение.
|
||||
|
||||
Попросите пользователя ввести число с клавиатуры.
|
||||
Если число делится на 3 без остатка, выведите сообщение
|
||||
"Число делится на 3".
|
||||
Если число больше 10, выведите сообщение "Число больше 10".
|
||||
Если число не удовлетворяет ни одному из условий,
|
||||
выведите сообщение "Число не соответствует условиям".
|
||||
|
||||
|
||||
|
65
code_of_future/part1_basic/lesson5/app.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Списки"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
print("ЧАСТЬ 1")
|
||||
some_list = [
|
||||
"abcd",
|
||||
True,
|
||||
42,
|
||||
"абвг",
|
||||
False,
|
||||
(1, 2, "Ноль"),
|
||||
"какое то слово",
|
||||
{1, 4, 6},
|
||||
{"a": None, "b": "Не None а str"},
|
||||
"не знаю что писать, пусть будет строка)",
|
||||
]
|
||||
|
||||
print(" список ".center(30, "#"))
|
||||
print("Печатаю созданный список поэлементно:")
|
||||
for el in some_list:
|
||||
print(el, "тип: ", type(el))
|
||||
|
||||
print()
|
||||
print(" срезы ".center(30, "#"))
|
||||
print("первые 5: ")
|
||||
print(some_list[:5])
|
||||
|
||||
print("последние 3:")
|
||||
print(some_list[-3:])
|
||||
|
||||
print("каждый 2ой:")
|
||||
print(some_list[1::2])
|
||||
|
||||
print()
|
||||
print(" замена 3го ".center(30, "#"))
|
||||
some_list[2] = "Заменен"
|
||||
print(*some_list, sep="\n")
|
||||
print()
|
||||
|
||||
print("ЧАСТЬ 2")
|
||||
print(" числа ".center(30, "#"))
|
||||
print(
|
||||
"Четное"
|
||||
if int(input("Проверка четности\nВведите число: ")) % 2 == 0
|
||||
else "нечетное"
|
||||
)
|
||||
print()
|
||||
|
||||
num = int(input("Проверка по условию\nВведите число:"))
|
||||
flag = True
|
||||
if num % 3 == 0:
|
||||
print("Делиться на 3")
|
||||
flag = False
|
||||
if num > 10:
|
||||
print("Больше 10")
|
||||
flag = False
|
||||
if flag:
|
||||
print("Число не соответствует условиям")
|
9
code_of_future/part1_basic/lesson6/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Задание. Код с использованием for:
|
||||
|
||||
Программа запрашивает у пользователя некоторое целое число, после чего использует цикл for, чтобы вывести на экран все числа от 0 до введенного числа включительно. Функция range(n + 1) возвращает последовательность чисел от 0 до n включительно. Значение i поочередно принимает каждое из чисел этой последовательности, и для каждого из них выполняется команда print(i).
|
||||
|
||||
|
||||
2 Задание. Код с использованием while:
|
||||
|
||||
Программа делает то же самое, что и предыдущая, но использует цикл while вместо цикла for. Переменная i инициализируется значением 0, а затем на каждой итерации цикла проверяется условие i <= n. Если оно выполнено, то на экран выводится текущее значение переменной i, после чего значение i увеличивается на 1. Цикл продолжается, пока i не станет больше n.
|
||||
|
44
code_of_future/part1_basic/lesson6/app.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Циклы"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
num = input("Введите число: ")
|
||||
try:
|
||||
num = int(num)
|
||||
except ValueError:
|
||||
print("Sorry, только целые числа принимаем")
|
||||
exit()
|
||||
|
||||
if num == 0:
|
||||
print("Ввели 0, циклу некуда шагать...")
|
||||
else:
|
||||
step = -1 if num < 0 else 1
|
||||
skip = False
|
||||
|
||||
print('Генерация с помощью "for"')
|
||||
for i in range(0, num + step, step):
|
||||
if abs(i) < 3 or abs(i) > abs(num + step) - 4:
|
||||
print(i)
|
||||
else:
|
||||
if not skip:
|
||||
skip = True
|
||||
print("Пропускаю строки")
|
||||
|
||||
print()
|
||||
print("Генерация с помощью while")
|
||||
idx = 0
|
||||
skip = False
|
||||
while abs(idx) <= abs(num):
|
||||
if abs(idx) < 3 or abs(idx) > abs(num + step) - 4:
|
||||
print(idx)
|
||||
else:
|
||||
if not skip:
|
||||
skip = True
|
||||
print("Пропускаю строки")
|
||||
idx += step
|
36
code_of_future/part1_basic/lesson7/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
Задание 1: Операции с кортежами
|
||||
|
||||
|
||||
Условие: Создайте кортеж, содержащий три целых числа. Выведите на экран каждое число, а затем выведите их сумму.
|
||||
|
||||
|
||||
Пример вывода:
|
||||
|
||||
|
||||
Кортеж: (2, 4, 6)
|
||||
|
||||
Первое число: 2
|
||||
|
||||
Второе число: 4
|
||||
|
||||
Третье число: 6
|
||||
|
||||
Сумма: 12
|
||||
|
||||
|
||||
|
||||
Задание 2: Работа со списками и множествами
|
||||
|
||||
|
||||
Условие: Вводятся два списка чисел, числа вводятся вручную. Выведите, сколько чисел содержится одновременно как в первом списке, так и во втором.
|
||||
|
||||
|
||||
Пример вывода:
|
||||
|
||||
Введите первый список: 1 2 6 7
|
||||
|
||||
Введите второй список: 2 7 5 9
|
||||
|
||||
Количество пересечений: 2
|
||||
|
||||
|
27
code_of_future/part1_basic/lesson7/app.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Структуры данных"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
|
||||
from random import randint as r
|
||||
|
||||
some_tuple = tuple(r(1, 10) for _ in range(3))
|
||||
|
||||
print("Кортеж:", some_tuple)
|
||||
for i in range(len(some_tuple)):
|
||||
print(f"{i + 1}ый элемент:", some_tuple[i])
|
||||
print("Сумма: ", sum(some_tuple))
|
||||
|
||||
print()
|
||||
|
||||
first_list = list(r(1, 10) for _ in range(5))
|
||||
second_list = list(r(1, 10) for _ in range(5))
|
||||
print("Сгенерированные списки:")
|
||||
print(first_list, second_list, sep="\n")
|
||||
print("Количество пересечений: ", len(set(first_list) & set(second_list)))
|
25
code_of_future/part1_basic/lesson8/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
Задание: Создание словаря и операции с ним
|
||||
|
||||
|
||||
Создайте пустой словарь с именем my_dict.
|
||||
|
||||
Добавьте в словарь my_dict следующие элементы:
|
||||
|
||||
Ключ "name" с соответствующим значением "John".
|
||||
|
||||
Ключ "age" с соответствующим значением 25.
|
||||
|
||||
Ключ "city" с соответствующим значением "New York".
|
||||
|
||||
|
||||
Выведите на экран содержимое словаря my_dict.
|
||||
|
||||
Измените возраст в словаре my_dict на 26.
|
||||
|
||||
Добавьте ключ "email" со значением "john@example.com" в словарь my_dict.
|
||||
|
||||
Проверьте, есть ли ключ "country" в словаре my_dict, и выведите соответствующее сообщение.
|
||||
|
||||
Удалите ключ "city" из словаря my_dict.
|
||||
|
||||
Выведите на экран все ключи и значения из словаря my_dict в следующем формате:
|
20
code_of_future/part1_basic/lesson8/app.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Словари и функции"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
my_dict = {"name": "John", "age": 25, "city": "New York"}
|
||||
|
||||
print(my_dict)
|
||||
my_dict["age"] = 26
|
||||
my_dict["email"] = "john@example.com"
|
||||
print(my_dict.get("country", "Нет в словаре ключа 'country'"))
|
||||
my_dict.pop("city")
|
||||
|
||||
for k, v in my_dict.items():
|
||||
print("ключ:", k, "значение:", v)
|
24
code_of_future/part1_basic/lesson9/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
Задание:
|
||||
|
||||
|
||||
Импортируйте библиотеку Tkinter в вашем Python-скрипте.
|
||||
|
||||
|
||||
Создайте основное окно приложения.
|
||||
|
||||
|
||||
Добавьте виджет Entry (поле для ввода текста) в основное окно.
|
||||
|
||||
|
||||
Создайте кнопку (Button), которая будет запускать функцию при нажатии.
|
||||
|
||||
|
||||
Создайте функцию, которая будет вызываться при нажатии кнопки и будет отображать введенный пользователем текст в новом окне или под полем для ввода.
|
||||
|
||||
|
||||
Добавьте кнопку которая будет очищать поле ввода.
|
||||
|
||||
|
||||
Добавьте проверку, чтобы при попытке запустить с пустым полем выводилось сообщение что поле пустое.
|
||||
|
||||
|
55
code_of_future/part1_basic/lesson9/app.py
Normal file
@@ -0,0 +1,55 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "tkinter"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
from tkinter import *
|
||||
|
||||
|
||||
class MyApp:
|
||||
def __init__(self):
|
||||
self.__root = Tk()
|
||||
self.label_text = StringVar()
|
||||
self.update_label("Введите текст")
|
||||
|
||||
self.label = Label(self.__root, textvariable=self.label_text)
|
||||
self.entry = Entry(self.__root)
|
||||
self.btn_act = Button(
|
||||
self.__root, text="Выполнить команду свыше", command=self.btn_act_click
|
||||
)
|
||||
self.btn_clear = Button(
|
||||
self.__root, text="Очистить", command=self.btn_clear_click
|
||||
)
|
||||
self.btn_exit = Button(self.__root, text="Выход", command=self.btn_exit_click)
|
||||
|
||||
self.label.pack(padx=15, pady=15)
|
||||
self.entry.pack(fill=X, padx=15, pady=15)
|
||||
self.btn_act.pack(padx=15, pady=15)
|
||||
self.btn_clear.pack(padx=15, pady=15)
|
||||
self.btn_exit.pack(padx=15, pady=15)
|
||||
mainloop()
|
||||
|
||||
def update_label(self, text):
|
||||
self.label_text.set(text)
|
||||
|
||||
def btn_act_click(self):
|
||||
text = self.entry.get()
|
||||
if text:
|
||||
self.update_label(f"Вы ввели: {text}")
|
||||
else:
|
||||
self.update_label("Вы ни чего не ввели")
|
||||
|
||||
def btn_clear_click(self):
|
||||
self.update_label("Введите что-нибудь еще")
|
||||
self.entry.delete(0, END)
|
||||
|
||||
def btn_exit_click(self):
|
||||
self.__root.destroy()
|
||||
|
||||
|
||||
app = MyApp()
|
42
code_of_future/part2_OOP/lesson1/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
Задача:
|
||||
|
||||
В первой строке вводится одно натуральное число num < 10.
|
||||
|
||||
Во второй строке создается пустой массив.
|
||||
|
||||
На третьей строке массив через цикл for заполняется рандомными натуральными числами < 100. Количество элементов не должно превышать num.
|
||||
|
||||
Отсортируйте массив используя метод “пузырька” по возрастанию.
|
||||
|
||||
Необходимо вывести получившийся массив.
|
||||
|
||||
|
||||
Пример:
|
||||
|
||||
Входные данные:
|
||||
|
||||
>> 5
|
||||
|
||||
--------------------
|
||||
|
||||
>>1
|
||||
|
||||
>>5
|
||||
|
||||
>>8
|
||||
|
||||
>>11
|
||||
|
||||
>>2
|
||||
|
||||
Выходные данные:
|
||||
|
||||
[1, 2, 5, 8, 11]
|
||||
|
||||
|
||||
Этапы выполнения:
|
||||
|
||||
Создайте файл с расширением “.py” и назовите его bubble_sort.
|
||||
Напишите код решения задачи
|
||||
Добавьте комментарии в коде объясняющие ход работы программы.
|
||||
|
44
code_of_future/part2_OOP/lesson1/bubble_sort.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Повторение. Сортировка"
|
||||
|
||||
В задании указанном в README.md требуется написать алгоритм
|
||||
пузырьковой сортировки над объектом типа list.
|
||||
В библиотеке collections представлен класс UserList,
|
||||
который позволяет кастомизировать стандартный объект
|
||||
list переопределением стандартных или добавлением своих
|
||||
методов оставляя за скобками остальные стандартные методы.
|
||||
Я создал свой class, переопределив метод sort, с использованием
|
||||
пузырьковой сортировки.
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
from collections import UserList
|
||||
|
||||
|
||||
class MyCustomList(UserList):
|
||||
def __init__(self):
|
||||
self.data = []
|
||||
|
||||
def len(self):
|
||||
return self.data.__len__()
|
||||
|
||||
def sort(self):
|
||||
for _ in range(self.len() - 1):
|
||||
for j in range(self.len() - 1):
|
||||
if self.data[j] > self.data[j + 1]:
|
||||
self.data[j], self.data[j + 1] = self.data[j + 1], self.data[j]
|
||||
|
||||
|
||||
arr = MyCustomList()
|
||||
|
||||
for _ in range(int(input("Введите количество элементов списка: "))):
|
||||
arr.append(int(input(f"Введите элемент {_ + 1}: ")))
|
||||
|
||||
print("Введенный список:", arr)
|
||||
arr.sort()
|
||||
print("Отсортированный", arr)
|
8
code_of_future/part2_OOP/lesson2/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
Домашнее задание 2.
|
||||
|
||||
|
||||
Создайте матрицу размера 3x3^ и заполните ее числами от 1 до 9
|
||||
|
||||
Создайте любую матрицу и посчитайте сумму всех ее элементов
|
||||
|
||||
Вычислите в матрице сумму элементов каждой строки
|
41
code_of_future/part2_OOP/lesson2/matrix.py
Normal file
@@ -0,0 +1,41 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Двумерные списки"
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
import random
|
||||
from functools import reduce
|
||||
|
||||
arr = []
|
||||
for _ in range(3):
|
||||
arr.append(list())
|
||||
|
||||
x = 0
|
||||
for i in range(1, 10):
|
||||
arr[x].append(i)
|
||||
if i in (3, 6):
|
||||
x += 1
|
||||
print("Печатаю матрицу 3х3")
|
||||
print(*arr, sep="\n", end="\n\n")
|
||||
|
||||
print("Генерирую произвольную матрицу со случайными числами")
|
||||
arr = []
|
||||
arr_x = random.randint(3, 10)
|
||||
arr_y = random.randint(3, 10)
|
||||
|
||||
for x in range(arr_x):
|
||||
arr.append(list())
|
||||
|
||||
for sub_list in arr:
|
||||
for _ in range(arr_y):
|
||||
sub_list.append(random.randint(-100, 100))
|
||||
|
||||
for i in range(arr_x):
|
||||
print(arr[i], "Сумма:", sum(arr[i]))
|
||||
|
||||
print("Сумма всех элементов:", sum(reduce(lambda x, y: x + y, arr)))
|
18
code_of_future/part2_OOP/lesson3/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
Домашнее задание 3.
|
||||
|
||||
Создайте класс `Car`, который имеет атрибуты:
|
||||
`make` (марка автомобиля),
|
||||
`model` (модель автомобиля) и
|
||||
`year` (год выпуска).
|
||||
Дайте им также метод `display_info()`, который выводит
|
||||
информацию о машине (марка, модель и год).
|
||||
|
||||
Создайте несколько объектов класса `Car`
|
||||
с разными характеристиками и вызовите метод
|
||||
`display_info()` для каждого из них.
|
||||
|
||||
Добавьте метод `calculate_age()` в класс `Car`,
|
||||
который будет рассчитывать и возвращать возраст
|
||||
автомобиля на текущий год.
|
||||
|
||||
|
29
code_of_future/part2_OOP/lesson3/cars.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from datetime import datetime as dt
|
||||
|
||||
|
||||
class Car:
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.make = kwargs.get("make")
|
||||
self.model = kwargs.get("model")
|
||||
self.year = kwargs.get("year")
|
||||
|
||||
def display_info(self):
|
||||
return (x for x in (self.make, self.model, self.year) if x is not None)
|
||||
|
||||
def calculate_age(self):
|
||||
if self.year is None:
|
||||
return "Неизвестно"
|
||||
return dt.today().year - self.year
|
||||
|
||||
|
||||
cars = (
|
||||
Car(make="Ваз", model="Нива", year=2000),
|
||||
Car(make="Mitsubishi", model="Colt", year=2007),
|
||||
Car(make="Газ", model="Вогла"),
|
||||
Car(make="БРДМ", year=1993),
|
||||
)
|
||||
|
||||
for car in cars:
|
||||
print(*car.display_info())
|
||||
print("возраст тс:", car.calculate_age())
|
||||
print()
|
21
code_of_future/part2_OOP/lesson4/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
Домашнее задание 4.
|
||||
|
||||
Создайте родительский класс `Animal` с атрибутами
|
||||
`name` и `species`. Дайте им также метод `make_sound()`,
|
||||
который выводит звук, издаваемый животными.
|
||||
|
||||
|
||||
Создайте подклассы `Dog` и `Cat`,
|
||||
которые наследуют от класса `Animal`.
|
||||
Дайте каждому из них свой собственный метод
|
||||
`make_sound()`, который выводит соответствующий
|
||||
звук (`"Гав"` для собаки и `"Мяу"` для кота).
|
||||
|
||||
|
||||
Добавьте дополнительные методы и атрибуты в подклассы.
|
||||
Например, метод `bark()` для собаки, который выводит
|
||||
сообщение о лае, и метод `purr()` для кота,
|
||||
который выводит сообщение о мурлыкании.
|
||||
Можно также добавить атрибуты, специфичные для каждого
|
||||
класса.
|
||||
|
67
code_of_future/part2_OOP/lesson4/animals.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
Модуль является результатом выполнения практической
|
||||
домашней работы по теме "Наследование классов"
|
||||
|
||||
Задачу решил через абстрактный класс Animal, с абстрактным методом
|
||||
make_sound, который обязательно должен быть реализован
|
||||
в дочерних классах(иначе будет Error).
|
||||
|
||||
:copyright: Сергей Ванюшкин <pi3c@yandex.ru>
|
||||
:git: https://git.pi3c.ru/pi3c/StudyRepo_Synergy.git
|
||||
:license: MIT
|
||||
2023г.
|
||||
"""
|
||||
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class Animal(ABC):
|
||||
def __init__(self, **kwargs):
|
||||
self.name = kwargs.get("name") or "Безымянное"
|
||||
self.species = kwargs.get("species") or "Чудище заморское"
|
||||
|
||||
@abstractmethod
|
||||
def make_sound(self):
|
||||
pass
|
||||
|
||||
|
||||
class Dog(Animal):
|
||||
def make_sound(self):
|
||||
return "Гав"
|
||||
|
||||
def bark(self):
|
||||
return "Лай,лай,лАй, лалаайлай..."
|
||||
|
||||
|
||||
class Cat(Animal):
|
||||
def make_sound(self):
|
||||
return "Мяу"
|
||||
|
||||
def purr(self):
|
||||
return "Мурмурмур"
|
||||
|
||||
|
||||
class SomeAnimal(Animal):
|
||||
def make_sound(self):
|
||||
return "Кряхтит, скрипит, зубами клацает"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
animals = (
|
||||
Dog(name="Rex", species="Собакен обычный"),
|
||||
Cat(name="Кузя", species="Котяра хитрожопый"),
|
||||
Dog(name="Галкин", species="Двортерьер Кусучий"),
|
||||
SomeAnimal(),
|
||||
)
|
||||
|
||||
for an in animals:
|
||||
print("Досье")
|
||||
print("Вид:", an.species)
|
||||
print("кличка:", an.name)
|
||||
print("говорит:", an.make_sound())
|
||||
if isinstance(an, Cat):
|
||||
print(an.name, "доволен:", an.purr())
|
||||
elif isinstance(an, Dog):
|
||||
print(an.name, "злой пес:", an.bark())
|
||||
print()
|
9
code_of_future/part2_OOP/lesson5/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Домашнее задание 5.
|
||||
|
||||
Создайте текстовый файл с названием "sample.txt" и написать программу для чтения и вывода его содержимого на экран.
|
||||
|
||||
Создайте программу, которая запрашивает у пользователя строку текста и записывает её в файл "user_input.txt".
|
||||
|
||||
Напишите программу для подсчета количества строк в текстовом файле "sample.txt" и вывода этого числа.
|
||||
|
||||
|
10
code_of_future/part2_OOP/lesson5/file_read.py
Normal file
@@ -0,0 +1,10 @@
|
||||
counter = 0
|
||||
print('file: sample.txt')
|
||||
print('#' * 60)
|
||||
with open('sample.txt', mode='r') as f:
|
||||
for line in f.readlines():
|
||||
counter += 1
|
||||
print(line.strip())
|
||||
print('#' * 60)
|
||||
print('end file')
|
||||
print('Количество строк в sample.txt is', counter)
|
6
code_of_future/part2_OOP/lesson5/file_write.py
Normal file
@@ -0,0 +1,6 @@
|
||||
while text:=input('Введите строку или оставьте пустым для выхода\n$> '):
|
||||
if text:
|
||||
with open('user_input.txt', mode='a') as f:
|
||||
f.write(text + '\n')
|
||||
|
||||
|
20
code_of_future/part2_OOP/lesson5/sample.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
Домашнее задание 5.
|
||||
|
||||
Создайте текстовый файл с названием "sample.txt"
|
||||
и написать программу для чтения и вывода его содержимого на экран.
|
||||
|
||||
Создайте программу, которая запрашивает у пользователя
|
||||
строку текста и записывает её в файл "user_input.txt".
|
||||
|
||||
Напишите
|
||||
программу
|
||||
для
|
||||
подсчета
|
||||
количества
|
||||
строк
|
||||
в текстовом
|
||||
файле
|
||||
"sample.txt" и
|
||||
вывода
|
||||
этого
|
||||
числа.
|
5
code_of_future/part2_OOP/lesson5/user_input.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
skahfdlahfsd
|
||||
sdkjahlkasdjlfnj
|
||||
adskjfldsajhfansdflksd
|
||||
sdkjfaknca
|
5
code_of_future/part2_OOP/lesson6/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Игра Змейка (pygame)
|
||||
## Описание
|
||||
Данный проект является результатом выполнения учебной практической работы.
|
||||
Игра написана с помощью библиотеки pygame.
|
||||
|
9
code_of_future/part2_OOP/lesson6/app.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from snake.game import Game
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = Game()
|
||||
game.game_init()
|
||||
game.set_title()
|
||||
game.get_menu()
|
||||
game.mainloop()
|
||||
|
113
code_of_future/part2_OOP/lesson6/poetry.lock
generated
Normal file
@@ -0,0 +1,113 @@
|
||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "pygame"
|
||||
version = "2.5.2"
|
||||
description = "Python Game Development"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "pygame-2.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a0769eb628c818761755eb0a0ca8216b95270ea8cbcbc82227e39ac9644643da"},
|
||||
{file = "pygame-2.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed9a3d98adafa0805ccbaaff5d2996a2b5795381285d8437a4a5d248dbd12b4a"},
|
||||
{file = "pygame-2.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30d1618672a55e8c6669281ba264464b3ab563158e40d89e8c8b3faa0febebd"},
|
||||
{file = "pygame-2.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39690e9be9baf58b7359d1f3b2336e1fd6f92fedbbce42987be5df27f8d30718"},
|
||||
{file = "pygame-2.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03879ec299c9f4ba23901b2649a96b2143f0a5d787f0b6c39469989e2320caf1"},
|
||||
{file = "pygame-2.5.2-cp310-cp310-win32.whl", hash = "sha256:74e1d6284100e294f445832e6f6343be4fe4748decc4f8a51131ae197dae8584"},
|
||||
{file = "pygame-2.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:485239c7d32265fd35b76ae8f64f34b0637ae11e69d76de15710c4b9edcc7c8d"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34646ca20e163dc6f6cf8170f1e12a2e41726780112594ac061fa448cf7ccd75"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3b8a6e351665ed26ea791f0e1fd649d3f483e8681892caef9d471f488f9ea5ee"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc346965847aef00013fa2364f41a64f068cd096dcc7778fc306ca3735f0eedf"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35632035fd81261f2d797fa810ea8c46111bd78ceb6089d52b61ed7dc3c5d05f"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e24d05184e4195fe5ebcdce8b18ecb086f00182b9ae460a86682d312ce8d31f"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-win32.whl", hash = "sha256:f02c1c7505af18d426d355ac9872bd5c916b27f7b0fe224749930662bea47a50"},
|
||||
{file = "pygame-2.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:6d58c8cf937815d3b7cdc0fa9590c5129cb2c9658b72d00e8a4568dea2ff1d42"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1a2a43802bb5e89ce2b3b775744e78db4f9a201bf8d059b946c61722840ceea8"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1c289f2613c44fe70a1e40769de4a49c5ab5a29b9376f1692bb1a15c9c1c9bfa"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:074aa6c6e110c925f7f27f00c7733c6303407edc61d738882985091d1eb2ef17"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe0228501ec616779a0b9c4299e837877783e18df294dd690b9ab0eed3d8aaab"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31648d38ecdc2335ffc0e38fb18a84b3339730521505dac68514f83a1092e3f4"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-win32.whl", hash = "sha256:224c308856334bc792f696e9278e50d099a87c116f7fc314cd6aa3ff99d21592"},
|
||||
{file = "pygame-2.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:dd2d2650faf54f9a0f5bd0db8409f79609319725f8f08af6507a0609deadcad4"},
|
||||
{file = "pygame-2.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b30bc1220c457169571aac998e54b013aaeb732d2fd8744966cb1cfab1f61d1"},
|
||||
{file = "pygame-2.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78fcd7643358b886a44127ff7dec9041c056c212b3a98977674f83f99e9b12d3"},
|
||||
{file = "pygame-2.5.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cf093a51cb294ede56c29d4acf41538c00f297fcf78a9b186fb7d23c0577b6"},
|
||||
{file = "pygame-2.5.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fe323acbf53a0195c8c98b1b941eba7ac24e3e2b28ae48e8cda566f15fc4945"},
|
||||
{file = "pygame-2.5.2-cp36-cp36m-win32.whl", hash = "sha256:5697528266b4716d9cdd44a5a1d210f4d86ef801d0f64ca5da5d0816704009d9"},
|
||||
{file = "pygame-2.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edda1f7cff4806a4fa39e0e8ccd75f38d1d340fa5fc52d8582ade87aca247d92"},
|
||||
{file = "pygame-2.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9bd738fd4ecc224769d0b4a719f96900a86578e26e0105193658a32966df2aae"},
|
||||
{file = "pygame-2.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30a8d7cf12363b4140bf2f93b5eec4028376ca1d0fe4b550588f836279485308"},
|
||||
{file = "pygame-2.5.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc12e4dea3e88ea8a553de6d56a37b704dbe2aed95105889f6afeb4b96e62097"},
|
||||
{file = "pygame-2.5.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b34c73cb328024f8db3cb6487a37e54000148988275d8d6e5adf99d9323c937"},
|
||||
{file = "pygame-2.5.2-cp37-cp37m-win32.whl", hash = "sha256:7d0a2794649defa57ef50b096a99f7113d3d0c2e32d1426cafa7d618eadce4c7"},
|
||||
{file = "pygame-2.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:41f8779f52e0f6e6e6ccb8f0b5536e432bf386ee29c721a1c22cada7767b0cef"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:677e37bc0ea7afd89dde5a88ced4458aa8656159c70a576eea68b5622ee1997b"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47a8415d2bd60e6909823b5643a1d4ef5cc29417d817f2a214b255f6fa3a1e4c"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ff21201df6278b8ca2e948fb148ffe88f5481fd03760f381dd61e45954c7dff"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29a84b2e02814b9ba925357fd2e1df78efe5e1aa64dc3051eaed95d2b96eafd"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d78485c4d21133d6b2fbb504cd544ca655e50b6eb551d2995b3aa6035928adda"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-win32.whl", hash = "sha256:d851247239548aa357c4a6840fb67adc2d570ce7cb56988d036a723d26b48bff"},
|
||||
{file = "pygame-2.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:88d1cdacc2d3471eceab98bf0c93c14d3a8461f93e58e3d926f20d4de3a75554"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4f1559e7efe4efb9dc19d2d811d702f325d9605f9f6f9ececa39ee6890c798f5"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf2191b756ceb0e8458a761d0c665b0c70b538570449e0d39b75a5ba94ac5cf0"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cf2257447ce7f2d6de37e5fb019d2bbe32ed05a5721ace8bc78c2d9beaf3aee"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75cbbfaba2b81434d62631d0b08b85fab16cf4a36e40b80298d3868927e1299"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:daca456d5b9f52e088e06a127dec182b3638a775684fb2260f25d664351cf1ae"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-win32.whl", hash = "sha256:3b3e619e33d11c297d7a57a82db40681f9c2c3ae1d5bf06003520b4fe30c435d"},
|
||||
{file = "pygame-2.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:1822d534bb7fe756804647b6da2c9ea5d7a62d8796b2e15d172d3be085de28c6"},
|
||||
{file = "pygame-2.5.2-pp36-pypy36_pp73-win32.whl", hash = "sha256:e708fc8f709a0fe1d1876489345f2e443d47f3976d33455e2e1e937f972f8677"},
|
||||
{file = "pygame-2.5.2-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c13edebc43c240fb0532969e914f0ccefff5ae7e50b0b788d08ad2c15ef793e4"},
|
||||
{file = "pygame-2.5.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:263b4a7cbfc9fe2055abc21b0251cc17dea6dff750f0e1c598919ff350cdbffe"},
|
||||
{file = "pygame-2.5.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e58e2b0c791041e4bccafa5bd7650623ba1592b8fe62ae0a276b7d0ecb314b6c"},
|
||||
{file = "pygame-2.5.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0bd67426c02ffe6c9827fc4bcbda9442fbc451d29b17c83a3c088c56fef2c90"},
|
||||
{file = "pygame-2.5.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dcff6cbba1584cf7732ce1dbdd044406cd4f6e296d13bcb7fba963fb4aeefc9"},
|
||||
{file = "pygame-2.5.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce4b6c0bfe44d00bb0998a6517bd0cf9455f642f30f91bc671ad41c05bf6f6ae"},
|
||||
{file = "pygame-2.5.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68c4e8e60b725ffc7a6c6ecd9bb5fcc5ed2d6e0e2a2c4a29a8454856ef16ad63"},
|
||||
{file = "pygame-2.5.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f3849f97372a3381c66955f99a0d58485ccd513c3d00c030b869094ce6997a6"},
|
||||
{file = "pygame-2.5.2.tar.gz", hash = "sha256:c1b89eb5d539e7ac5cf75513125fb5f2f0a2d918b1fd6e981f23bf0ac1b1c24a"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygame-menu"
|
||||
version = "4.4.3"
|
||||
description = "A menu for pygame. Simple, and easy to use"
|
||||
optional = false
|
||||
python-versions = ">=3.6, <4"
|
||||
files = [
|
||||
{file = "pygame-menu-4.4.3.tar.gz", hash = "sha256:02a99e557601f356ce2cc82a10e98bcb581d539a41c666c4ee614fae366c3647"},
|
||||
{file = "pygame_menu-4.4.3-py3-none-any.whl", hash = "sha256:d81f50acc854701c6b8d08b36a0b4f3a69f9ee63d3ae7591d063239812e75a0e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pygame = ">=1.9.3"
|
||||
pyperclip = "*"
|
||||
typing-extensions = "*"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||
test = ["nose2[coverage-plugin]"]
|
||||
|
||||
[[package]]
|
||||
name = "pyperclip"
|
||||
version = "1.8.2"
|
||||
description = "A cross-platform clipboard module for Python. (Only handles plain text for now.)"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pyperclip-1.8.2.tar.gz", hash = "sha256:105254a8b04934f0bc84e9c24eb360a591aaf6535c9def5f29d92af107a9bf57"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.9.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
|
||||
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "daa7d8a25daf865c7fecc14f541825fed526983d327dcd142eb997cb5caa05ee"
|
17
code_of_future/part2_OOP/lesson6/pyproject.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[tool.poetry]
|
||||
name = "lesson6"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["pi3c <pi3c@yandex.ru>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
pygame = "^2.5.2"
|
||||
pygame-menu = "^4.4.3"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
0
code_of_future/part2_OOP/lesson6/snake/__init__.py
Normal file
25
code_of_future/part2_OOP/lesson6/snake/food.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import os
|
||||
import random
|
||||
|
||||
import pygame as pg
|
||||
|
||||
|
||||
class Food:
|
||||
FOOD = (
|
||||
pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'mouse1.png')),
|
||||
pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'mouse2.png'))
|
||||
)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.x = random.randint(0, 25) * 30
|
||||
self.y = random.randint(0, 19) * 30
|
||||
self.type = random.choice(self.FOOD)
|
||||
|
||||
|
||||
def draw(self, screen):
|
||||
screen.blit(self.type, (self.x, self.y))
|
||||
|
||||
def get_coords(self):
|
||||
return self.x, self.y
|
||||
|
||||
|
163
code_of_future/part2_OOP/lesson6/snake/game.py
Normal file
@@ -0,0 +1,163 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
import pygame as pg
|
||||
import pygame_menu
|
||||
|
||||
from .snake import Snake
|
||||
from .food import Food
|
||||
|
||||
class Game:
|
||||
def __init__(self) -> None:
|
||||
self.screen_widht = 780
|
||||
self.screen_hight = 600
|
||||
self.clock = pg.time.Clock()
|
||||
pg.font.init()
|
||||
self.font = pg.font.SysFont('arial', 72)
|
||||
self.score = 0
|
||||
self.paused = True
|
||||
self.started = False
|
||||
self.title = 'Snakessss'
|
||||
self.done = False # Флаг главного цикла
|
||||
self.need_reset = False
|
||||
self.bg = pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'bg.png'))
|
||||
self.screen = pg.display.set_mode((self.screen_widht, self.screen_hight))
|
||||
self.fps = 60
|
||||
self.set_title()
|
||||
self.menu = None
|
||||
self.snake = Snake()
|
||||
self.foods_array = []
|
||||
self.game_speed = 0
|
||||
|
||||
def game_init(self):
|
||||
pg.init()
|
||||
|
||||
def get_menu(self):
|
||||
self.set_bg()
|
||||
self.menu = pygame_menu.Menu('Snakessss game', 400, 300, theme=pygame_menu.themes.THEME_BLUE)
|
||||
self.menu.add.button('Start new game', self.start_new_game)
|
||||
if self.started:
|
||||
self.menu.add.button('Restore game', self.restore_game)
|
||||
self.menu.add.selector('Speed', [('Slow', 0), ('Medium', 1), ('Fast', 2)], onchange=self.set_speed, onreturn=self.restore_game)
|
||||
self.menu._widgets[-1].set_value(self.game_speed)
|
||||
self.menu.add.button('Exit', pygame_menu.events.EXIT)
|
||||
self.menu.mainloop(self.screen)
|
||||
|
||||
def disable_menu(self):
|
||||
if self.menu is not None:
|
||||
self.menu.disable()
|
||||
|
||||
def set_speed(self, tuple_celected, difficulty):
|
||||
self.game_speed = difficulty
|
||||
self.snake.set_speed(speed=self.game_speed)
|
||||
|
||||
def set_title(self):
|
||||
pg.display.set_caption(self.title)
|
||||
|
||||
def set_bg(self):
|
||||
self.screen.blit(self.bg, (0, 0))
|
||||
|
||||
def start_new_game(self):
|
||||
print(self.game_speed, self.snake.speed)
|
||||
self.started = True
|
||||
self.paused = False
|
||||
self.disable_menu()
|
||||
self.need_reset = True
|
||||
|
||||
def restore_game(self, *args, **kwargs):
|
||||
if self.started:
|
||||
self.disable_menu()
|
||||
self.paused = False
|
||||
else:
|
||||
self.start_new_game()
|
||||
|
||||
|
||||
def save_game(self):
|
||||
pass
|
||||
|
||||
def load_game(self):
|
||||
pass
|
||||
|
||||
def gameover(self):
|
||||
surf = self.font.render('GAME OVER', True, (20, 20, 20))
|
||||
rect = surf.get_rect()
|
||||
score = self.font.render(f'Score: {self.score}', True, (20, 20, 20))
|
||||
rect2 = score.get_rect()
|
||||
rect.midtop = (390, 250)
|
||||
rect2.midtop = (390, 320)
|
||||
self.screen.blit(surf, rect)
|
||||
self.screen.blit(score, rect2)
|
||||
pg.display.flip()
|
||||
time.sleep(3)
|
||||
|
||||
self.get_menu()
|
||||
|
||||
def update_game_window(self):
|
||||
while len(self.foods_array) < 2:
|
||||
food = Food()
|
||||
if food.get_coords() not in self.snake.get_coords():
|
||||
self.foods_array.append(food)
|
||||
|
||||
for f in self.foods_array:
|
||||
if self.snake.get_head_coords() == f.get_coords():
|
||||
self.score += 5 * self.snake.length
|
||||
self.foods_array.remove(f)
|
||||
self.snake.length += 1
|
||||
|
||||
self.set_bg()
|
||||
self.snake.draw(self.screen)
|
||||
for f in self.foods_array:
|
||||
f.draw(self.screen)
|
||||
|
||||
pg.display.update()
|
||||
|
||||
if self.snake.impacted:
|
||||
self.started = False
|
||||
self.gameover()
|
||||
|
||||
|
||||
def mainloop(self):
|
||||
while not self.done:
|
||||
if self.need_reset:
|
||||
self.snake.reset(speed=self.game_speed)
|
||||
self.start_new_game()
|
||||
self.need_reset = False
|
||||
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
self.done = True
|
||||
|
||||
pressed = pg.key.get_pressed()
|
||||
|
||||
if pressed[pg.K_ESCAPE]:
|
||||
self.paused = False if self.paused else True
|
||||
if self.paused:
|
||||
self.get_menu()
|
||||
|
||||
if pressed[pg.K_UP]:
|
||||
if self.snake.direction != 'down':
|
||||
self.snake.direction = 'up'
|
||||
|
||||
if pressed[pg.K_DOWN]:
|
||||
if self.snake.direction != 'up':
|
||||
self.snake.direction = 'down'
|
||||
|
||||
if pressed[pg.K_LEFT]:
|
||||
if self.snake.direction != 'right':
|
||||
self.snake.direction = 'left'
|
||||
|
||||
if pressed[pg.K_RIGHT]:
|
||||
if self.snake.direction != 'left':
|
||||
self.snake.direction = 'right'
|
||||
|
||||
self.update_game_window()
|
||||
|
||||
self.clock.tick(self.fps)
|
||||
|
||||
if __name__ == "__main__":
|
||||
game = Game()
|
||||
game.game_init()
|
||||
game.set_title()
|
||||
game.get_menu()
|
||||
game.mainloop()
|
||||
|
BIN
code_of_future/part2_OOP/lesson6/snake/img/bg.png
Normal file
After Width: | Height: | Size: 1013 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_h.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_ld_ur.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_lu_dr.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_rd_ul.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_ru_dl.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/body_v.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/mouse1.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/mouse2.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_down.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_left.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_right.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
code_of_future/part2_OOP/lesson6/snake/img/snake_up.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
106
code_of_future/part2_OOP/lesson6/snake/snake.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import os
|
||||
|
||||
import pygame as pg
|
||||
|
||||
|
||||
class Snake:
|
||||
def __init__(self, **kwargs) -> None:
|
||||
self.x = kwargs.get('x', 90)
|
||||
self.y = kwargs.get('y', 300)
|
||||
self.snake_head = {
|
||||
'left': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_left.png')),
|
||||
'right': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_right.png')),
|
||||
'up': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_up.png')),
|
||||
'down': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'snake_down.png')),
|
||||
}
|
||||
self.snake_body = {
|
||||
'h': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_h.png')),
|
||||
'v': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_v.png')),
|
||||
'ru_dl': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_ru_dl.png')),
|
||||
'rd_ul': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_rd_ul.png')),
|
||||
'lu_dr': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_lu_dr.png')),
|
||||
'ld_ur': pg.image.load(os.path.join(os.curdir, 'snake', 'img', 'body_ld_ur.png')),
|
||||
}
|
||||
|
||||
self.direction = 'right'
|
||||
self.direction_prev = 'right'
|
||||
self.length = 2
|
||||
self.speed = 30 # скорость движения змейки чем меньше, тем быстрее
|
||||
self.counter = 0 # Просто счетчик, для регулировки скорости нужен
|
||||
self.body = kwargs.get('body', [('h', 60, 300), ('h', 30, 300)])
|
||||
self.impacted = False
|
||||
|
||||
def set_speed(self, **kwargs):
|
||||
self.speed = (30, 20, 10)[kwargs.get('speed', 30)]
|
||||
|
||||
def reset(self, **kwargs):
|
||||
self.x = 90
|
||||
self.y = 300
|
||||
self.body = [('h', 60, 300), ('h', 30, 300)]
|
||||
self.direction = 'right'
|
||||
self.direction_prev = 'right'
|
||||
self.impacted = False
|
||||
self.length = 2
|
||||
self.set_speed(**kwargs)
|
||||
|
||||
def get_head_coords(self):
|
||||
return self.x, self.y
|
||||
|
||||
def get_coords(self):
|
||||
return [(self.x, self.y)] + [(el[1], el[2]) for el in self.body]
|
||||
|
||||
def draw(self, screen):
|
||||
if len(self.body) > self.length:
|
||||
self.body.pop()
|
||||
|
||||
if self.counter >= self.speed:
|
||||
|
||||
if self.direction == self.direction_prev:
|
||||
if self.direction in ('right', 'left'):
|
||||
self.body.insert(0, ('h', self.x, self.y))
|
||||
else:
|
||||
self.body.insert(0, ('v', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('right', 'up'), ('down', 'left')]:
|
||||
self.body.insert(0, ('ru_dl', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('right', 'down'), ('up', 'left')]:
|
||||
self.body.insert(0, ('rd_ul', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('left', 'up'), ('down', 'right')]:
|
||||
self.body.insert(0, ('lu_dr', self.x, self.y))
|
||||
elif (self.direction_prev, self.direction) in [('left', 'down'), ('up', 'right')]:
|
||||
self.body.insert(0, ('ld_ur', self.x, self.y))
|
||||
|
||||
|
||||
match self.direction:
|
||||
case 'left':
|
||||
self.x -= 30
|
||||
if self.x < 0:
|
||||
self.x = 750
|
||||
self.direction_prev = 'left'
|
||||
case 'right':
|
||||
self.x += 30
|
||||
if self.x > 750:
|
||||
self.x = 0
|
||||
self.direction_prev = 'right'
|
||||
case 'up':
|
||||
self.y -= 30
|
||||
if self.y < 0:
|
||||
self.y = 570
|
||||
self.direction_prev = 'up'
|
||||
case 'down':
|
||||
self.y += 30
|
||||
if self.y > 570:
|
||||
self.y = 0
|
||||
self.direction_prev = 'down'
|
||||
|
||||
if (self.x, self.y) in [(x[1], x[2]) for x in self.body]:
|
||||
self.impacted = True
|
||||
|
||||
self.counter = 0
|
||||
|
||||
self.counter += 1
|
||||
|
||||
screen.blit(self.snake_head[self.direction], (self.x, self.y))
|
||||
for el in self.body:
|
||||
screen.blit(self.snake_body[el[0]], (el[1], el[2]))
|
||||
|
||||
|