diff --git a/hw1_oop/HW1_python2_OOP.ipynb b/hw1_oop/HW1_python2_OOP.ipynb new file mode 100644 index 0000000..2372154 --- /dev/null +++ b/hw1_oop/HW1_python2_OOP.ipynb @@ -0,0 +1,849 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7c5a538f-2dbe-445c-9f46-cf0dc18867e4", + "metadata": {}, + "source": [ + "#### Задание 1 (5 баллов)" + ] + }, + { + "cell_type": "markdown", + "id": "1e8cc3b0-6f60-40da-8058-30d9eb434daf", + "metadata": {}, + "source": [ + "Напишите классы **Chat**, **Message** и **User**. Они должны соответствовать следующим требованиям:\n", + "\n", + "**Chat**:\n", + "+ Должен иметь атрибут `chat_history`, где будут храниться все сообщения (`Message`) в обратном хронологическом порядке (сначала новые, затем старые)\n", + "+ Должен иметь метод `show_last_message`, выводящий на экран информацию о последнем сообщении\n", + "+ Должен иметь метод `get_history_from_time_period`, который принимает два опциональных аргумента (даты с которой и по какую мы ищем сообщения и выдаём их). Метод также должен возвращать объект типа `Chat`\n", + "+ Должен иметь метод `show_chat`, выводящий на экран все сообщения (каждое сообщение в таком же виде как и `show_last_message`, но с разделителем между ними)\n", + "+ Должен иметь метод `recieve`, который будет принимать сообщение и добавлять его в чат\n", + "\n", + "**Message**:\n", + "+ Должен иметь три обязательных атрибута\n", + " + `text` - текст сообщения\n", + " + `datetime` - дата и время сообщения (встроенный модуль datetime вам в помощь). Важно! Это должна быть не дата создания сообщения, а дата его попадания в чат! \n", + " + `user` - информация о пользователе, который оставил сообщение (какой тип данных использовать здесь, разберётесь сами)\n", + "+ Должен иметь метод `show`, который печатает или возвращает информацию о сообщении с необходимой информацией (дата, время, юзер, текст)\n", + "+ Должен иметь метод `send`, который будет отправлять сообщение в чат\n", + "\n", + "**User**:\n", + "+ Класс с информацией о юзере, наполнение для этого класса придумайте сами\n", + "\n", + "Напишите несколько примеров использования кода, которое показывает взаимодействие между объектами.\n", + "\n", + "В тексте задания намерено не указано, какие аргументы должны принимать методы, пускай вам в этом поможет здравый смысл)\n", + "\n", + "В этом задании не стоит флексить всякими продвинутыми штуками, для этого есть последующие\n", + "\n", + "В этом задании можно использовать только модуль `datetime`" + ] + }, + { + "cell_type": "code", + "execution_count": 777, + "id": "3478b96c", + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "\n", + "\n", + "class Chat:\n", + " default_start = datetime(1970, 1, 1)\n", + " \n", + " def __init__(self):\n", + " self._chat_history = [] # List of all messages in chat\n", + " \n", + " def show_last_message(self):\n", + " last_message = self._chat_history[0]\n", + " print(last_message.show())\n", + " \n", + " def get_history_from_time_period(self, start=None, end=None):\n", + " if start is None:\n", + " start = self.default_start\n", + " if end is None:\n", + " end = datetime.now()\n", + " self.start = start\n", + " self.end = end\n", + " \n", + " for message in self._chat_history:\n", + " if self.end >= message.datetime >= self.start:\n", + " print(message.show()) \n", + " \n", + " def show_chat(self, separator='\\n'):\n", + " print(*[message.show() for message in self._chat_history], sep=separator)\n", + " \n", + " def _recieve(self, message):\n", + " if isinstance(message, Message):\n", + " message.datetime = datetime.now() # Set attribute datetime when message is recieved by chat\n", + " self._chat_history.insert(0, message)\n", + "\n", + "\n", + "class Message:\n", + " def __init__(self, text, user):\n", + " self.user = user\n", + " self.text = text \n", + " self.datetime = None # Will set this attribute after sending message to chat\n", + " \n", + " def show(self):\n", + " if self.datetime:\n", + " return f'{self.datetime} {self.user}: {self.text}'\n", + " else:\n", + " return f'{self.user}: {self.text}'\n", + " \n", + " def send(self, chat):\n", + " if isinstance(chat, Chat):\n", + " chat._recieve(self)\n", + "\n", + " \n", + "class User:\n", + " all_users = [] # List of all objects of class User\n", + " \n", + " def __init__(self, login, name='Unknown', city='Unknown', birthdate='Unknown'):\n", + " self.login = login\n", + " self.name = name\n", + " self.city = city\n", + " self.birthdate = birthdate\n", + " self.history = None # Add method for this later!\n", + " self.all_users.append(self)\n", + " \n", + " def print_user_info(self): # Print all information about user\n", + " print(f'User: {self.login}\\nName: {self.name}\\nCity: {self.city}\\nBirthdate: {self.birthdate}')\n", + " \n", + " def print_all_users():\n", + " for user in User.all_users:\n", + " print(user.login) " + ] + }, + { + "cell_type": "code", + "execution_count": 741, + "id": "6ec6dc99", + "metadata": {}, + "outputs": [], + "source": [ + "# Creating empty chat" + ] + }, + { + "cell_type": "code", + "execution_count": 742, + "id": "2021d845", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "my_chat = Chat()\n", + "my_chat.show_chat()" + ] + }, + { + "cell_type": "code", + "execution_count": 743, + "id": "1995a4f4", + "metadata": {}, + "outputs": [], + "source": [ + "# Creating a couple of messages empty chat" + ] + }, + { + "cell_type": "code", + "execution_count": 744, + "id": "7b05a040", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Amy: Good morning!'" + ] + }, + "execution_count": 744, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "msg1 = Message('Good morning!', 'Amy')\n", + "msg1.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 745, + "id": "3a6ef68a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Kate: Hi!'" + ] + }, + "execution_count": 745, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "msg2 = Message('Hi!', 'Kate')\n", + "msg2.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 746, + "id": "b90824a1", + "metadata": {}, + "outputs": [], + "source": [ + "# Sending msg1 to chat" + ] + }, + { + "cell_type": "code", + "execution_count": 747, + "id": "5565b1e8", + "metadata": {}, + "outputs": [], + "source": [ + "msg1.send(my_chat)" + ] + }, + { + "cell_type": "code", + "execution_count": 748, + "id": "84264e54", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-02-26 14:50:07.937826 Amy: Good morning!\n" + ] + } + ], + "source": [ + "my_chat.show_chat()" + ] + }, + { + "cell_type": "code", + "execution_count": 749, + "id": "fe017d18", + "metadata": {}, + "outputs": [], + "source": [ + "# Sending msg2 to chat" + ] + }, + { + "cell_type": "code", + "execution_count": 750, + "id": "b5d349e6", + "metadata": {}, + "outputs": [], + "source": [ + "msg2.send(my_chat)" + ] + }, + { + "cell_type": "code", + "execution_count": 751, + "id": "e785b559", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-02-26 14:50:10.165374 Kate: Hi!\n", + "2023-02-26 14:50:07.937826 Amy: Good morning!\n" + ] + } + ], + "source": [ + "my_chat.show_chat()" + ] + }, + { + "cell_type": "code", + "execution_count": 752, + "id": "8c506634", + "metadata": {}, + "outputs": [], + "source": [ + "# Getting last message in chat" + ] + }, + { + "cell_type": "code", + "execution_count": 753, + "id": "6e97646a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-02-26 14:50:10.165374 Kate: Hi!\n" + ] + } + ], + "source": [ + "my_chat.show_last_message()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cae81b2c", + "metadata": {}, + "outputs": [], + "source": [ + "# Getting chat history" + ] + }, + { + "cell_type": "code", + "execution_count": 756, + "id": "bd210046", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-02-26 14:50:10.165374 Kate: Hi!\n", + "2023-02-26 14:50:07.937826 Amy: Good morning!\n" + ] + } + ], + "source": [ + "my_chat.get_history_from_time_period()" + ] + }, + { + "cell_type": "code", + "execution_count": 759, + "id": "dcfb6c3e", + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'str' object cannot be interpreted as an integer", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[759], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m my_chat\u001b[38;5;241m.\u001b[39mget_history_from_time_period(end\u001b[38;5;241m=\u001b[39m\u001b[43mdatetime\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m2023-02-26 14:50:08\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m)\n", + "\u001b[0;31mTypeError\u001b[0m: 'str' object cannot be interpreted as an integer" + ] + } + ], + "source": [ + "my_chat.get_history_from_time_period(end=datetime('2023-02-26 14:50:08'))" + ] + }, + { + "cell_type": "code", + "execution_count": 760, + "id": "7ed48969", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-02-26 14:50:10.165374 Kate: Hi!\n", + "2023-02-26 14:50:07.937826 Amy: Good morning!\n" + ] + } + ], + "source": [ + "my_chat.show_chat()" + ] + }, + { + "cell_type": "code", + "execution_count": 764, + "id": "6d034471", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2023-02-26 14:50:10.165374 Kate: Hi!\n", + "||||||\n", + "2023-02-26 14:50:07.937826 Amy: Good morning!\n" + ] + } + ], + "source": [ + "my_chat.show_chat('\\n||||||\\n')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "26786c47", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b538625", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "a59aa1b3-4c93-480e-a09f-e57df34eb60a", + "metadata": {}, + "source": [ + "# Задание 2 (3 балла)" + ] + }, + { + "cell_type": "markdown", + "id": "ab07eb69-877f-4c38-8c7d-88beae20071b", + "metadata": {}, + "source": [ + "В питоне как-то слишком типично и неинтересно происходят вызовы функций. Напишите класс `Args`, который будет хранить в себе аргументы, а функции можно будет вызывать при помощи следующего синтаксиса.\n", + "\n", + "Использовать любые модули **нельзя**, да и вряд-ли это как-то поможет)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "d73d6b31-c15a-4ae6-ad9b-b3fdab88efed", + "metadata": {}, + "outputs": [], + "source": [ + "class Args:\n", + " # Ваш код здесь\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "55afedbb-4725-4078-bd98-bf803be0bf93", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum << Args([1, 2])" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "c37f0728-9bdc-469e-a5b8-3ab5aa43a731", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "53" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(lambda a, b, c: a**2 + b + c) << Args(1, 2, c=50)" + ] + }, + { + "cell_type": "markdown", + "id": "d6915eaf-92fe-460b-bf9b-06ccf55b093f", + "metadata": {}, + "source": [ + "# Задание 3 (5 баллов)" + ] + }, + { + "cell_type": "markdown", + "id": "5a588ef8-8af6-42b6-972b-3c716a604c34", + "metadata": {}, + "source": [ + "Сделайте класс наследник `float`. Он должен вести себя как `float`, но также должен обладать некоторыми особенностями:\n", + "+ При получении атрибутов формата `<действие>_<число>` мы получаем результат такого действия над нашим числом\n", + "+ Создавать данные атрибуты в явном виде, очевидно, не стоит\n", + "\n", + "Подсказка: если в процессе гуглёжки, вы выйдете на такую тему как **\"Дескрипторы\", то это НЕ то, что вам сейчас нужно**\n", + "\n", + "Примеры использования ниже" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "61cb63a2-90ac-4b79-97a5-bb0496262e32", + "metadata": {}, + "outputs": [], + "source": [ + "class StrangeFloat(float):\n", + " # Ваш код здесь\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "id": "f730c9c0-7d90-4037-97c6-e926dcbc1ea3", + "metadata": {}, + "outputs": [], + "source": [ + "number = StrangeFloat(3.5)" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "id": "b2756368-a489-486d-a0f1-244697f8503c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4.5" + ] + }, + "execution_count": 132, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number.add_1" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "id": "c6799592-3cb6-4c7d-af62-9c0a48a76c1d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-16.5" + ] + }, + "execution_count": 133, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number.subtract_20" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "id": "130027b5-017a-4c70-b072-1fdc6acf670f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "17.5" + ] + }, + "execution_count": 134, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number.multiply_5" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "id": "2b901e5c-5a51-4788-b15b-9b20a074e1a4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.14" + ] + }, + "execution_count": 139, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number.divide_25" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "id": "ea52c492-b0ce-4d73-8aba-a0ea51ed0b60", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-4.125" + ] + }, + "execution_count": 136, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number.add_1.add_2.multiply_6.divide_8.subtract_9" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "id": "e26ef411-a5df-46c7-bb9d-e77a1fad3cec", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1.0" + ] + }, + "execution_count": 146, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "getattr(number, \"add_-2.5\") # Используем getattr, так как не можем написать number.add_-2.5 - это SyntaxError" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "7a57bb29-1105-4df1-a4c4-5fbf62eef11d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11.5" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number + 8 # Стандартные для float операции работают также" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f0246b31-c55a-4bb8-ac15-46509bd8b340", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(7, 2)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "number.as_integer_ratio() # Стандартные для float операции работают также (это встроенный метод float, писать его НЕ НАДО)" + ] + }, + { + "cell_type": "markdown", + "id": "3635bceb-723c-4b2f-82e3-269bd914c46c", + "metadata": {}, + "source": [ + "# Задание 4 (3 балла)" + ] + }, + { + "cell_type": "markdown", + "id": "31d35f82-1e20-4bf5-b896-7b8163f8386f", + "metadata": {}, + "source": [ + "В данном задании мы немного отдохнём и повеселимся. От вас требуется заменить в данном коде максимально возможное количество синтаксических конструкций на вызовы dunder методов, dunder атрибутов и dunder переменных.\n", + "\n", + "Маленькая заметка: полностью всё заменить невозможно. Например, `function()` можно записать как `function.__call__()`, но при этом мы всё ещё не избавляемся от скобочек, так что можно делать так до бесконечности `function.__call__.__call__.__call__.__call__.....__call__()` и при всём при этом мы ещё не избавляемся от `.` для доступа к атрибутам. В общем, замените всё, что получится, не закапываясь в повторы, как в приведённом примере. Чем больше разных методов вы найдёте и используете, тем лучше и тем выше будет балл\n", + "\n", + "Код по итогу дожен работать и печатать число **4420.0**, как в примере. Структуру кода менять нельзя, просто изменяем конструкции на синонимичные\n", + "\n", + "И ещё маленькая подсказка. Заменить здесь можно всё кроме:\n", + "+ Конструкции `for ... in ...`:\n", + "+ Синтаксиса создания лямбда функции\n", + "+ Оператора присваивания `=`\n", + "+ Конструкции `if-else`" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "id": "a87cff2a-7168-470d-b38f-1cb5a60ac0c4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4420.0\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "\n", + "matrix = []\n", + "for idx in range(0, 100, 10):\n", + " matrix += [list(range(idx, idx + 10))]\n", + " \n", + "selected_columns_indices = list(filter(lambda x: x in range(1, 5, 2), range(len(matrix))))\n", + "selected_columns = map(lambda x: [x[col] for col in selected_columns_indices], matrix)\n", + "\n", + "arr = np.array(list(selected_columns))\n", + "\n", + "mask = arr[:, 1] % 3 == 0\n", + "new_arr = arr[mask]\n", + "\n", + "product = new_arr @ new_arr.T\n", + "\n", + "if (product[0] < 1000).all() and (product[2] > 1000).any():\n", + " print(product.mean())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e29cc00-c8db-4cc4-a93b-2908352d9344", + "metadata": {}, + "outputs": [], + "source": [ + "# Ваш код здесь" + ] + }, + { + "cell_type": "markdown", + "id": "e90e5938-cabe-4ee1-9a88-73f25b3b67c3", + "metadata": {}, + "source": [ + "# Задание 5 (10 баллов)" + ] + }, + { + "cell_type": "markdown", + "id": "0e58f6a8-7bb8-45f0-b14d-3bcd1f1ba5a9", + "metadata": {}, + "source": [ + "Напишите абстрактный класс `BiologicalSequence`, который задаёт следующий интерфейс:\n", + "+ Работа с функцией `len`\n", + "+ Возможность получать элементы по индексу и делать срезы последовательности (аналогично строкам)\n", + "+ Вывод на печать в удобном виде и возможность конвертации в строку\n", + "+ Возможность проверить алфавит последовательности на корректность\n", + "\n", + "Напишите класс `NucleicAcidSequence`:\n", + "+ Данный класс реализует интерфейс `BiologicalSequence`\n", + "+ Данный класс имеет новый метод `complement`, возвращающий комплементарную последовательность\n", + "+ Данный класс имеет новый метод `gc_content`, возвращающий GC-состав (без разницы, в процентах или в долях)\n", + "\n", + "Напишите классы наследники `NucleicAcidSequence`: `DNASequence` и `RNASequence`\n", + "+ `DNASequence` должен иметь метод `transcribe`, возвращающий транскрибированную РНК-последовательность\n", + "+ Данные классы не должны иметь публичных методов `complement` и метода для проверки алфавита, так как они уже должны быть реализованы в `NucleicAcidSequence`.\n", + "\n", + "Напишите класс `AminoAcidSequence`:\n", + "+ Данный класс реализует интерфейс `BiologicalSequence`\n", + "+ Добавьте этому классу один любой метод, подходящий по смыслу к аминокислотной последовательности. Например, метод для нахождения изоэлектрической точки, молекулярного веса и т.д.\n", + "\n", + "Комментарий по поводу метода `NucleicAcidSequence.complement`, так как я хочу, чтобы вы сделали его опредедённым образом:\n", + "\n", + "При вызове `dna.complement()` или условного `dna.check_alphabet()` должны будут вызываться соответствующие методы из `NucleicAcidSequence`. При этом, данный метод должен обладать свойством полиморфизма, иначе говоря, внутри `complement` не надо делать условия а-ля `if seuqence_type == \"DNA\": return self.complement_dna()`, это крайне не гибко. Данный метод должен опираться на какой-то общий интерфейс между ДНК и РНК. Создание экземпляров `NucleicAcidSequence` не подразумевается, поэтому код `NucleicAcidSequence(\"ATGC\").complement()` не обязан работать, а в идеале должен кидать исключение `NotImplementedError` при вызове от экземпляра `NucleicAcidSequence`\n", + "\n", + "Вся сложность задания в том, чтобы правильно организовать код. Если у вас есть повторяющийся код в сестринских классах или родительском и дочернем, значит вы что-то делаете не так.\n", + "\n", + "\n", + "Маленькое замечание: По-хорошему, между классом `BiologicalSequence` и классами `NucleicAcidSequence` и `AminoAcidSequence`, ещё должен быть класс-прослойка, частично реализующий интерфейс `BiologicalSequence`, но его писать не обязательно, так как задание и так довольно большое (правда из-за этого у вас неминуемо возникнет повторяющийся код в классах `NucleicAcidSequence` и `AminoAcidSequence`)" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "id": "f17d5d3f-9982-4271-a987-3af7bc071c42", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "\n", + "# Ваш код здесь" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/hw1_oop/HW1_python2_OOP.py b/hw1_oop/HW1_python2_OOP.py new file mode 100644 index 0000000..b459752 --- /dev/null +++ b/hw1_oop/HW1_python2_OOP.py @@ -0,0 +1,68 @@ +from datetime import datetime + + +class Chat: + default_start = datetime(1970, 1, 1) + + def __init__(self): + self._chat_history = [] # List of all messages in chat + + def show_last_message(self): + last_message = self._chat_history[0] + print(last_message.show()) + + def get_history_from_time_period(self, start=None, end=None): + if start is None: + start = self.default_start + if end is None: + end = datetime.now() + self.start = start + self.end = end + + for message in self._chat_history: + if self.end >= message.datetime >= self.start: + print(message.show()) + + def show_chat(self, separator='\n'): + print(*[message.show() for message in self._chat_history], sep=separator) + + def _recieve(self, message): + if isinstance(message, Message): + message.datetime = datetime.now() # Set attribute datetime when message is recieved by chat + self._chat_history.insert(0, message) + + +class Message: + def __init__(self, text, user): + self.user = user + self.text = text + self.datetime = None # Will set this attribute after sending message to chat + + def show(self): + if self.datetime: + return f'{self.datetime} {self.user}: {self.text}' + else: + return f'{self.user}: {self.text}' + + def send(self, chat): + if isinstance(chat, Chat): + chat._recieve(self) + + +class User: + all_users = [] # List of all objects of class User + + def __init__(self, login, name='Unknown', city='Unknown', birthdate='Unknown'): + self.login = login + self.name = name + self.city = city + self.birthdate = birthdate + self.history = None # Add method for this later! + self.all_users.append(self) + + def print_user_info(self): # Print all information about user + print(f'User: {self.login}\nName: {self.name}\nCity: {self.city}\nBirthdate: {self.birthdate}') + + def print_all_users(): + for user in User.all_users: + print(user.login) \ No newline at end of file diff --git a/hw1_oop/README.md b/hw1_oop/README.md new file mode 100644 index 0000000..e69de29