1"""
2[Title/Звание]
3Хотел Неврокоп
4
5[Description/Обрисовка]
6Хотел Неврокоп е удобно приложение за управление на малък хотел, но уютен, хотел разположен в град Гоце Делчев.
7Системата позволява съхраняване и управление на информация за хотелски стаи, гости и резервации.
8Чрез приложението служителите могат бързо да проверяват кои стаи са свободни, кои гости са настанени и какви
9резервации има за определен период.
10
11[Functionalities/Надарености]
12Когато се стратира системата, на потребителя му излизат опции, потребителят въвежда своя избор чрез индексът на
13съответната опция.
14Потребителят може да добавя нови хотелски стаи с информация за номер, тип и капацитет.
15Потребителят може да разглежда списък с всички налични стаи.
16Потребителят може да добавя гости с име, телефон и имейл адрес.
17Приложението съхранява информацията за всеки гост в отделен списък.
18Потребителят може да създава резервации, като избира гост, стая и период на настаняване.
19Системата проверява дали избраната стая е свободна за съответния период.
20Потребителят може да разглежда всички активни резервации.
21Приложението позволява редактиране и изтриване на резервации.
22За всяка информация, която въведе потребителят, ще има валидаращи функции, проверяващи коректността да въведените данни.
23
24[Milestones/Възлови точки]
25
26Създаване на основна структура на проекта
27Организация на файловете и класовете
28Създаване на основни модели за стаи, гости и резервации
29Модул за управление на стаи
30Добавяне на стаи
31Преглед на списък със стаи
32Изтриване и редактиране на стаи
33Модул за управление на гости
34Добавяне на гости
35Преглед на гости
36Редактиране на информация за гост
37Модул за управление на резервации
38Създаване на резервация
39Проверка за свободна стая
40Изтриване и редактиране на резервации
41"бутони"
42
43[Estimate in man-hours/Времеоценка в човекочасове]
44Около 60 часа.
45
46[Usage of technologies/Потребление на технологии]
47Организация на проекта – Python OOP (класове и обекти)
48Допълнителни библиотеки – datetime за работа с дати и резервации.
49"""
----------------------------------------------------------------------
Ran 0 tests in 0.000s
NO TESTS RAN
Виктор Бечев
17.05.2026 14:50Няколко въпроса остават след прочит на описанието на идеята ти:
1. Какъв е интерфейсът тук? Десктоп приложение, уеб приложение, мобилно приложение?
2. Представи си, че интерфейсът няма значение. Само като код. Колко код очакваш да има? Защото аз си представям следното:
```
class Room:
# number, type, capacity
def reserve(...): ...
class Guest:
# whatever guest information
class Reservation:
# possibly, may even not be necessary
```
Образно казано, мисълта ми е, ако го сведеш до брой класове и функции, ще излезе колкото едно домашно, вероятно от по-ранните. От къде би дошла сложността?
3. Ще имаш ли някакво persistency? База данни, нещо друго?
С други думи - така изглеждащ проектът ти може да звучи добре като набор от функционалности на хартия, но може да се сведе до няколко класа, метода и тук таме някой списък / речник.
Ако не си сигурна как да отговориш на тези въпроси - ела да си поговорим в някоя почивка.
|
| f | 1 | """ | f | 1 | """ |
| 2 | [Title/Звание] | 2 | [Title/Звание] | ||
| 3 | Хотел Неврокоп | 3 | Хотел Неврокоп | ||
| 4 | 4 | ||||
| 5 | [Description/Обрисовка] | 5 | [Description/Обрисовка] | ||
| 6 | Хотел Неврокоп е удобно приложение за управление на малък хотел, но уютен, хотел разположен в град Гоце Делчев. | 6 | Хотел Неврокоп е удобно приложение за управление на малък хотел, но уютен, хотел разположен в град Гоце Делчев. | ||
| 7 | Системата позволява съхраняване и управление на информация за хотелски стаи, гости и резервации. | 7 | Системата позволява съхраняване и управление на информация за хотелски стаи, гости и резервации. | ||
| 8 | Чрез приложението служителите могат бързо да проверяват кои стаи са свободни, кои гости са настанени и какви | 8 | Чрез приложението служителите могат бързо да проверяват кои стаи са свободни, кои гости са настанени и какви | ||
| 9 | резервации има за определен период. | 9 | резервации има за определен период. | ||
| 10 | 10 | ||||
| 11 | [Functionalities/Надарености] | 11 | [Functionalities/Надарености] | ||
| 12 | Когато се стратира системата, на потребителя му излизат опции, потребителят въвежда своя избор чрез индексът на | 12 | Когато се стратира системата, на потребителя му излизат опции, потребителят въвежда своя избор чрез индексът на | ||
| 13 | съответната опция. | 13 | съответната опция. | ||
| 14 | Потребителят може да добавя нови хотелски стаи с информация за номер, тип и капацитет. | 14 | Потребителят може да добавя нови хотелски стаи с информация за номер, тип и капацитет. | ||
| 15 | Потребителят може да разглежда списък с всички налични стаи. | 15 | Потребителят може да разглежда списък с всички налични стаи. | ||
| 16 | Потребителят може да добавя гости с име, телефон и имейл адрес. | 16 | Потребителят може да добавя гости с име, телефон и имейл адрес. | ||
| 17 | Приложението съхранява информацията за всеки гост в отделен списък. | 17 | Приложението съхранява информацията за всеки гост в отделен списък. | ||
| 18 | Потребителят може да създава резервации, като избира гост, стая и период на настаняване. | 18 | Потребителят може да създава резервации, като избира гост, стая и период на настаняване. | ||
| 19 | Системата проверява дали избраната стая е свободна за съответния период. | 19 | Системата проверява дали избраната стая е свободна за съответния период. | ||
| 20 | Потребителят може да разглежда всички активни резервации. | 20 | Потребителят може да разглежда всички активни резервации. | ||
| 21 | Приложението позволява редактиране и изтриване на резервации. | 21 | Приложението позволява редактиране и изтриване на резервации. | ||
| 22 | За всяка информация, която въведе потребителят, ще има валидаращи функции, проверяващи коректността да въведените данни. | 22 | За всяка информация, която въведе потребителят, ще има валидаращи функции, проверяващи коректността да въведените данни. | ||
| 23 | 23 | ||||
| 24 | [Milestones/Възлови точки] | 24 | [Milestones/Възлови точки] | ||
| 25 | 25 | ||||
| 26 | Създаване на основна структура на проекта | 26 | Създаване на основна структура на проекта | ||
| 27 | Организация на файловете и класовете | 27 | Организация на файловете и класовете | ||
| 28 | Създаване на основни модели за стаи, гости и резервации | 28 | Създаване на основни модели за стаи, гости и резервации | ||
| 29 | Модул за управление на стаи | 29 | Модул за управление на стаи | ||
| 30 | Добавяне на стаи | 30 | Добавяне на стаи | ||
| 31 | Преглед на списък със стаи | 31 | Преглед на списък със стаи | ||
| 32 | Изтриване и редактиране на стаи | 32 | Изтриване и редактиране на стаи | ||
| 33 | Модул за управление на гости | 33 | Модул за управление на гости | ||
| 34 | Добавяне на гости | 34 | Добавяне на гости | ||
| 35 | Преглед на гости | 35 | Преглед на гости | ||
| 36 | Редактиране на информация за гост | 36 | Редактиране на информация за гост | ||
| 37 | Модул за управление на резервации | 37 | Модул за управление на резервации | ||
| 38 | Създаване на резервация | 38 | Създаване на резервация | ||
| 39 | Проверка за свободна стая | 39 | Проверка за свободна стая | ||
| 40 | Изтриване и редактиране на резервации | 40 | Изтриване и редактиране на резервации | ||
| 41 | "бутони" | 41 | "бутони" | ||
| 42 | 42 | ||||
| 43 | [Estimate in man-hours/Времеоценка в човекочасове] | 43 | [Estimate in man-hours/Времеоценка в човекочасове] | ||
| t | 44 | Около 30 часа. | t | 44 | Около 60 часа. |
| 45 | 45 | ||||
| 46 | [Usage of technologies/Потребление на технологии] | 46 | [Usage of technologies/Потребление на технологии] | ||
| 47 | Организация на проекта – Python OOP (класове и обекти) | 47 | Организация на проекта – Python OOP (класове и обекти) | ||
| 48 | Допълнителни библиотеки – datetime за работа с дати и резервации. | 48 | Допълнителни библиотеки – datetime за работа с дати и резервации. | ||
| 49 | """ | 49 | """ |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| t | 1 | """ | t | 1 | """ |
| 2 | [Title/Звание] | 2 | [Title/Звание] | ||
| 3 | Хотел Неврокоп | 3 | Хотел Неврокоп | ||
| 4 | 4 | ||||
| 5 | [Description/Обрисовка] | 5 | [Description/Обрисовка] | ||
| 6 | Хотел Неврокоп е удобно приложение за управление на малък хотел, но уютен, хотел разположен в град Гоце Делчев. | 6 | Хотел Неврокоп е удобно приложение за управление на малък хотел, но уютен, хотел разположен в град Гоце Делчев. | ||
| 7 | Системата позволява съхраняване и управление на информация за хотелски стаи, гости и резервации. | 7 | Системата позволява съхраняване и управление на информация за хотелски стаи, гости и резервации. | ||
| 8 | Чрез приложението служителите могат бързо да проверяват кои стаи са свободни, кои гости са настанени и какви | 8 | Чрез приложението служителите могат бързо да проверяват кои стаи са свободни, кои гости са настанени и какви | ||
| 9 | резервации има за определен период. | 9 | резервации има за определен период. | ||
| 10 | 10 | ||||
| 11 | [Functionalities/Надарености] | 11 | [Functionalities/Надарености] | ||
| 12 | Когато се стратира системата, на потребителя му излизат опции, потребителят въвежда своя избор чрез индексът на | 12 | Когато се стратира системата, на потребителя му излизат опции, потребителят въвежда своя избор чрез индексът на | ||
| 13 | съответната опция. | 13 | съответната опция. | ||
| 14 | Потребителят може да добавя нови хотелски стаи с информация за номер, тип и капацитет. | 14 | Потребителят може да добавя нови хотелски стаи с информация за номер, тип и капацитет. | ||
| 15 | Потребителят може да разглежда списък с всички налични стаи. | 15 | Потребителят може да разглежда списък с всички налични стаи. | ||
| 16 | Потребителят може да добавя гости с име, телефон и имейл адрес. | 16 | Потребителят може да добавя гости с име, телефон и имейл адрес. | ||
| 17 | Приложението съхранява информацията за всеки гост в отделен списък. | 17 | Приложението съхранява информацията за всеки гост в отделен списък. | ||
| 18 | Потребителят може да създава резервации, като избира гост, стая и период на настаняване. | 18 | Потребителят може да създава резервации, като избира гост, стая и период на настаняване. | ||
| 19 | Системата проверява дали избраната стая е свободна за съответния период. | 19 | Системата проверява дали избраната стая е свободна за съответния период. | ||
| 20 | Потребителят може да разглежда всички активни резервации. | 20 | Потребителят може да разглежда всички активни резервации. | ||
| 21 | Приложението позволява редактиране и изтриване на резервации. | 21 | Приложението позволява редактиране и изтриване на резервации. | ||
| 22 | За всяка информация, която въведе потребителят, ще има валидаращи функции, проверяващи коректността да въведените данни. | 22 | За всяка информация, която въведе потребителят, ще има валидаращи функции, проверяващи коректността да въведените данни. | ||
| 23 | 23 | ||||
| 24 | [Milestones/Възлови точки] | 24 | [Milestones/Възлови точки] | ||
| 25 | 25 | ||||
| 26 | Създаване на основна структура на проекта | 26 | Създаване на основна структура на проекта | ||
| 27 | Организация на файловете и класовете | 27 | Организация на файловете и класовете | ||
| 28 | Създаване на основни модели за стаи, гости и резервации | 28 | Създаване на основни модели за стаи, гости и резервации | ||
| 29 | Модул за управление на стаи | 29 | Модул за управление на стаи | ||
| 30 | Добавяне на стаи | 30 | Добавяне на стаи | ||
| 31 | Преглед на списък със стаи | 31 | Преглед на списък със стаи | ||
| 32 | Изтриване и редактиране на стаи | 32 | Изтриване и редактиране на стаи | ||
| 33 | Модул за управление на гости | 33 | Модул за управление на гости | ||
| 34 | Добавяне на гости | 34 | Добавяне на гости | ||
| 35 | Преглед на гости | 35 | Преглед на гости | ||
| 36 | Редактиране на информация за гост | 36 | Редактиране на информация за гост | ||
| 37 | Модул за управление на резервации | 37 | Модул за управление на резервации | ||
| 38 | Създаване на резервация | 38 | Създаване на резервация | ||
| 39 | Проверка за свободна стая | 39 | Проверка за свободна стая | ||
| 40 | Изтриване и редактиране на резервации | 40 | Изтриване и редактиране на резервации | ||
| 41 | "бутони" | 41 | "бутони" | ||
| 42 | 42 | ||||
| 43 | [Estimate in man-hours/Времеоценка в човекочасове] | 43 | [Estimate in man-hours/Времеоценка в човекочасове] | ||
| 44 | Около 30 часа. | 44 | Около 30 часа. | ||
| 45 | 45 | ||||
| 46 | [Usage of technologies/Потребление на технологии] | 46 | [Usage of technologies/Потребление на технологии] | ||
| 47 | Организация на проекта – Python OOP (класове и обекти) | 47 | Организация на проекта – Python OOP (класове и обекти) | ||
| 48 | Допълнителни библиотеки – datetime за работа с дати и резервации. | 48 | Допълнителни библиотеки – datetime за работа с дати и резервации. | ||
| 49 | """ | 49 | """ |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| t | 1 | import importlib | t | 1 | import importlib |
| 2 | import re | 2 | import re | ||
| 3 | from itertools import product | 3 | from itertools import product | ||
| 4 | 4 | ||||
| 5 | class BridgeKeeperProxy: | 5 | class BridgeKeeperProxy: | ||
| 6 | def __init__(self, module): | 6 | def __init__(self, module): | ||
| 7 | self._module = module | 7 | self._module = module | ||
| 8 | 8 | ||||
| 9 | def __getattr__(self, name): | 9 | def __getattr__(self, name): | ||
| 10 | try: | 10 | try: | ||
| 11 | obj = getattr(self._module, name) | 11 | obj = getattr(self._module, name) | ||
| 12 | except AttributeError: | 12 | except AttributeError: | ||
| 13 | raise AttributeError(f"The module has no attribute named'{name}'") | 13 | raise AttributeError(f"The module has no attribute named'{name}'") | ||
| 14 | 14 | ||||
| 15 | if self._ask_question_1(obj) and self._ask_question_2(obj) and self._ask_question_3(obj): | 15 | if self._ask_question_1(obj) and self._ask_question_2(obj) and self._ask_question_3(obj): | ||
| 16 | return obj | 16 | return obj | ||
| 17 | 17 | ||||
| 18 | raise AttributeError(f"The object '{name}' did not pass the Bridge Guardian's questions!") | 18 | raise AttributeError(f"The object '{name}' did not pass the Bridge Guardian's questions!") | ||
| 19 | 19 | ||||
| 20 | def _generate_dummy_arg(self, type_str): | 20 | def _generate_dummy_arg(self, type_str): | ||
| 21 | options = [t.strip() for t in type_str.split('|')] | 21 | options = [t.strip() for t in type_str.split('|')] | ||
| 22 | 22 | ||||
| 23 | for opt in options: | 23 | for opt in options: | ||
| 24 | val = self._generate_single_type(opt) | 24 | val = self._generate_single_type(opt) | ||
| 25 | if val is not None: | 25 | if val is not None: | ||
| 26 | return val | 26 | return val | ||
| 27 | return None | 27 | return None | ||
| 28 | 28 | ||||
| 29 | def _extract_params(self, doc): | 29 | def _extract_params(self, doc): | ||
| 30 | if not doc: | 30 | if not doc: | ||
| 31 | return [] | 31 | return [] | ||
| 32 | 32 | ||||
| 33 | lines = doc.splitlines() | 33 | lines = doc.splitlines() | ||
| 34 | start = None | 34 | start = None | ||
| 35 | 35 | ||||
| 36 | for i, line in enumerate(lines): | 36 | for i, line in enumerate(lines): | ||
| 37 | if line.strip() == "Parameters": | 37 | if line.strip() == "Parameters": | ||
| 38 | start = i + 2 | 38 | start = i + 2 | ||
| 39 | break | 39 | break | ||
| 40 | 40 | ||||
| 41 | if start is None: | 41 | if start is None: | ||
| 42 | return [] | 42 | return [] | ||
| 43 | 43 | ||||
| 44 | params = [] | 44 | params = [] | ||
| 45 | for line in lines[start:]: | 45 | for line in lines[start:]: | ||
| 46 | if not line.strip(): | 46 | if not line.strip(): | ||
| 47 | break | 47 | break | ||
| 48 | if ':' in line: | 48 | if ':' in line: | ||
| 49 | _, val = line.split(':', 1) | 49 | _, val = line.split(':', 1) | ||
| 50 | params.append(val.strip()) | 50 | params.append(val.strip()) | ||
| 51 | 51 | ||||
| 52 | return params | 52 | return params | ||
| 53 | 53 | ||||
| 54 | def _generate_single_type(self, type_str): | 54 | def _generate_single_type(self, type_str): | ||
| 55 | if type_str == 'int': return 1 | 55 | if type_str == 'int': return 1 | ||
| 56 | if type_str == 'float': return 1.5 | 56 | if type_str == 'float': return 1.5 | ||
| 57 | if type_str == 'str': return "str" | 57 | if type_str == 'str': return "str" | ||
| 58 | if type_str == 'bool': return True | 58 | if type_str == 'bool': return True | ||
| 59 | 59 | ||||
| 60 | dict_match = re.search(r'dict\[(.+?),\s*(.+?)\]', type_str) | 60 | dict_match = re.search(r'dict\[(.+?),\s*(.+?)\]', type_str) | ||
| 61 | if dict_match: | 61 | if dict_match: | ||
| 62 | k = self._generate_dummy_arg(dict_match.group(1)) | 62 | k = self._generate_dummy_arg(dict_match.group(1)) | ||
| 63 | v = self._generate_dummy_arg(dict_match.group(2)) | 63 | v = self._generate_dummy_arg(dict_match.group(2)) | ||
| 64 | return {k: v} | 64 | return {k: v} | ||
| 65 | 65 | ||||
| 66 | coll_match = re.search(r'(list|tuple|set)\[(.+?)\]', type_str) | 66 | coll_match = re.search(r'(list|tuple|set)\[(.+?)\]', type_str) | ||
| 67 | if coll_match: | 67 | if coll_match: | ||
| 68 | item = self._generate_dummy_arg(coll_match.group(2)) | 68 | item = self._generate_dummy_arg(coll_match.group(2)) | ||
| 69 | if coll_match.group(1) == 'list': return [item] | 69 | if coll_match.group(1) == 'list': return [item] | ||
| 70 | if coll_match.group(1) == 'tuple': return (item,) | 70 | if coll_match.group(1) == 'tuple': return (item,) | ||
| 71 | if coll_match.group(1) == 'set': return {item} | 71 | if coll_match.group(1) == 'set': return {item} | ||
| 72 | 72 | ||||
| 73 | return None | 73 | return None | ||
| 74 | 74 | ||||
| 75 | def _ask_question_1(self, obj): | 75 | def _ask_question_1(self, obj): | ||
| 76 | name = getattr(obj, '__name__', '') | 76 | name = getattr(obj, '__name__', '') | ||
| 77 | return isinstance(name, str) and len(name) > 0 and name[0].isupper() | 77 | return isinstance(name, str) and len(name) > 0 and name[0].isupper() | ||
| 78 | 78 | ||||
| 79 | def _ask_question_2(self, obj): | 79 | def _ask_question_2(self, obj): | ||
| 80 | if not callable(obj): | 80 | if not callable(obj): | ||
| 81 | return False | 81 | return False | ||
| 82 | 82 | ||||
| 83 | doc = getattr(obj, '__doc__', '') or '' | 83 | doc = getattr(obj, '__doc__', '') or '' | ||
| 84 | types = self._extract_params(doc) | 84 | types = self._extract_params(doc) | ||
| 85 | all_options = [] | 85 | all_options = [] | ||
| 86 | for t in types: | 86 | for t in types: | ||
| 87 | variants = [opt.strip() for opt in t.split('|')] | 87 | variants = [opt.strip() for opt in t.split('|')] | ||
| 88 | generated = [self._generate_single_type(v) for v in variants] | 88 | generated = [self._generate_single_type(v) for v in variants] | ||
| 89 | all_options.append(generated) | 89 | all_options.append(generated) | ||
| 90 | 90 | ||||
| 91 | for combo in product(*all_options): | 91 | for combo in product(*all_options): | ||
| 92 | try: | 92 | try: | ||
| 93 | obj(*combo) | 93 | obj(*combo) | ||
| 94 | return True | 94 | return True | ||
| 95 | except Exception: | 95 | except Exception: | ||
| 96 | continue | 96 | continue | ||
| 97 | 97 | ||||
| 98 | return False | 98 | return False | ||
| 99 | 99 | ||||
| 100 | def _ask_question_3(self, obj): | 100 | def _ask_question_3(self, obj): | ||
| 101 | for attr in dir(obj): | 101 | for attr in dir(obj): | ||
| 102 | if (attr.startswith('__') and attr.endswith('__')) or (re.search(r'[aeiouAEIOU]{4,}', attr)): | 102 | if (attr.startswith('__') and attr.endswith('__')) or (re.search(r'[aeiouAEIOU]{4,}', attr)): | ||
| 103 | continue | 103 | continue | ||
| 104 | 104 | ||||
| 105 | latin_letters = [l for l in attr if l in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'] | 105 | latin_letters = [l for l in attr if l in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'] | ||
| 106 | if latin_letters and latin_letters[-1].isupper(): | 106 | if latin_letters and latin_letters[-1].isupper(): | ||
| 107 | return True | 107 | return True | ||
| 108 | return False | 108 | return False | ||
| 109 | 109 | ||||
| 110 | 110 | ||||
| 111 | class BridgeKeeper: | 111 | class BridgeKeeper: | ||
| 112 | def __init__(self, module_name): | 112 | def __init__(self, module_name): | ||
| 113 | self.module_name = module_name | 113 | self.module_name = module_name | ||
| 114 | self.proxy = None | 114 | self.proxy = None | ||
| 115 | 115 | ||||
| 116 | def __enter__(self): | 116 | def __enter__(self): | ||
| 117 | module = importlib.import_module(self.module_name) | 117 | module = importlib.import_module(self.module_name) | ||
| 118 | self.proxy = BridgeKeeperProxy(module) | 118 | self.proxy = BridgeKeeperProxy(module) | ||
| 119 | return self.proxy | 119 | return self.proxy | ||
| 120 | 120 | ||||
| 121 | def __exit__(self, exc_type, exc_val, exc_tb): | 121 | def __exit__(self, exc_type, exc_val, exc_tb): | ||
| 122 | pass | 122 | pass | ||
| 123 | 123 | ||||
| 124 | 124 | ||||
| 125 | 125 | ||||
| 126 | 126 | ||||
| 127 | 127 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||