From 73f3a0607cfaeb94c23265b8bdc240775a9a0be9 Mon Sep 17 00:00:00 2001 From: Aleksei Mihalin Date: Wed, 17 Oct 2018 14:49:00 +0300 Subject: [PATCH 1/6] hw3 --- client.py | 87 +++++++++----------------------- config.py | 15 ++++++ console_menu.py | 19 +++++++ server.py | 131 +++++++++++++++++++++++++++--------------------- 4 files changed, 132 insertions(+), 120 deletions(-) create mode 100755 config.py create mode 100755 console_menu.py diff --git a/client.py b/client.py index 64e7c8e..d3588f3 100755 --- a/client.py +++ b/client.py @@ -1,71 +1,32 @@ -#!/usr/bin/env python3 -"""Script for Tkinter GUI chat client.""" -from socket import AF_INET, socket, SOCK_STREAM -from threading import Thread -import tkinter +import socket +import json +from config import get_client_socket +from console_menu import print_menu, get_command +def send_data(s): + data = { + "text": input("Input text: "), + "user": input("Input username: "), + "age": int(input("Input age: ")) + } -def receive(): - """Handles receiving of messages.""" - while True: - try: - msg = client_socket.recv(BUFSIZ).decode("utf8") - msg_list.insert(tkinter.END, msg) - except OSError: # Possibly client has left the chat. - break - - -def send(event=None): # event is passed by binders. - """Handles sending of messages.""" - msg = my_msg.get() - my_msg.set("") # Clears input field. - client_socket.send(bytes(msg, "utf8")) - if msg == "{quit}": - client_socket.close() - top.quit() - + s.send(json.dumps(data).encode("utf-8")) -def on_closing(event=None): - """This function is to be called when the window is closed.""" - my_msg.set("{quit}") - send() + print("Data sended") -top = tkinter.Tk() -top.title("Chatter") +def exit_program(s): + s.send(json.dumps({"exit": ""}).encode("utf-8")) + print("Exit") + exit() -messages_frame = tkinter.Frame(top) -my_msg = tkinter.StringVar() # For the messages to be sent. -my_msg.set("Type your messages here.") -scrollbar = tkinter.Scrollbar(messages_frame) # To navigate through past messages. -# Following will contain the messages. -msg_list = tkinter.Listbox(messages_frame, height=15, width=50, yscrollcommand=scrollbar.set) -scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y) -msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH) -msg_list.pack() -messages_frame.pack() +if __name__ == "__main__": + s = get_client_socket() + menu = ["Send data", "Exit"] -entry_field = tkinter.Entry(top, textvariable=my_msg) -entry_field.bind("", send) -entry_field.pack() -send_button = tkinter.Button(top, text="Send", command=send) -send_button.pack() + actions = {"1":send_data, "2":exit_program} -top.protocol("WM_DELETE_WINDOW", on_closing) - -#----Now comes the sockets part---- -HOST = input('Enter host: ') -PORT = input('Enter port: ') -if not PORT: - PORT = 33000 -else: - PORT = int(PORT) - -BUFSIZ = 1024 -ADDR = (HOST, PORT) - -client_socket = socket(AF_INET, SOCK_STREAM) -client_socket.connect(ADDR) + while True: + print_menu(menu) + command = get_command(menu) -receive_thread = Thread(target=receive) -receive_thread.start() -tkinter.mainloop() # Starts GUI execution. \ No newline at end of file + actions[command](s) \ No newline at end of file diff --git a/config.py b/config.py new file mode 100755 index 0000000..46291ee --- /dev/null +++ b/config.py @@ -0,0 +1,15 @@ +import socket + +ADDRESS = "localhost" +PORT = 9292 + +def get_client_socket(): + s = socket.socket() + s.connect((ADDRESS, PORT)) + return s + +def get_server_socket(): + s = socket.socket() + s.bind((ADDRESS, PORT)) + s.listen(10) + return s \ No newline at end of file diff --git a/console_menu.py b/console_menu.py new file mode 100755 index 0000000..1b3c7f5 --- /dev/null +++ b/console_menu.py @@ -0,0 +1,19 @@ +def print_menu(menu): + for i,m in enumerate(menu, start=1): + print(f"{i}.{m}") + +def get_command(menu): + + while True: + command = input("Input command: ") + + if command.isdigit() and (1 <= int(command) <= len(menu)): + return command + else: + print("Wrong command. Try again!") + + +if __name__ == "__main__": + pass + +# import this \ No newline at end of file diff --git a/server.py b/server.py index 3deeb06..266caed 100755 --- a/server.py +++ b/server.py @@ -1,57 +1,74 @@ -from socket import socket, AF_INET, SOCK_STREAM -from threading import Thread - - -def broadcast(msg, prefix=""): # prefix is for name identification. - """Broadcasts a message to all the clients.""" - for sock in clients: - sock.send(bytes(prefix, "utf8") + msg) - - -def handle_client(client): # Takes client socket as argument. - """Handles a single client connection.""" - name = client.recv(BUFSIZ).decode("utf8") - welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name - client.send(bytes(welcome, "utf8")) - msg = "%s has joined the chat!" % name - broadcast(bytes(msg, "utf8")) - clients[client] = name - while True: - msg = client.recv(BUFSIZ) - if msg != bytes("{quit}", "utf8"): - broadcast(msg, name + ": ") - else: - client.send(bytes("{quit}", "utf8")) - client.close() - del clients[client] - broadcast(bytes("%s has left the chat." % name, "utf8")) - break - - -def accept_incoming_connections(): - """Sets up handling for incoming clients.""" - while True: - client, client_address = SERVER.accept() - print("%s:%s has connected." % (client, client_address)) - client.send(bytes("Greetings from the cave!" + - "Now type your name and press enter!", "utf8")) - addresses[client] = client_address - Thread(target=handle_client, args=(client,)).start() - - -clients = {} -addresses = {} -HOST = '' -PORT = 33000 -BUFSIZ = 1024 -ADDR = (HOST, PORT) -SERVER = socket(AF_INET, SOCK_STREAM) -SERVER.bind(ADDR) - -if __name__ == "__main__": - SERVER.listen(5) # Listens for 5 connections at max. - print("Waiting for connection...") - ACCEPT_THREAD = Thread(target=accept_incoming_connections) - ACCEPT_THREAD.start() # Starts the infinite loop. - ACCEPT_THREAD.join() - SERVER.close() +import socket +import json +from config import get_server_socket +s = get_server_socket() +print("Server started") +client, addr = s.accept() +print("Client connected: ",client, addr) + +while True: + print("Waiting data") + + data = json.loads(client.recv(1024).decode("utf-8")) + print("Data received") + + if "exit" not in data: + print(data) + else: + client.close() + s.close() + print("Exit") + break + + + + + + +# Присутствие +# Каждый пользователь при подключении к серверу отсылает сервисное сообщение о присутствии — presence с необязательным полем type: +# { +# "action": "presence", +# "time": , +# "type": "status", +# "user": { +# "account_name": "C0deMaver1ck", +# "status": "Yep, I am here!" +# } +# } +# + +# Коды ответов сервера +# JIM-протокол использует коды ошибок HTTP. Перечислим поддерживаемые: +# 1xx — информационные сообщения: +# 100 — базовое уведомление; +# 101 — важное уведомление. +# 2xx — успешное завершение: +# 200 — OK; +# 201 (created) — объект создан; +# 202 (accepted) — подтверждение. +# 4xx — ошибка на стороне клиента: +# 400 — неправильный запрос/JSON-объект; +# 401 — не авторизован; +# 402 — неправильный логин/пароль; +# 403 (forbidden) — пользователь заблокирован; +# 404 (not found) — пользователь/чат отсутствует на сервере; +# 409 (conflict) — уже имеется подключение с указанным логином; +# 410 (gone) — адресат существует, но недоступен (offline). +# 5xx — ошибка на стороне сервера: +# 500 — ошибка сервера. +# Коды ошибок могут быть дополнены новыми. +# +# Сообщения-ответы имеют следующий формат (в зависимости от кода ответа): +# { +# "response": 1xx / 2xx, +# "time": , +# "alert": "message (optional for 2xx codes)" +# } +# +# Или такой: +# { +# "response": 4xx / 5xx, +# "time": , +# "error": "error message (optional)" +# } From 3c0864625998e6eb7d6d8ffa3dd1f330bb2a6a7e Mon Sep 17 00:00:00 2001 From: Aleksei Mihalin Date: Tue, 30 Oct 2018 12:41:11 +0300 Subject: [PATCH 2/6] lesson03 - client-server + json --- lesson03/client.py | 32 +++++++++++++++++ lesson03/config.py | 15 ++++++++ lesson03/console_menu.py | 19 +++++++++++ lesson03/server.py | 74 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+) create mode 100755 lesson03/client.py create mode 100755 lesson03/config.py create mode 100755 lesson03/console_menu.py create mode 100755 lesson03/server.py diff --git a/lesson03/client.py b/lesson03/client.py new file mode 100755 index 0000000..d3588f3 --- /dev/null +++ b/lesson03/client.py @@ -0,0 +1,32 @@ +import socket +import json +from config import get_client_socket +from console_menu import print_menu, get_command + +def send_data(s): + data = { + "text": input("Input text: "), + "user": input("Input username: "), + "age": int(input("Input age: ")) + } + + s.send(json.dumps(data).encode("utf-8")) + + print("Data sended") + +def exit_program(s): + s.send(json.dumps({"exit": ""}).encode("utf-8")) + print("Exit") + exit() + +if __name__ == "__main__": + s = get_client_socket() + menu = ["Send data", "Exit"] + + actions = {"1":send_data, "2":exit_program} + + while True: + print_menu(menu) + command = get_command(menu) + + actions[command](s) \ No newline at end of file diff --git a/lesson03/config.py b/lesson03/config.py new file mode 100755 index 0000000..46291ee --- /dev/null +++ b/lesson03/config.py @@ -0,0 +1,15 @@ +import socket + +ADDRESS = "localhost" +PORT = 9292 + +def get_client_socket(): + s = socket.socket() + s.connect((ADDRESS, PORT)) + return s + +def get_server_socket(): + s = socket.socket() + s.bind((ADDRESS, PORT)) + s.listen(10) + return s \ No newline at end of file diff --git a/lesson03/console_menu.py b/lesson03/console_menu.py new file mode 100755 index 0000000..1b3c7f5 --- /dev/null +++ b/lesson03/console_menu.py @@ -0,0 +1,19 @@ +def print_menu(menu): + for i,m in enumerate(menu, start=1): + print(f"{i}.{m}") + +def get_command(menu): + + while True: + command = input("Input command: ") + + if command.isdigit() and (1 <= int(command) <= len(menu)): + return command + else: + print("Wrong command. Try again!") + + +if __name__ == "__main__": + pass + +# import this \ No newline at end of file diff --git a/lesson03/server.py b/lesson03/server.py new file mode 100755 index 0000000..266caed --- /dev/null +++ b/lesson03/server.py @@ -0,0 +1,74 @@ +import socket +import json +from config import get_server_socket +s = get_server_socket() +print("Server started") +client, addr = s.accept() +print("Client connected: ",client, addr) + +while True: + print("Waiting data") + + data = json.loads(client.recv(1024).decode("utf-8")) + print("Data received") + + if "exit" not in data: + print(data) + else: + client.close() + s.close() + print("Exit") + break + + + + + + +# Присутствие +# Каждый пользователь при подключении к серверу отсылает сервисное сообщение о присутствии — presence с необязательным полем type: +# { +# "action": "presence", +# "time": , +# "type": "status", +# "user": { +# "account_name": "C0deMaver1ck", +# "status": "Yep, I am here!" +# } +# } +# + +# Коды ответов сервера +# JIM-протокол использует коды ошибок HTTP. Перечислим поддерживаемые: +# 1xx — информационные сообщения: +# 100 — базовое уведомление; +# 101 — важное уведомление. +# 2xx — успешное завершение: +# 200 — OK; +# 201 (created) — объект создан; +# 202 (accepted) — подтверждение. +# 4xx — ошибка на стороне клиента: +# 400 — неправильный запрос/JSON-объект; +# 401 — не авторизован; +# 402 — неправильный логин/пароль; +# 403 (forbidden) — пользователь заблокирован; +# 404 (not found) — пользователь/чат отсутствует на сервере; +# 409 (conflict) — уже имеется подключение с указанным логином; +# 410 (gone) — адресат существует, но недоступен (offline). +# 5xx — ошибка на стороне сервера: +# 500 — ошибка сервера. +# Коды ошибок могут быть дополнены новыми. +# +# Сообщения-ответы имеют следующий формат (в зависимости от кода ответа): +# { +# "response": 1xx / 2xx, +# "time": , +# "alert": "message (optional for 2xx codes)" +# } +# +# Или такой: +# { +# "response": 4xx / 5xx, +# "time": , +# "error": "error message (optional)" +# } From 2488c93cb3d47196e20c26bad07a0657f997f245 Mon Sep 17 00:00:00 2001 From: Aleksei Mihalin Date: Tue, 30 Oct 2018 17:15:16 +0300 Subject: [PATCH 3/6] lesson04 - tests --- main.py | 16 ++++++++++++++++ test_main.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100755 main.py create mode 100755 test_main.py diff --git a/main.py b/main.py new file mode 100755 index 0000000..c67283c --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +def get_answer_on_presence(msg): + response = { + "response": 200, + } + + if msg["action"] == "presence": + + response["year_of_birth"] = int(msg["year"]) + + else: + + response["response"] = 400 + + + return response + diff --git a/test_main.py b/test_main.py new file mode 100755 index 0000000..17ba12b --- /dev/null +++ b/test_main.py @@ -0,0 +1,50 @@ +import unittest +import threading +import client +import server +import socket +from config import * + +def create_client(): + s = socket.socket() + s.connect((ADDRESS, PORT)) + # + # s.send(b"Hello") + while True: + pass + +class TestMain(unittest.TestCase): + + def test_send_data(self): + t = threading.Thread(target=create_client, daemon=True) + + t.start() + + s = socket.socket() + s.bind((ADDRESS, PORT)) + s.listen(10) + s.settimeout(3) + + print("Server started") + + try: + + client, addr = s.accept() + data = client.recv(1024) + + self.assertEqual(data, b"Hello") + + + client.close() + s.close() + except socket.timeout as err: + + self.fail("Accept failed") + + + + + + +if __name__ == '__main__': + unittest.main() From 6ad774ccb17cf07c651e28995e26ac9b24c09083 Mon Sep 17 00:00:00 2001 From: Aleksei Mihalin Date: Tue, 6 Nov 2018 20:18:14 +0300 Subject: [PATCH 4/6] lesson04 - logging --- lesson05/01_logging_basic.py | 22 ++++++++ lesson05/02_logging_formatter.py | 21 ++++++++ lesson05/03_use_log_config.py | 23 ++++++++ lesson05/log_config.py | 91 ++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100755 lesson05/01_logging_basic.py create mode 100755 lesson05/02_logging_formatter.py create mode 100755 lesson05/03_use_log_config.py create mode 100755 lesson05/log_config.py diff --git a/lesson05/01_logging_basic.py b/lesson05/01_logging_basic.py new file mode 100755 index 0000000..74a92f6 --- /dev/null +++ b/lesson05/01_logging_basic.py @@ -0,0 +1,22 @@ +# ------- Журналирование (логгирование) с использованием модуля logging ------- +# Базовая настройка + +import logging + +# Быстрая настройка логгирования может быть выполнена так: +logging.basicConfig( + # filename = "app_01.log", + format = "%(levelname)s %(asctime)s %(message)s", + level = logging.DEBUG +) + +# Для использования логгера его нужно получить/создать функцией getLogger +log = logging.getLogger('basic') + +# После этого можно использовать логгирование таким образом +log.debug('There will be debug information') +log.info('Hello, World!') +log.warning('It seems to be a bug...') +log.critical('Critical bug in app! Hello, World!') + +# Обратите внимание, что не все сообщения попали в лог-файл. Почему? diff --git a/lesson05/02_logging_formatter.py b/lesson05/02_logging_formatter.py new file mode 100755 index 0000000..d5f7f11 --- /dev/null +++ b/lesson05/02_logging_formatter.py @@ -0,0 +1,21 @@ +# ------- Журналирование (логгирование) с использованием модуля logging ------- +# Расширенная настройка настройка. Форматирование, обработчики + +import logging +import sys + +# Определить формат сообщений +_format = logging.Formatter("%(levelname)-10s %(asctime)s %(message)s") + +# Создать обработчик, который выводит сообщения с уровнем CRITICAL в поток stderr +crit_hand = logging.StreamHandler(sys.stderr) +crit_hand.setLevel(logging.CRITICAL) +crit_hand.setFormatter(_format) + +# Создать регистратор +log = logging.getLogger('basic') + +# Добавить обработчик к регистратору +log.addHandler(crit_hand) +# Передать сообщение обработчику +log.critical('Oghr! Kernel panic!') \ No newline at end of file diff --git a/lesson05/03_use_log_config.py b/lesson05/03_use_log_config.py new file mode 100755 index 0000000..499aba4 --- /dev/null +++ b/lesson05/03_use_log_config.py @@ -0,0 +1,23 @@ +# ------- Журналирование (логгирование) с использованием модуля logging ------- +# Вынесение настройки логгирования в отдельный модуль + + +import logging + +import log_config + +# Обратите внимание, логгер уже создан в модуле log_config, +# теперь нужно его просто получить +log = logging.getLogger('app.main') + +def main(): + ''' Тестовая главная функция + ''' + # logger.debug('Старт приложения') + log.debug('There will be debug information') + log.info('Hello, World!') + log.warning('It seems to be a bug...') + log.critical('Critical bug in app! Hello, World!') + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/lesson05/log_config.py b/lesson05/log_config.py new file mode 100755 index 0000000..67c9e85 --- /dev/null +++ b/lesson05/log_config.py @@ -0,0 +1,91 @@ + +# ---- Пример настройки логгирования для приложения, используя logging ---- + +# * Logging Cookbook: https://docs.python.org/3/howto/logging-cookbook.html + +# logging - стандартный модуль для организации логгирования +import logging +import sys + +# Быстрая настройка логгирования может быть выполнена так: +# logging.basicConfig(filename="gui.log", +# format="%(levelname)-10s %(asctime)s %(message)s", +# level = logging.INFO +# ) + +# Можно выполнить более расширенную настройку логгирования. +# Создаём объект-логгер с именем db_admin_gui: +logger = logging.getLogger('app.main') + +# Создаём объект форматирования: +formatter = logging.Formatter("%(levelname)s %(asctime)s %(message)s") + +# Возможные настройки для форматирования: +# ----------------------------------------------------------------------------- +# | Формат | Описание +# ----------------------------------------------------------------------------- +# | %(name)s | Имя регистратора. +# | %(levelno)s | Числовой уровень важности. +# | %(levelname)s | Символическое имя уровня важности. +# | %(pathname)s | Путь к исходному файлу, откуда была выполнена запись в журнал. +# | %(filename)s | Имя исходного файла, откуда была выполнена запись в журнал. +# | %(funcName)s | Имя функции, выполнившей запись в журнал. +# | %(module)s | Имя модуля, откуда была выполнена запись в журнал. +# | %(lineno)d | Номер строки, откуда была выполнена запись в журнал. +# | %(created)f | Время, когда была выполнена запись в журнал. Значением +# | | должно быть число, такое как возвращаемое функцией time.time(). +# | %(asctime)s | Время в формате ASCII, когда была выполнена запись в журнал. +# | %(msecs)s | Миллисекунда, когда была выполнена запись в журнал. +# | %(thread)d | Числовой идентификатор потока выполнения. +# | %(threadName)s | Имя потока выполнения. +# | %(process)d | Числовой идентификатор процесса. +# | %(message)s | Текст журналируемого сообщения (определяется пользователем). +# ----------------------------------------------------------------------------- + +# Создаём файловый обработчик логгирования (можно задать кодировку): +fh = logging.FileHandler("app.main.log", encoding='utf-8') +fh.setLevel(logging.DEBUG) +fh.setFormatter(formatter) + + +# Создать обработчик, который выводит сообщения с уровнем CRITICAL в поток stderr +crit_hand = logging.StreamHandler(sys.stderr) +crit_hand.setLevel(logging.CRITICAL) +crit_hand.setFormatter(formatter) + + +# Добавляем в логгер новый обработчик событий и устанавливаем уровень логгирования +logger.addHandler(fh) +logger.setLevel(logging.DEBUG) + +# Возможные уровни логгирования: +# ----------------------------------------------------------------------------- +# | Уровень важности | Использование +# ----------------------------------------------------------------------------- +# | CRITICAL | log.critical(fmt [, *args [, exc_info [, extra]]]) +# | ERROR | log.error(fmt [, *args [, exc_info [, extra]]]) +# | WARNING | log.warning(fmt [, *args [, exc_info [, extra]]]) +# | INFO | log.info(fmt [, *args [, exc_info [, extra]]]) +# | DEBUG | log.debug(fmt [, *args [, exc_info [, extra]]]) +# ----------------------------------------------------------------------------- +console = logging.StreamHandler() +console.setLevel(logging.DEBUG) +console.setFormatter(formatter) + +logger.addHandler(console) + + +if __name__ == '__main__': + # Создаём потоковый обработчик логгирования (по умолчанию sys.stderr): + + # В логгирование передаем имя текущей функции и имя вызвавшей функции + + + + ''' Тестовая главная функция + ''' + # logger.debug('Старт приложения') + logger.debug('There will be debug information') + logger.info('Hello, World!') + logger.warning('It seems to be a bug...') + logger.critical('Critical bug in app! Hello, World!') From 71cda86e0c5060d43c87d9ee395d4b1a6d9c4488 Mon Sep 17 00:00:00 2001 From: Aleksei Mihalin Date: Tue, 6 Nov 2018 23:13:32 +0300 Subject: [PATCH 5/6] lesson06 - DECORATOR --- lesson06/main.py | 416 ++++++++++++++++++++++++++++++++ lesson06/main2.py | 13 + lesson06/when_deco_is_called.py | 47 ++++ 3 files changed, 476 insertions(+) create mode 100755 lesson06/main.py create mode 100755 lesson06/main2.py create mode 100755 lesson06/when_deco_is_called.py diff --git a/lesson06/main.py b/lesson06/main.py new file mode 100755 index 0000000..bc64fa4 --- /dev/null +++ b/lesson06/main.py @@ -0,0 +1,416 @@ +# # def f(): +# # print("Hello") +# # +# # def aa(): +# # print("AA") +# # +# # return aa +# # +# # +# # def d(): +# # f() +# # print("World!") +# # +# # +# # a = f +# # +# # d = a() +# # d() +# +# +# +# +# +# def f(): +# print("Hello") +# +# def decorator(func): +# def wrapper(): +# print("Before") +# func() +# print("After") +# +# return wrapper +# +# f() +# f = decorator(f) +# f() +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# import time +# +# def my_sum(a, b): +# time.sleep(1) +# return a + b +# +# +# cargo = dict() +# +# +# def caching(func): +# def wrapper(a, b): +# if (a, b) in cargo: +# return cargo[(a, b)] +# +# ret = func(a, b) +# +# cargo[(a, b)] = ret +# +# return ret +# +# return wrapper +# +# +# my_sum = caching(my_sum) +# +# +# for i in range(5): +# print(".") +# my_sum(1,2) + +# +# import time +# +# +# def my_sum(a, b): +# time.sleep(1) +# return a + b +# +# +# def my_sum_v2(a, b, c): +# time.sleep(1) +# return a + b + c +# +# +# cargo = dict() +# +# +# def caching(func): +# def wrapper(a, b): +# if (a, b) in cargo: +# return cargo[(a, b)] +# +# ret = func(a, b) +# +# cargo[(a, b)] = ret +# +# return ret +# +# return wrapper +# +# +# def caching_v2(func): +# def wrapper(a, b, c): +# if (a, b, c) in cargo: +# return cargo[(a, b, c)] +# +# ret = func(a, b, c) +# +# cargo[(a, b, c)] = ret +# +# return ret +# +# return wrapper +# +# +# my_sum = caching(my_sum) +# my_sum = caching_v2(my_sum_v2) +# +# for i in range(5): +# print(".") +# my_sum(1, 2) + + +# import time +# +# +# def my_sum(a, b): +# time.sleep(1) +# return a + b +# +# +# def my_sum_v2(a, b, c): +# time.sleep(1) +# return a + b + c +# +# +# cargo = dict() +# +# +# def caching(func): +# def wrapper(*args): +# +# if args in cargo: +# return cargo[args] +# +# ret = func(*args) +# +# cargo[args] = ret +# +# return ret +# +# return wrapper +# +# +# my_sum = caching(my_sum) +# my_sum_v2 = caching(my_sum_v2) +# +# for i in range(5): +# print(".") +# my_sum(1, 2) + + +# import time +# +# cargo = dict() +# +# +# def caching(func): +# def wrapper(*args): +# if args in cargo: +# return cargo[args] +# +# ret = func(*args) +# +# cargo[args] = ret +# +# return ret +# +# return wrapper +# +# +# @caching +# def my_sum(a, b): +# time.sleep(1) +# return a + b +# +# +# @caching +# def my_sum_v2(a, b, c): +# time.sleep(1) +# return a + b + c +# +# +# for i in range(5): +# print(".") +# my_sum(1, 2) + + +# def log_param(msg): +# def log(func): +# def wrapper(*args): +# func(*args) +# print(msg) +# +# return wrapper +# +# return log +# +# +# @log_param("My sum log") +# def my_sum(a, b): +# return a + b +# +# # my_sum = log_param("My sum log")(my_sum) +# +# +# @log_param("My sumv2 log") +# def my_sum_v2(a, b, c): +# return a + b + c +# +# +# my_sum(1, 2) +# my_sum_v2(1, 2, 4) + +# +# def set_bold(func): +# def wrapper(*args): +# return f"{func(*args)}" +# +# return wrapper +# +# +# def set_italic(func): +# def wrapper(*args): +# return f"{func(*args)}" +# +# return wrapper +# +# +# def add_br(func): +# def wrapper(*args): +# return f"{func(*args)}
" +# +# return wrapper +# +# +# # +# # @set_italic +# # @set_bold +# # @add_br +# # def get_name(name): +# # return f"{name}" +# +# def get_name(name): +# return f"{name}" +# +# +# get_name = set_italic(set_bold(add_br(get_name))) +# +# print(get_name("Andrey")) + + +# +# def set_bold(func): +# def wrapper(*args): +# return f"{func(*args)}" +# +# return wrapper +# +# +# def set_italic(func): +# def wrapper(*args): +# func(*args) +# +# return wrapper +# +# +# def add_br(func): +# def wrapper(*args): +# return f"{func(*args)}
" +# +# return wrapper +# +# +# # +# @set_bold +# @set_italic +# @add_br +# def get_name(name): +# return f"{name}" +# +# # def get_name(name): +# # return f"{name}" +# # +# # +# # get_name = set_italic(set_bold(add_br(get_name))) +# +# print(get_name("Andrey")) +# +# + + +# import when_deco_is_called +# +# @when_deco_is_called.register +# def ff(): +# pass + + +# class Log: +# def __init__(self, msg): +# self.msg = msg +# +# def __call__(self, func): +# def wrapper(*args): +# func(*args) +# print(self.msg) +# +# return wrapper +# +# +# @Log("Andrey") +# @Log("World!") +# def f(): +# print("Hello") +# +# +# f() + + +# import sys +# s = dict() +# +# print(sys.getsizeof(s)) + + +# -------------------- SOCKETS ------------------------------------ + + +# import socket +# import threading +# +# s = socket.socket() +# +# s.bind(("", 9090)) +# s.listen(5) + + +# def read_data(client): +# while True: +# print("recv ", end=" ") +# data = client.recv(1024) +# print(data) +# +# +# while True: +# print("Pre accept") +# client, addr = s.accept() +# +# threading.Thread(target=read_data, args=(client,)).start() + + +import select +import socket + +s = socket.socket() + +s.bind(("", 9090)) +s.listen(5) +s.settimeout(0) + +clients = [] + +while True: + print("Pre accept") + + try: + client, addr = s.accept() + + clients.append(client) + + except: + pass + + if len(clients) > 0: + r, w, e = select.select(clients, clients, clients) + + for i in r: + data = i.recv(1024) + print(data) + + for i in w: + i.send(b"Hello") diff --git a/lesson06/main2.py b/lesson06/main2.py new file mode 100755 index 0000000..e118f44 --- /dev/null +++ b/lesson06/main2.py @@ -0,0 +1,13 @@ +import socket + + +s = socket.socket() +s.connect(("localhost", 9090)) +print("Connected") + +while True: + print('sending') + s.send(b"World") + + + diff --git a/lesson06/when_deco_is_called.py b/lesson06/when_deco_is_called.py new file mode 100755 index 0000000..2a5601b --- /dev/null +++ b/lesson06/when_deco_is_called.py @@ -0,0 +1,47 @@ + +# -------------------- Декораторы. Когда выполняется декоратор? --------------------------- + +# Рассмотрим пример, который позволит отследить момент выполнения декоратора + +registry = [] # Список-реестр "зарегистрированных" функций + +# Создадим демонстрационный декоратор +def register(func): + ''' Декоратор, регистрирующий функции в неком "реестре" + ''' + print(' running register ( %s ) ' % func) + registry.append(func) + # Возвращается та же функция, что была передана в декоратор + # На практике декоратор обычно определяет внутреннюю функцию и возвращает именно ее + return func + +# Теперь создадим функции, которые могут быть декорированы: + +@register +def f1() : + print ('running f1()') + +@register +def f2() : + print ('running f2()') + +# Намеренно декорируем не все функции + +def f3(): + print( 'running f3() ' ) + + +def main(): + print (' running main()' ) + # Выведем список "зарегистрированных" функций + print (' registry ->' , registry) + + # Теперь просто выполним все функции + f1() + f2() + f3() + + +if __name__ == '__main__': + main() + \ No newline at end of file From d34362e10f902a48dec9ebb3188091390632bb13 Mon Sep 17 00:00:00 2001 From: Aleksei Mihalin Date: Wed, 23 Jan 2019 16:59:46 +0300 Subject: [PATCH 6/6] lesson08 - threading --- lesson08/main.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 lesson08/main.py diff --git a/lesson08/main.py b/lesson08/main.py new file mode 100644 index 0000000..06975ce --- /dev/null +++ b/lesson08/main.py @@ -0,0 +1,77 @@ +import threading +import time +from multiprocessing import Process, Queue + + +# def f(duration, s, queue): +# i = 0 +# while True: +# queue.put(i) +# i += 1 +# time.sleep(duration) +# +# +# if __name__ == '__main__': +# q = Queue() +# t = Process(target=f, args=(3, "first", q)) +# t.daemon = True +# +# t.start() +# +# while True: +# print("Get from queue") +# print(q.get()) +# +# +# # GIL +# # Global Interpretator Lock +# +# +# class MyThread(threading.Thread): +# +# def __init__(self, duration): +# super().__init__() +# self.duration = duration +# +# def run(self): +# for i in range(10): +# time.sleep(self.duration) +# print("Inside thread") +# +# +# a = MyThread(0.5) +# +# a.start() +# +# def f(duration, s): +# while True: +# print(f"Hello from {s} thread") +# #t = threading.Thread() +# time.sleep(duration) +# +# def g(): +# for i in range(10): +# time.sleep(0.3) +# print("Inside thread") +# +# +# # t = threading.Thread(target=f, args=(3,"first"), daemon=True) +# t2 = threading.Thread(target=g, daemon=True) +# +# # t.start() +# t2.start() +# # +# # print(t2.name) +# # print(t2.is_alive()) +# # print(t2.isDaemon()) +# # print(t2.ident) +# # +# # t2.setName("MyThread") +# # print(t2.name) +# # +# # t2.join() +# # +# # t2.setDaemon(False) +# # +# # print(t2.is_alive()) +# # a = input("Input data: ")