├── .gitignore ├── LICENSE ├── README.md ├── _zoom_parser ├── README.md ├── configuration.py ├── main.py ├── requirements.txt └── src │ ├── __init__.py │ ├── excel_logic.py │ ├── formatters.py │ ├── logic.py │ ├── parse_zoom.py │ └── sheets.py ├── lab-1 ├── README.md ├── example_db.png ├── example_er.jpg └── variants.md ├── lab-2 ├── README.md └── lab2.sql ├── lab-3 ├── .gitignore └── README.md ├── lab-4 └── README.md └── lab-5 └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Kovynev Maxim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # db_sql_lab_examples 2 | Задания лабораторных работ по курсу БД 3 | 4 | http://se.moevm.info/doku.php/courses:databases:labs 5 | 6 | -------------------------------------------------------------------------------- /_zoom_parser/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Парсер статистики посещения Zoom пар 3 | 4 | Основано на нечеткой логике и в тестовом режиме -------------------------------------------------------------------------------- /_zoom_parser/configuration.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | # Исходная таблица со студентами 4 | users = { 5 | 'sheet_id': '1WdaaGINwqaOvzUKYT-5l9ZkDSKuUSsz78eVizJQUrSw', 6 | 'table_name': 'Оценки', 7 | 'column_name': 'ФИО', 8 | 'column_group': 'Группа', 9 | 'column_email': 'Email' 10 | } 11 | 12 | # Указать откуда брать данные, за какую пару, сколько минимум минут 13 | sheets = [{ 14 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 15 | 'table_name': "09.09.2021", 16 | 'date': datetime(2021, 9, 9), 17 | 'min_time': 45, 18 | 'column_name': 'ФИО', 19 | 'column_endurance': 'Длительность', 20 | 'column_email': 'Почта' 21 | }, { 22 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 23 | 'table_name': "16.09.2021", 24 | 'date': datetime(2021, 9, 16), 25 | 'min_time': 75, 26 | 'column_name': 'ФИО', 27 | 'column_endurance': 'Длительность', 28 | 'column_email': 'Почта' 29 | }, { 30 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 31 | 'table_name': "23.09.2021", 32 | 'date': datetime(2021, 9, 23), 33 | 'min_time': 75, 34 | 'column_name': 'ФИО', 35 | 'column_endurance': 'Длительность', 36 | 'column_email': 'Почта' 37 | }, { 38 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 39 | 'table_name': "30.09.2021", 40 | 'date': datetime(2021, 9, 30), 41 | 'min_time': 75, 42 | 'column_name': 'ФИО', 43 | 'column_endurance': 'Длительность', 44 | 'column_email': 'Почта' 45 | }, { 46 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 47 | 'table_name': "07.10.2021", 48 | 'date': datetime(2021, 10, 7), 49 | 'min_time': 75, 50 | 'column_name': 'ФИО', 51 | 'column_endurance': 'Длительность', 52 | 'column_email': 'Почта' 53 | }, { 54 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 55 | 'table_name': "14.10.2021", 56 | 'date': datetime(2021, 10, 14), 57 | 'min_time': 75, 58 | 'column_name': 'ФИО', 59 | 'column_endurance': 'Длительность', 60 | 'column_email': 'Почта' 61 | }, { 62 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 63 | 'table_name': "21.10.2021", 64 | 'date': datetime(2021, 10, 21), 65 | 'min_time': 75, 66 | 'column_name': 'ФИО', 67 | 'column_endurance': 'Длительность', 68 | 'column_email': 'Почта' 69 | }, { 70 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 71 | 'table_name': "28.10.2021", 72 | 'date': datetime(2021, 10, 28), 73 | 'min_time': 75, 74 | 'column_name': 'ФИО', 75 | 'column_endurance': 'Длительность', 76 | 'column_email': 'Почта' 77 | }, { 78 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 79 | 'table_name': "11.11.2021", 80 | 'date': datetime(2021, 11, 11), 81 | 'min_time': 75, 82 | 'column_name': 'ФИО', 83 | 'column_endurance': 'Длительность', 84 | 'column_email': 'Почта' 85 | }, { 86 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 87 | 'table_name': "18.11.2021", 88 | 'date': datetime(2021, 11, 18), 89 | 'min_time': 75, 90 | 'column_name': 'ФИО', 91 | 'column_endurance': 'Длительность', 92 | 'column_email': 'Почта' 93 | }, { 94 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 95 | 'table_name': "25.11.2021", 96 | 'date': datetime(2021, 11, 25), 97 | 'min_time': 55, 98 | 'column_name': 'ФИО', 99 | 'column_endurance': 'Длительность', 100 | 'column_email': 'Почта' 101 | }, { 102 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 103 | 'table_name': "02.12.2021", 104 | 'date': datetime(2021, 12, 2), 105 | 'min_time': 75, 106 | 'column_name': 'ФИО', 107 | 'column_endurance': 'Длительность', 108 | 'column_email': 'Почта' 109 | }, { 110 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 111 | 'table_name': "09.12.2021", 112 | 'date': datetime(2021, 12, 9), 113 | 'min_time': 75, 114 | 'column_name': 'ФИО', 115 | 'column_endurance': 'Длительность', 116 | 'column_email': 'Почта' 117 | }, { 118 | 'sheet_id': '1xU4akJt6QbTG2FYsrBgYYRTRTrqGRc9IRtdoN-SKQx4', 119 | 'table_name': "23.12.2021", 120 | 'date': datetime(2021, 12, 23), 121 | 'min_time': 75, 122 | 'column_name': 'ФИО', 123 | 'column_endurance': 'Длительность', 124 | 'column_email': 'Почта' 125 | }] 126 | 127 | output_file = 'Подсчет посещения.xlsx' 128 | similarity_threshold = 85 129 | -------------------------------------------------------------------------------- /_zoom_parser/main.py: -------------------------------------------------------------------------------- 1 | from src.parse_zoom import main 2 | 3 | main() 4 | -------------------------------------------------------------------------------- /_zoom_parser/requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2021.5.30 2 | charset-normalizer==2.0.6 3 | fuzzywuzzy==0.18.0 4 | idna==3.2 5 | numpy==1.21.2 6 | pandas==1.3.3 7 | pydash==5.0.2 8 | python-dateutil==2.8.2 9 | pytz==2021.1 10 | requests==2.26.0 11 | six==1.16.0 12 | transliterate==1.10.2 13 | urllib3==1.26.6 14 | XlsxWriter==3.0.1 15 | -------------------------------------------------------------------------------- /_zoom_parser/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moevm/db_sql_lab_examples/cbc82e6b11a4d0c4e70eb9458aaf6c5519844b74/_zoom_parser/src/__init__.py -------------------------------------------------------------------------------- /_zoom_parser/src/excel_logic.py: -------------------------------------------------------------------------------- 1 | from pydash import get 2 | from xlsxwriter import Workbook 3 | 4 | from configuration import output_file 5 | 6 | 7 | def write_sheet(wb, ws, data, offset=0, header_map=None, with_colors=True): 8 | keys = list(data[0].keys()) 9 | keys_translation = keys if not header_map else list(header_map.values()) 10 | 11 | first_row = 0 + offset 12 | for header in keys_translation: 13 | col = keys_translation.index(header) 14 | ws.write(first_row, col, header) 15 | 16 | green = wb.add_format({'bg_color': '#00FF00'}) 17 | yellow = wb.add_format({'bg_color': '#FFFF00'}) 18 | red = wb.add_format({'bg_color': '#FF0000'}) 19 | 20 | row = 1 + offset 21 | for row_data in data: 22 | 23 | color = None 24 | if get(row_data, 'visited_enough'): 25 | color = green 26 | if not get(row_data, 'visited_enough'): 27 | color = yellow 28 | if get(row_data, 'row_index') == '-': 29 | color = red 30 | 31 | for _key, _value in row_data.items(): 32 | col = keys.index(_key) 33 | if not color or not with_colors: 34 | ws.write(row, col, str(_value)) 35 | else: 36 | ws.write(row, col, str(_value), color) 37 | 38 | row += 1 39 | 40 | 41 | header_map = { 42 | 'user_name': 'ФИО', 43 | 'group': 'Группа', 44 | 'user_email': 'Почта', 45 | 'match_with': 'Совпадение с', 46 | 'row_index': 'Номера строк', 47 | 'by_email': 'Совпадение по почте', 48 | 'prob_1': 'Вероятн. 1', 49 | 'prob_2': 'Вероятн. 2', 50 | 'minutes': 'Длительность', 51 | 'visited_enough': 'Балл' 52 | } 53 | 54 | header_map_unknown = { 55 | 'name': 'Неопознанный', 56 | 'minutes': 'Длительность', 57 | 'email': 'Почта', 58 | } 59 | 60 | header_total = { 61 | 'user_name': 'ФИО', 62 | 'user_group': 'Группа', 63 | 'count': 'Кол-во', 64 | 'dates': 'Даты посещения', 65 | } 66 | 67 | 68 | def write_excel(total, found_users, unknown_users): 69 | wb = Workbook(output_file) 70 | 71 | ws = wb.add_worksheet('Посещение') 72 | write_sheet(wb, ws, total, header_map=header_total, with_colors=False) 73 | ws.set_column(0, 0, 45) 74 | 75 | for key, value in found_users.items(): 76 | 77 | ws = wb.add_worksheet(key) 78 | write_sheet(wb, ws, value, header_map=header_map) 79 | write_sheet(wb, 80 | ws, 81 | unknown_users[key], 82 | offset=len(value) + 2, 83 | header_map=header_map_unknown) 84 | ws.set_column(0, 0, 45) 85 | ws.set_column(2, 2, 45) 86 | ws.set_column(3, 3, 45) 87 | 88 | wb.close() 89 | -------------------------------------------------------------------------------- /_zoom_parser/src/formatters.py: -------------------------------------------------------------------------------- 1 | import re 2 | from fuzzywuzzy import fuzz 3 | from transliterate import translit 4 | from pydash import map_, order_by 5 | 6 | 7 | def parse_name(name, with_midname=False): 8 | # В транслит 9 | name = translit(name, 'ru') 10 | # Нижний регистр 11 | name = name.lower() 12 | # Убрать номер группы 13 | name = re.sub(r'\d', '', name) 14 | # Нижнее подчеркивание = пробел 15 | name = name.replace('_', ' ') 16 | # Убрать дополнительную информацию из скобок 17 | name = re.sub(r'\(.*\)', '', name) 18 | # Убрать лишние пробелы 19 | name = name.strip() 20 | 21 | s = name.split(' ') 22 | 23 | def rejoin(s, index): 24 | return ' '.join(s[index:]) 25 | 26 | if not with_midname: 27 | return s[0], rejoin(s, 1) 28 | else: 29 | return s[0], s[1], rejoin(s, 2) 30 | 31 | 32 | def parse_email(email): 33 | return email.strip() if isinstance(email, str) else '' 34 | 35 | 36 | def similarity_coefficient(str1, str2): 37 | return fuzz.ratio(str1, str2) 38 | 39 | 40 | def pretty_name(name): 41 | return ' '.join(map_(name, lambda s: s.capitalize())) 42 | 43 | 44 | def format_date(date): 45 | return date.strftime('%Y.%m.%d') 46 | 47 | 48 | def sort_dict(v, order): 49 | for key, value in v.items(): 50 | v[key] = order_by(value, order) 51 | -------------------------------------------------------------------------------- /_zoom_parser/src/logic.py: -------------------------------------------------------------------------------- 1 | from pydash import map_, find, get, pick 2 | 3 | from configuration import similarity_threshold 4 | from src.formatters import parse_name, similarity_coefficient, pretty_name, sort_dict 5 | from src.sheets import get_info_from_row 6 | 7 | 8 | def identify_user(sheet, found_users, date, user_name, user_email, user_group): 9 | found_user = False 10 | # По каждой строке таблицы посещаемости 11 | for row_index, row in sheet['sheet'].iterrows(): 12 | user_attendance_name, user_attendance_email, user_attendance_minutes = get_info_from_row( 13 | row, sheet) 14 | 15 | possible_name = parse_name(user_attendance_name) 16 | 17 | # Варианты сопоставления 18 | variants_name = [ 19 | f'{possible_name[1]} {possible_name[0]}', 20 | f'{possible_name[0]} {possible_name[1]}' 21 | ] 22 | name_format = f'{user_name[0]} {user_name[1]}' 23 | 24 | s1 = similarity_coefficient(name_format, variants_name[0]) 25 | s2 = similarity_coefficient(name_format, variants_name[1]) 26 | 27 | # Если нет совпадения по ФИО или почте - следующая строка 28 | if not (s1 > similarity_threshold or s2 > similarity_threshold 29 | or user_email == user_attendance_email): 30 | continue 31 | 32 | # Студент найден 33 | found_user = True 34 | 35 | # Учитываем случай, если студент зашел с 2+ аккаунтов - обновление данных 36 | duplicate = find(found_users[date], 37 | lambda x: x['user_email'] == user_email) 38 | if duplicate: 39 | duplicate['minutes'].append(user_attendance_minutes) 40 | duplicate['row_index'].append(row_index) 41 | duplicate['match_with'].append(user_attendance_name) 42 | duplicate['visited_enough'] = sum(map_(duplicate['minutes'], 43 | int)) >= sheet['min_time'] 44 | continue 45 | 46 | # Сохраняем пользователя 47 | visited_enough = user_attendance_minutes >= sheet['min_time'] 48 | found_users[date].append({ 49 | 'user_name': pretty_name(user_name), 50 | 'group': user_group, 51 | 'user_email': user_email, 52 | 'match_with': [user_attendance_name], 53 | 'row_index': [row_index], 54 | 'by_email': user_email == user_attendance_email, 55 | 'prob_1': s1, 56 | 'prob_2': s2, 57 | 'minutes': [user_attendance_minutes], 58 | 'visited_enough': visited_enough, 59 | }) 60 | return found_user 61 | 62 | 63 | def add_not_visited(user_not_visited, date, user_name, user_email, user_group): 64 | user_not_visited[date].append({ 65 | 'user_name': pretty_name(user_name), 66 | 'group': user_group, 67 | 'user_email': user_email, 68 | 'match_with': '-', 69 | 'row_index': '-', 70 | 'by_email': False, 71 | 'prob_1': 0, 72 | 'prob_2': 0, 73 | 'minutes': 0, 74 | 'visited_enough': False, 75 | }) 76 | 77 | 78 | def count_total(found_users): 79 | results = [] 80 | for date, users in found_users.items(): 81 | for user in users: 82 | found = find(results, 83 | lambda u: u['user_name'] == user['user_name']) 84 | counter = 1 if user['visited_enough'] else 0 85 | 86 | if found: 87 | found['count'] += counter 88 | if counter: 89 | found['dates'].append(date) 90 | else: 91 | results.append({ 92 | 'user_name': user['user_name'], 93 | 'user_group': user['group'], 94 | 'count': counter, 95 | 'dates': [date] if counter else [] 96 | }) 97 | sort_dict({'_': results}, ['group', 'user_name']) 98 | return results 99 | 100 | 101 | def preprocess_results(v): 102 | # Из-за заголовков индексы едут 103 | for key, value in v.items(): 104 | for el in value: 105 | if isinstance(get(el, 'row_index'), list): 106 | el['row_index'] = map_(el['row_index'], lambda i: i + 2) 107 | -------------------------------------------------------------------------------- /_zoom_parser/src/parse_zoom.py: -------------------------------------------------------------------------------- 1 | from pydash import get, map_, find 2 | 3 | from configuration import sheets, users 4 | from src.formatters import format_date, parse_name, parse_email, sort_dict 5 | from src.logic import identify_user, add_not_visited, preprocess_results, count_total 6 | from src.sheets import get_sheet, get_info_from_row 7 | from src.excel_logic import write_excel 8 | 9 | 10 | def main(): 11 | # Скачивание всех таблиц 12 | sheet_dfs = map_(sheets, lambda x: {**x, **{'sheet': get_sheet(x)}}) 13 | 14 | # Скачивание таблицы пользователя 15 | users_df = get_sheet(users) 16 | 17 | # Пользователи, которых не смогли определить 18 | unknown_users = {} 19 | # Студенты, которые не посетили пару 20 | user_not_visited = {} 21 | # Опознанные студенты 22 | found_users = {} 23 | 24 | # По каждой таблица посещаемости 25 | for sheet in sheet_dfs: 26 | date = format_date(sheet['date']) 27 | 28 | found_users[date] = [] 29 | unknown_users[date] = [] 30 | user_not_visited[date] = [] 31 | 32 | for _, user in users_df.iterrows(): 33 | user_name_raw = user[get(users, 'column_name')] 34 | if not user_name_raw or not isinstance(user_name_raw, str): 35 | break 36 | 37 | # Получаем ФИО, группу студента 38 | user_name = parse_name(user_name_raw, with_midname=True) 39 | user_group = int(user[get(users, 'column_group')]) 40 | user_email = parse_email(user[get(users, 'column_email')]) 41 | 42 | # Ищем пользователя и сохраняем информацию 43 | found_user = identify_user(sheet, found_users, date, user_name, 44 | user_email, user_group) 45 | 46 | if not found_user: 47 | add_not_visited(user_not_visited, date, user_name, user_email, 48 | user_group) 49 | 50 | # Повторно проходим, чтобы просмотреть не сопоставленные строки 51 | for sheet in sheet_dfs: 52 | date = format_date(sheet['date']) 53 | 54 | unknown_users[date] = [] 55 | 56 | for row_index, row in sheet['sheet'].iterrows(): 57 | found = find(found_users[date], 58 | lambda x: row_index in x['row_index']) 59 | if not found: 60 | 61 | user_attendance_name, user_attendance_email, user_attendance_minutes = get_info_from_row( 62 | row, sheet) 63 | 64 | unknown_users[date].append({ 65 | 'name': user_attendance_name, 66 | 'minutes': user_attendance_minutes, 67 | 'email': user_attendance_email, 68 | }) 69 | 70 | # Объединяем списки 71 | for key, value in user_not_visited.items(): 72 | found_users[key] += value 73 | 74 | sort_dict(found_users, ['group', 'user_name']) 75 | sort_dict(unknown_users, ['name']) 76 | 77 | preprocess_results(found_users) 78 | 79 | total = count_total(found_users) 80 | 81 | write_excel(total, found_users, unknown_users) 82 | -------------------------------------------------------------------------------- /_zoom_parser/src/sheets.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import requests as requests 3 | from io import BytesIO 4 | from pydash import get 5 | 6 | 7 | def sheet_id_to_url(sheet_id, name): 8 | return f"https://docs.google.com/spreadsheets/d/{sheet_id}/gviz/tq?tqx=out:csv&sheet={name}" 9 | 10 | 11 | def get_sheet(sheet): 12 | url = sheet_id_to_url(get(sheet, 'sheet_id'), get(sheet, 'table_name')) 13 | r = requests.get(url) 14 | return pd.read_csv(BytesIO(r.content), encoding='utf-8') 15 | 16 | 17 | def get_info_from_row(row, sheet): 18 | user_attendance_name = row[sheet['column_name']] 19 | user_attendance_email = row[sheet['column_email']] 20 | user_attendance_minutes = row[sheet['column_endurance']] 21 | return user_attendance_name, user_attendance_email, user_attendance_minutes 22 | -------------------------------------------------------------------------------- /lab-1/README.md: -------------------------------------------------------------------------------- 1 | # Лабораторная работа №1 2 | 3 | > Проектирование ER модели и структуры БД по текстовому описанию предметной области 4 | 5 | - Выбрать вариант задания: ((N - 1) mod M ) + 1, где N - номер в группе, M - число вариантов (22), нумерация с 1. То есть если вы в списке 1, то берете 1, 22 - 22, 23 - 1. 6 | - Варианты в файле variants.md 7 | - Нарисовать ER модель, рекомендуется использовать draw.io или иной редактор 8 | - Нарисовать структуру БД, содержащую названия полей, таблиц, связи, типы данных, ключи. 9 | - Проверить и обосновать, что реляционная модель соответвует НФБК 10 | - Прикрепить 2 изображения (er.png, db.png) в PR 11 | - Описать полученные модели, для чего нужна каждая сущность, почему такие связи и т.п. 12 | - В отчете описать цель, текст задания в соответствии с вариантом, 2 изображения моделей, их описание, обоснование НФБК, ссылку на PR в приложении, вывод 13 | 14 | -------------------------------------------------------------------------------- /lab-1/example_db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moevm/db_sql_lab_examples/cbc82e6b11a4d0c4e70eb9458aaf6c5519844b74/lab-1/example_db.png -------------------------------------------------------------------------------- /lab-1/example_er.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moevm/db_sql_lab_examples/cbc82e6b11a4d0c4e70eb9458aaf6c5519844b74/lab-1/example_er.jpg -------------------------------------------------------------------------------- /lab-1/variants.md: -------------------------------------------------------------------------------- 1 | В конце каждого варианта идут вопросы. Они потребуются в лабораторных №2,3. Для выполнения 1 работы необходимо только описание предметной области . 2 | 3 | # Вариант 1 4 | 5 | Пусть требуется создать программную систему, предназначенную для 6 | администратора гостиницы. Такая система должна обеспечивать хранение 7 | сведений об имеющихся в гостинице номерах, о проживающих в гостинице 8 | клиентах и о служащих, убирающих в номерах. Пусть количество номеров в 9 | гостинице известно, и имеются номера трех типов: одноместный, 10 | двухместный и трехместный, отличающиеся стоимостью проживания в 11 | сутки. В каждом номере есть телефон. О каждом проживающем должна 12 | храниться следующая информация: номер паспорта, фамилия, имя, отчество, 13 | город, из которого он прибыл, дата поселения в гостинице, выделенный 14 | гостиничный номер. О служащих гостиницы должна храниться информация 15 | следующего содержания: фамилия, имя , отчество, где (этаж) и когда (день 16 | недели) он убирает. Служащий гостиницы убирает все номера на одном 17 | этаже в определенные дни недели, при этом в разные дни он может убирать 18 | разные этажи. 19 | Работа с системой предполагает получение следующей информации: 20 | - о клиентах, проживающих в заданном номере, 21 | - о клиентах, прибывших из заданного города, 22 | - о том, кто из служащих убирал номер указанного клиента в заданный 23 | день недели, 24 | - есть ли в гостинице свободные места и свободные номера и, если есть, 25 | то сколько. 26 | Администратор должен иметь возможность выполнить следующие 27 | операции: 28 | - принять на работу или уволить служащего гостиницы. 29 | - изменить расписание работы служащего. 30 | - поселить или выселить клиента. 31 | 32 | 33 | # Вариант 2 34 | 35 | Пусть требуется создать программную систему, предназначенную для 36 | работников библиотеки. Такая система должна обеспечивать хранение 37 | сведений об имеющихся в библиотеке книгах, о читателях библиотеки и 38 | читальных залах. 39 | Для каждой книги в БД должны храниться следующие сведения: 40 | название книги, автор (ы), издательство, год издания, число экземпляров этой 41 | книги в каждом зале библиотеки, а также шифр книги и дата закрепления 42 | книги за читателем. Сведения о читателях библиотеки должны включать 43 | номер читательского билета, фамилию читателя, номер паспорта, дату 44 | рождения, адрес, номер телефон, образование, наличие ученой степени. 45 | Читатели закрепляются за определенным залом и могут записываться и 46 | выписываться из библиотеки. Библиотека имеет несколько читальных залов, 47 | которые характеризуются номером, названием и вместимостью, то есть 48 | количеством людей, которые могут одновременно работать в зале. . 49 | Библиотека может получать новые книги и списывать старые. Шифр книги 50 | может измениться в результате переклассификации, а номер читательского 51 | билета в результате перерегистрации. 52 | Библиотекарю могут потребоваться следующие сведения о текущем 53 | состоянии библиотеки: 54 | - Какие книги закреплены за определенным читателем? 55 | - Как называется книга с заданным шифром? 56 | - Какой шифр у книги с заданным названием? 57 | - Когда книга была закреплена за читателем? 58 | - Кто из читателей взял книгу более месяца тому назад? 59 | - За кем из читателей закреплены книги, количество экземпляров которых в библиотеке не превышает 2? 60 | - Какое число читателей пользуется библиотекой? 61 | - Сколько в библиотеке читателей младше 20 лет? 62 | 63 | # Вариант 3 64 | Пусть требуется создать программную систему, предназначенную для 65 | завуча школы. Она должна обеспечивать хранение сведений о каждом 66 | учителе, о предметах, которые он преподает, номере закрепленного за ним 67 | кабинета, о расписании занятий. Существуют учителя, которые не имеют 68 | собственного кабинета. Об учениках должны храниться следующие 69 | сведения: фамилия и имя, в каком классе учится, какую оценку имеет в 70 | текущей четверти по каждому предмету. Завуч должен иметь возможность 71 | добавить сведения о новом учителе или ученике, внести в базу данных 72 | четвертные оценки учеников каждого класса по каждому предмету, удалить 73 | данные об уволившемся учителе и отчисленном из школы ученике, внести 74 | изменения в данные об учителях и учениках, в том числе поменять оценку 75 | ученика по тому или иному предмету. В задачу завуча входит также 76 | составление расписания. Завучу могут потребоваться следующие сведения: 77 | - Какой предмет будет в заданном классе, в заданный день недели на 78 | заданном уроке? 79 | - Кто из учителей преподает в заданном классе? 80 | - В каком кабинете будет 5-й урок в среду у некоторого класса? 81 | - В каких классах преподает заданный предмет заданный учитель? 82 | - Расписание на заданный день недели для указанного класса? 83 | - Сколько учеников в указанном классе? 84 | 85 | # Вариант 4 86 | Пусть требуется создать программную систему, предназначенную для 87 | организаторов выставки собак. Она должна обеспечивать хранение сведений 88 | о собаках - участниках выставки и экспертах. Для каждой собаки в БД 89 | должны храниться сведения, о том, к какому клубу она относится, кличка, 90 | порода и возраст, сведения о родословной (номер документа, клички 91 | родителей), дата последней прививки, фамилия, имя, отчество и паспортные 92 | данные хозяина. На каждый клуб отводится участок номеров, под которыми 93 | будут выступать участники выставки. Сведения об эксперте должны 94 | включать фамилию и имя, номер ринга, который он обслуживает; клуб, 95 | название клуба, в котором он состоит. Каждый ринг могут обслуживать 96 | несколько экспертов. Каждая порода собак выступает на своем ринге, но на 97 | одном и том же ринге в разное время могут выступать разные породы. 98 | Итогом выставки является определение медалистов по каждой породе. 99 | Организатор выставки должен иметь возможность добавить в базу нового 100 | участника или нового эксперта, снять эксперта с судейства, заменив его 101 | другим, отстранить собаку от участия в выставке. Организатору выставки 102 | могут потребоваться следующие сведения; 103 | - На каком ринге выступает заданный хозяин со своей собакой? 104 | - Какими породами представлен заданный клуб? 105 | - Какие медали и сколько заслужены клубом? 106 | - Какие эксперты обслуживают породу? 107 | - Количество участников по каждой породе? 108 | 109 | # Вариант 5 110 | Пусть требуется создать программную систему, предназначенную для 111 | работников приемной комиссии высшего учебного заведения. Она должна 112 | обеспечивать хранение, просмотр и изменение сведений об абитуриентах, а 113 | также о расписании экзаменов и консультаций. Результатом работы 114 | приемной комиссии должен быть список абитуриентов, зачисленных в 115 | институт. 116 | Секретарь приемной комиссии регистрирует абитуриентов. Для каждого 117 | абитуриента в базу данных заносятся следующие сведения: фамилия, имя, 118 | отчество, паспортные данные, какое учебное заведение, где и когда окончил, 119 | наличие золотой или серебряной медали, название кафедры и факультета, 120 | на которые поступает абитуриент. При регистрации абитуриенту выдают 121 | экзаменационный лист, имеющий уникальный номер, и сообщают номер 122 | группы и потока. Группы формируются на период вступительных экзаменов 123 | и объединяются в потоки по 3-4 группы. Для каждой группы по каждому 124 | предмету в базу данных заносится экзаменационная ведомость. Оценка, 125 | полученная абитуриентом, может быть изменена на апелляции. Абитуриент 126 | может не только подать, но и забрать документы, а также перевести их на 127 | другую кафедру. Для каждого потока формируется расписание консультаций 128 | и экзаменов по предметам. Медалисты сдают только один экзамен. Известно 129 | количество мест на каждый факультет. Приемная комиссия по результатам 130 | экзаменов должна сформировать списки абитуриентов, зачисленных в 131 | институт. Секретарю приемной комиссии могут потребоваться следующие 132 | сведения: 133 | - Список абитуриентов на заданный факультет? 134 | - Оценки, полученные указанным абитуриентом? 135 | - Когда и в какой аудитории будет консультация и экзамен у 136 | заданного абитуриента по указанному предмету? 137 | - Где, когда и по каким предметам будут проходить экзамены у 138 | заданной группы? 139 | - Конкурс на каждый факультет? 140 | - Средний балл по каждому предмету на каждом факультете? 141 | 142 | # Вариант 6 143 | Пусть требуется создать программную систему, позволяющую 144 | отслеживать распределение по почтовым отделениям газет, печатающихся в 145 | типографиях города. Такая система должна обеспечивать хранение, 146 | просмотр и изменение сведений о газетах, почтовых отделениях, 147 | получающих газеты и о типографиях, выпускающих газеты. Сведения о 148 | газетах включают в себя: название газеты, индекс издания, фамилию, имя и 149 | отчество редактора, цену экземпляра газеты. Цены могут меняться. 150 | Возможно появление новых газет и изменение индекса существующего 151 | издания. Для типографий указываются их названия и адреса. В типографии 152 | разными тиражами печатаются газеты нескольких наименований. 153 | Типография может быть закрыта, тогда необходимо скорректировать работу 154 | других типографий с учетом потребностей почтовых отделений в газетах. 155 | Почтовое отделение имеет номер и адрес. На каждое почтовое отделение 156 | поступают в определенных количествах газеты разных наименований, 157 | причем часть экземпляров одной и той же газеты может быть напечатана в 158 | одной типографии, а часть – в другой. 159 | - Пользователям системы может потребоваться следующая 160 | информация: 161 | - По каким адресам печатаются газеты данного наименования? 162 | - Фамилия редактора газеты, которая печатается в указанной 163 | типографии самым большим тиражом? 164 | - На какие почтовые отделения (адреса) поступает газета, имеющая 165 | цену больше указанной? 166 | - Какие газеты и куда (номер почты) поступают в количестве меньшем, 167 | чем заданное? 168 | - Куда поступает данная газета, печатающаяся по данному адресу 169 | 170 | # Вариант 7 171 | 172 | ![image](https://github.com/user-attachments/assets/6716feff-42a2-4d2a-abb4-3ea9d374d3fe) 173 | 174 | 175 | Пусть требуется создать программную систему, ориентированную на 176 | администрацию птицефабрики и позволяющую работать с информацией о 177 | работниках фабрики и об имеющихся на ней курах. 178 | О каждой курице должна храниться следующая информация: вес, 179 | возраст, порода, количество ежемесячно получаемых от курицы яиц, а также 180 | информация о местонахождении курицы. Сведения о породе включают в 181 | себя: название породы, среднее количество яиц в месяц 182 | (производительность) и средний вес, номер рекомендованной диеты. 183 | Птицефабрика имеет несколько цехов, и за каждой курицей закреплена 184 | отдельная клетка. Код клетки, где находится курица, характеризуется 185 | номером цеха, номером ряда в цехе и номером клетки в ряду. О работниках 186 | птицефабрики в БД должна храниться следующая информация: паспортные 187 | данные, зарплата, закрепленные за работником клетки. Директор 188 | птицефабрики может принять или уволить работника, при этом не должно 189 | быть кур, не обслуживаемых ни одним работником. Количество кур 190 | может изменяться как в большую, так и в меньшую сторону, в отдельные 191 | моменты времени часть клеток может пустовать. Директору могут 192 | потребоваться следующие сведения: 193 | - Какое количество яиц получают от каждой курицы данного веса, 194 | породы, возраста? 195 | - В каком цехе наибольшее количество кур определенной породы? 196 | - В каких клетках находятся куры указанного возраста с заданным 197 | номером диеты? 198 | - Сколько яиц в день приносят куры указанного работника? 199 | - Среднее количество яиц, которое получает в день каждый работник от 200 | обслуживаемых им кур? 201 | - В каком цехе находится курица, от которой получают больше всего 202 | яиц. 203 | - Сколько кур каждой породы в каждом цехе? 204 | - Какое количество кур обслуживает каждый работник? 205 | 206 | # Вариант 8 207 | 208 | Пусть требуется создать программную систему, предназначенную для 209 | директора продовольственного магазина. Такая система должна 210 | обеспечивать хранение сведений о магазине, об имеющихся в нем товарах, о 211 | торговых базах и товарах, хранящихся на этих базах. Магазин осуществляет 212 | закупку товаров на разных базах, предпочитая при этом закупать одни виды 213 | товара на одних базах, а другие на других. Магазин характеризуется классом, 214 | номером и имеет несколько отделов. Каждый товар в каждом магазине 215 | продается, по крайней мере, в одном отделе. Каждый отдел имеет 216 | заведующего. Товары, имеющиеся в магазине и хранящиеся на базах, 217 | характеризуются ценой, сортом и количеством. Розничные цены в магазине 218 | зависят от класса магазина. 219 | Директор магазина должен иметь возможность изменить цену товара по 220 | своему усмотрению, осуществить закупку недостающего товара на базе. Он 221 | может также закрыть один из отделов или открыть новый, при этом товары 222 | могут перемещаться из отдела в отдел. Директору могут потребоваться 223 | следующие сведения: 224 | - Какие товары имеются в магазине (на базе)? 225 | - Какие отсутствующие товары может заказать магазин на базе? 226 | - Какие товары, и в каком количестве имеются в отделе магазина? 227 | - Список заведующих отделами магазина? 228 | - Суммарная стоимость товара в каждом отделе? 229 | - На каких базах, и в каких количествах есть товар нужного 230 | наименования? 231 | 232 | # Вариант 9 233 | Пусть требуется создать программную систему, предназначенную для 234 | диспетчера автобусного парка. Такая система должна обеспечивать хранение 235 | сведений о водителях, о маршрутах и характеристиках автобусов. 236 | Каждый водитель характеризуется паспортными данными, классом, 237 | стажем работы и окладом, причем оклад зависит от класса и стажа работы. 238 | Маршрут автобуса характеризуется номером маршрута, названием 239 | начального и конечного пункта движения, временем начала и конца 240 | движения, интервалом движения и протяженностью в минутах (время 241 | движения от кольца до кольца). Характеристиками автобуса являются: 242 | номер государственной регистрации автобуса, его тип и вместимость, причем 243 | вместимость автобуса зависит от его типа. Каждый водитель закреплен за 244 | отдельным автобусом и работает на определенном маршруте, но в случае 245 | поломки своего автобуса или болезни другого водителя может пересесть на 246 | другую машину. В базе должен храниться график работы водителей. 247 | Необходимо предусмотреть возможность корректировки БД в случаях 248 | поступления на работу нового водителя, списания старого автобуса, 249 | введения нового маршрута или изменения старого и т.п. 250 | Диспетчеру автопарка могут потребоваться следующие сведения: 251 | - Список водителей, работающих на определенном маршруте с 252 | указанием графика их работы? 253 | - Какие автобусы обслуживают данный маршрут? 254 | - Какие маршруты начинаются или заканчиваются в пункте с заданным 255 | названием? 256 | - Когда начинается и заканчивается движение автобусов на каждом 257 | маршруте? 258 | - Какова протяженность определенного маршрута? 259 | - Какова общая протяженность маршрутов, обслуживаемых автопарком? 260 | - Какие автобусы не вышли на линию, и по какой причине 261 | (неисправность, отсутствие водителя)? 262 | 263 | 264 | # Вариант 10 265 | Пусть требуется создать программную систему, предназначенную для 266 | работников справочной службы кинотеатров города. Такая система должна 267 | обеспечивать хранение сведений о кинотеатрах города, о фильмах, которые в 268 | них демонстрируются, о сеансах и билетах на эти сеансы. Сведения о 269 | кинотеатре — это его название, район города, где расположен кинотеатр, 270 | категория, вместимость. Сведения о фильме — это название фильма, режиссер, 271 | оператор, актеры, сыгравшие главные роли, жанр; производство, наличие 272 | призов кинофестивалей, продолжительность сеанса, кадр из фильма для 273 | рекламы. Кроме того, должна храниться информация о репертуаре 274 | кинотеатров на месяц, то есть о том какие фильмы, когда и где 275 | демонстрируются, о ценах на билеты и о количестве свободных мест на тот 276 | или иной сеанс. На разных сеансах в одном кинотеатре могут идти разные 277 | фильмы, а если в кинотеатре несколько залов, то и на одном. Кинотеатр 278 | может ввести новый фильм в репертуар или убрать фильм из репертуара. 279 | Работник справочной службы может корректировать перечень фильмов, 280 | находящихся в прокате – добавлять новые фильмы и снимать с проката, а 281 | также перечень кинотеатров, поскольку кинотеатры могут открываться или 282 | закрываться, причем иногда временно, например, на ремонт. Цена билета 283 | определяется прокатной стоимостью копии фильма, сеансом и категорией 284 | кинотеатра. 285 | Справочной службе могут потребоваться следующие сведения о 286 | текущем состоянии проката фильмов в городе: 287 | - Репертуар кинотеатра? 288 | - Адрес и район кинотеатра ? 289 | - Число свободных мест на данный сеанс в указанном кинотеатре? 290 | - Цена билетов на данный сеанс в указанном кинотеатре? 291 | - Жанр, производство и режиссер данного фильма ? 292 | - Какие фильмы имеют награды, когда и в каких кинотеатрах они 293 | демонстрируются? 294 | - В каких кинотеатрах в указанный день на указанных сеансах 295 | демонстрируется комедия? 296 | 297 | 298 | # Вариант 11 299 | Пусть требуется создать программную систему, предназначенную для 300 | работников почтового отделения. Такая система должна обеспечивать 301 | хранение сведений о подписчиках газет и журналов, обслуживаемых 302 | отделением связи, и о почтальонах. 303 | Каждое подписное издание характеризуется индексом, названием и 304 | подписной ценой. Данные о подписчиках включают в себя: фамилию, имя, 305 | отчество, домашний адрес, индексы получаемых изданий, дату, начиная с 306 | которой оформлена подписка, и срок подписки на каждое издание. 307 | Несколько домов объединяются в участок, который обслуживается одним 308 | почтальоном. Каждый почтальон может обслуживать несколько участков. В 309 | БД должны содержаться сведения о том, к каким участкам относятся 310 | подписчики газет, и об обслуживающем их почтальоне. Заведующий 311 | почтовым отделением может принять на работу и уволить почтальона, при 312 | этом участки не должны оставаться без обслуживания. Оператор почтовой 313 | связи должен иметь возможность по просьбе клиента оформить подписку, а 314 | также добавить в БД сведения о новом подписном издании. Оформление 315 | подписки связано с выдачей клиенту квитанции, в которой указывается 316 | общая стоимость подписки, что выписано, и на какой срок. 317 | Возможны следующие запросы к БД: 318 | - Определить наименование и количество экземпляров всех изданий, 319 | получаемых отделением связи. 320 | - По заданному адресу определить фамилию почтальона, 321 | обслуживающего подписчика. 322 | - Какие газеты выписывает гражданин с указанной фамилией, именем, 323 | отчеством? 324 | - Сколько почтальонов работает в почтовом отделении? 325 | - На каком участке количество экземпляров подписных изданий 326 | максимально? 327 | - Каков средний срок подписки по каждому изданию? 328 | 329 | 330 | # Вариант 12 331 | Пусть требуется создать программную систему, предназначенную для 332 | организаторов соревнований по футболу в рамках первенства страны. Такая 333 | система должна обеспечивать хранение сведений о командах, участвующих в 334 | первенстве, об игроках команд, о расписании встреч и их результатах, о цене 335 | билетов на игры. 336 | Сведения о команде — название команды, город, где она базируется, имя 337 | главного тренера, место в таблице прошлого сезона, расписание встреч. В 338 | один день команда может участвовать только в одной встрече. Сведения об 339 | игроке включают в себя фамилию и имя игрока, его возраст, номер и амплуа 340 | в команде. Сведения о стадионе, на котором происходит встреча содержат 341 | город, в котором он находится, название стадиона, и его вместимость. Цена 342 | билета на матч зависит от вместимости стадиона и положения 343 | встречающихся команд в турнирной таблице прошлого сезона (наибольшая - 344 | при игре тройки призеров, наименьшая — при игре тройки аутсайдеров). 345 | Организаторы соревнований должны иметь возможность внести изменения в 346 | данные о составе команд, перенести встречу. 347 | Им могут потребоваться следующие сведения: 348 | - Даты встреч указанной команды, ее противники и счет? 349 | - Номера и фамилии игроков команд, участвовавших во встрече, которая 350 | проходила в указанный день в указанном городе? 351 | - Цена, билета на матч между указанными командами? 352 | - Игрок, забивший в турнире наибольшее количество мячей? 353 | - Команды, имеющие наилучшую и наихудшую разницу забитых и 354 | пропущенных мячей? 355 | - Самый молодой участник турнира? 356 | - Команды, занявшие призовые места? 357 | 358 | # Вариант 13 359 | Пусть требуется создать программную систему, предназначенную для 360 | работника методического отдела института. Такая система должна 361 | обеспечивать хранение сведений о специальностях, по которым ведет 362 | подготовку институт, о факультетах и кафедрах, обеспечивающих эту 363 | подготовку, о дисциплинах, входящих в перечень подготовки по каждой 364 | специальности. Сведения о специальности – это код и название 365 | специальности, присваиваемая квалификация, продолжительность и форма 366 | обучения (дневная, вечерняя, заочная). Сведения о кафедре включают ее 367 | название, телефон (телефоны), факультет, к которому относится кафедра, 368 | данные о заведующем кафедрой (фамилия, имя, отчество, степень, звание). 369 | Сведения о дисциплине – это название дисциплины, в каком семестре 370 | (семестрах) и для каких специальностей она читается, сколько часов для 371 | каждой специальности отводится на лекции, лабораторные и практические 372 | занятия по этой дисциплине, на курсовое проектирование, виды отчетности 373 | (зачет, экзамен, текущий контроль). Сотрудник методического отдела может 374 | внести в БД информацию о новой дисциплине, изменить количество часов, 375 | отводимых под тот или иной вид учебной программы, изменить название 376 | кафедры или факультета, сведения о заведующем кафедрой, номер телефона 377 | кафедры. 378 | Сотруднику методического отдела могут потребоваться следующие 379 | сведения: 380 | - Названия дисциплин, которые читаются более одного семестра? 381 | - Общее количество часов, отводимых на лабораторные работы в одном 382 | из семестров, проведение которых обеспечивает определенная кафедра? 383 | - Название дисциплин, по которым проводятся лабораторные работы на 384 | факультете? 385 | - Разница в часах, отведенных по каждой дисциплине на лабораторные и 386 | практические занятия в одном из семестров на заданном факультете? 387 | - Дисциплины, по которым выполняют курсовые работы студенты 388 | указанной специальности? 389 | - Для каких специальностей читается указанная дисциплина? 390 | - Какое количество дисциплин входит в учебный план подготовки 391 | студентов по указанной специальности, и сколько лет осуществляется 392 | подготовка? 393 | 394 | # Вариант 14 395 | Пусть требуется создать программную систему для отдела кадров 396 | института. Такая система должна обеспечивать хранение сведений о 397 | преподавателях и других сотрудниках института. Эти сведения включают в 398 | себя паспортные данные сотрудника, данные трудовой книжки, ИНН, номер 399 | пенсионного свидетельства, название кафедры или отдела, в котором 400 | работает сотрудник, дата поступления на работу в институт, должность, 401 | степень, звание, правительственные награды, дата начала и конца отпуска в 402 | текущем году. Данные трудовой книжки – это ее номер и дата выдачи, а 403 | также даты и номера приказов о зачислении и увольнении, о переходе в 404 | другое подразделение или об изменении должности. Кроме того, для 405 | преподавателей должна быть известна нагрузка в текущем году (суммарное 406 | количество часов), дата заключения контракта, дата окончания контракта, 407 | педагогический стаж, и перечень дисциплин, которые он преподает или 408 | может преподавать. 409 | Сотруднику отдела кадров могут потребоваться следующие сведения: 410 | - Список преподавателей, которые работают на определенной кафедре, с 411 | указанием их категории (доцент, ассистент, ассистент к.н., профессор, 412 | старший преподаватель) и стажа преподавательской работы? 413 | - Средняя нагрузка ассистентов указанной кафедры? 414 | - Дисциплины, которые читает каждый из доцентов указанной кафедры? 415 | - Количество преподавателей каждой из категорий, работающих в 416 | институте? 417 | - Список сотрудников, находящихся в отпуске в определенном месяце; 418 | - Список преподавателей, у которых истек срок контракта. 419 | - Список сотрудников, награжденных медалью «За оборону 420 | Ленинграда»? 421 | 422 | # Вариант 15 423 | Пусть требуется создать программную систему, предназначенную для 424 | работника деканата Такая система должна обеспечивать хранение сведений о 425 | группах и студентах, а также о результатах текущей сессии. Таким образом, 426 | для каждого студента должны храниться такие данные, как фамилия, имя 427 | отчество студента, номер его зачетной книжки, адрес постоянной прописки и 428 | адрес, по которому студент проживает, получает или нет стипендию, а также 429 | оценки, полученные в текущей сессии, и отметки о сданных зачетах. 430 | Сведения о группе – это номер группы, факультет, кафедра, специальность, к 431 | которым она относится, год формирования группы. 432 | Работник деканата может вносить в БД следующие изменения: 433 | - Удалить или добавить в базу студента; 434 | - Поменять студенту номер группы, специальность, кафедру, номер 435 | зачетки; 436 | - Занести оценки, полученные студентами на экзаменах по каждому 437 | предмету; 438 | - По результатам сессии начислить стипендии студентам, не имеющим 439 | троек или иногородним студентам, которые имеют не более одной тройки. 440 | Право на 50 % повышение стипендии имеют студенты, получившие в сессию 441 | не более двух четверок, а на 100 % повышение – студенты, сдавшие сессию 442 | на все пятерки. 443 | Работнику деканата могут потребоваться следующие сведения: 444 | - Студенты, обучающиеся на определенной кафедре и не сдавшие хотя 445 | бы один экзамен, с указанием группы и предмета, по которому оценка 446 | отсутствует или равна 2? 447 | - Средний балл студентов каждой группы указанного факультета? 448 | - Средний балл по каждому предмету? 449 | - Список студентов указанной кафедры, которые по итогам сессии могут 450 | получать стипендию? 451 | 452 | # Вариант 16 453 | Пусть требуется создать программную систему, предназначенную для 454 | врачей и работников регистратуры поликлиники. Такая система должна 455 | хранить сведения об участках, которые относятся к поликлинике, о 456 | расписании работы участковых врачей, информацию о врачах, а также 457 | карточки пациентов. Карточка имеет номер, в нее заносятся сведения о 458 | каждом посещении поликлиники пациентом: дата посещения, жалобы, 459 | предварительный диагноз, назначения, выписан или нет больничный лист, и, 460 | если выписан, то на какой срок, имя врача. В карточке на первой странице 461 | указаны также фамилия, имя, отчество пациента, его домашний адрес, пол и 462 | возраст, номер страхового полиса, дата заполнения карточки. В расписании 463 | работы врачей указывается, на каком участке работает врач, дни и часы 464 | приема, номер кабинета. Врач может обслуживать более одного участка. В 465 | случае увольнения врача его участок(участки)передается другим врачам. 466 | Данные о враче, которые хранятся в БД, - это фамилия, имя отчество, 467 | категория, стаж работы, дата рождения. В карточку больного при каждом его 468 | посещении поликлиники врачом заносится очередная запись. Работники 469 | регистратуры регистрируют пациента, заполняя первую страницу его 470 | карточки. Уволить врача имеет право только заведующий поликлиникой. Он 471 | удаляет из базы сведения о враче и передает его больных другому врачу. 472 | Работникам поликлиники могут потребоваться следующие сведения: 473 | - Адрес данного больного, дата последнего посещения поликлиники и 474 | диагноз? 475 | - Фамилия и инициалы лечащего врача данного больного? 476 | - Номер кабинета, дни и часы приема данного врача? 477 | - Больные, находящиеся в данный момент на лечении у данного врача(не 478 | истек срок больничного листа); 479 | - Назначения врачей при указанном заболевании? 480 | - Кто работает в данный момент в указанном кабинете? 481 | - Сколько раз за прошедший месяц обращался в поликлинику указанный 482 | больной? 483 | - Какое количество больных обслужил за прошедший месяц каждый из 484 | врачей поликлиники? 485 | 486 | 487 | # Вариант 17 488 | Пусть требуется создать программную систему, предназначенную для 489 | диспетчера станции техобслуживания. Такая система должна обеспечивать 490 | хранение сведений об услугах, оказываемых станцией и их стоимости, о 491 | клиентах станции, о работниках станции и об автомобилях, которые они 492 | ремонтируют в текущий момент. Клиент станции – это человек, который 493 | хотя бы раз воспользовался услугами станции. О клиенте должны хранится 494 | следующие сведения: паспортные данные, включая фамилию, имя, отчество, 495 | дату рождения, прописку, а также даты обращения на станцию 496 | техобслуживания с указанием автомобилей, которые он сдавал в ремонт. 497 | Клиент сдает в ремонт необязательно автомобиль, владельцем которого он 498 | является. Сведения об автомобилях включают в себя марку автомобиля, его 499 | цвет, год выпуска, номер государственной регистрации, перечень 500 | неисправностей и данные о владельце. Сведения о работнике – это его 501 | фамилия, имя, отчество, специальность, разряд, стаж работы. Диспетчер 502 | заносит в БД сведения об автомобиле и о клиенте, если клиент обращается на 503 | станцию впервые. После этого диспетчер определяет рабочих, которые будут 504 | устранять имеющиеся в автомобиле неисправности. Оставляя автомобиль на 505 | станции техобслуживания, клиент получает расписку, в которой указано, 506 | когда автомобиль был поставлен на ремонт, какие он имеет неисправности, 507 | когда станция обязуется возвратить отремонтированный автомобиль. После 508 | возвращения автомобиля клиенту данные о произведенном ремонте 509 | помещаются в архив, клиент получает счет, в котором содержится перечень 510 | устраненных неисправностей с указанием времени работы, стоимости работы 511 | и стоимости запчастей. Возможно увольнение и прием на работу работников 512 | станции, изменение сведений о клиенте (клиент может поменять паспорт, 513 | права, адрес, телефон), номера государственной регистрации и цвета 514 | автомобиля. 515 | Диспетчеру могут потребоваться следующие сведения: 516 | - фамилия, имя, отчество и адрес владельца автомобиля с данным 517 | номером государственной регистрации? 518 | - Марка и год выпуска автомобиля данного владельца? 519 | - Перечень устраненных неисправностей в автомобиле данного 520 | владельца? 521 | - фамилия, имя, отчество работника станции, устранявшего данную 522 | неисправность в автомобиле данного клиента, и время ее устранения? 523 | - фамилия, имя, отчество клиентов, сдавших в ремонт автомобили с 524 | указанным типом неисправности? 525 | 526 | 527 | # Вариант 18 528 | Пусть требуется создать программную систему, предназначенную для 529 | менеджера музыкальных групп. Такая система должна обеспечивать 530 | хранение сведений о группах, включающих название группы, год 531 | образования и страну, состав исполнителей, положение в последнем хит-параде; 532 | репертуар группы. Сведения о каждой песне из репертуара группы — 533 | это ее название, композитор, автор текста. Необходимо также хранить 534 | данные о последней гастрольной поездке каждой группы: название 535 | гастрольной программы, названия населенных пунктов, дата начала и 536 | окончания выступлений, средняя цена билета (зависит от места выступления 537 | и положения группы в хит-параде). Возможно появление новой группы и 538 | изменение состава исполнителей. Каждая песня может быть в репертуаре 539 | только одной группы. 540 | Менеджеру могут потребоваться следующие сведения: 541 | - Автор текста, композитор и дата создания песни с данным названием? 542 | В репертуар какой группы она входит? 543 | - Репертуар наиболее популярной группы? 544 | - Цена билета на последний концерт указанной группы? 545 | - Состав исполнителей группы с заданным названием, их возраст и 546 | амплуа? 547 | - Место и продолжительность гастролей группы с заданным названием? 548 | - Какие группы в текущем году отмечают юбилей 549 | - Самый молодой вокалист? Какую группу он представляет? 550 | 551 | # Вариант 19 552 | Пусть требуется создать программную систему, предназначенную для 553 | работников технического архива предприятия. Технический архив содержит 554 | стеллажи, полки и ячейки, в которых хранится документация. Ячейка 555 | архива может быть пустой или хранить все экземпляры одного документа. 556 | Каждый экземпляр документации имеет инвентарный номер и название. В 557 | базе данных должна храниться следующая информация о каждом документе 558 | архива: номер стеллажа, номер полки, номер ячейки, где хранится документ, 559 | название документа и название темы, к которой он относится, его 560 | инвентарный номер, количество экземпляров документа, содержащихся в 561 | ячейке, дата поступления документа в архив. Документ может быть 562 | востребован абонентом архива. Абонент характеризуется фамилией, именем, 563 | отчеством, номером и телефоном отдела, где он работает. Работники архива, 564 | выдавая документ, должны зафиксировать, когда и кому он был выдан. 565 | Архив может пополняться документами, как новыми, так и копиями уже 566 | имеющихся в архиве. Экземпляр документа может быть утрачен. Возможна 567 | закупка новых стеллажей и списание старых. Документ может поменять 568 | место хранения и инвентарный номер. Возможно и изменение сведений об 569 | абонентах. Абонент может поменять фамилию, перейти в другой отдел, 570 | уволится с предприятия. Возможно изменение номеров телефонов отделов. 571 | Работнику архива могут потребоваться следующие сведения: 572 | - Название наиболее востребованного документа? 573 | - Общее количество документов на заданную тему? 574 | - Тема документа по заданному названию? 575 | - Название документа, который имеется в архиве в максимальном 576 | количестве экземпляров? 577 | - Фамилия, имя и отчество абонента, который брал указанный документ 578 | последним? 579 | - Есть ли в архиве пустые стеллажи, полки, ячейки, и в каком 580 | количестве? 581 | - Список документов, не востребованных в течение более, чем 5 лет? 582 | 583 | # Вариант 20 584 | Пусть требуется создать программную систему, предназначенную для 585 | работников туристической фирмы. Такая система должна обеспечивать 586 | хранение сведений об имеющихся в продаже путевках и о клиентах фирмы. 587 | Сведения о путевке включают ее стоимость, время отправления и 588 | возвращения, маршрут, способы перемещения, места для проживания, 589 | экскурсии и прочие услуги, например, в стоимость путевки полностью или 590 | частично может входить питание. Путевка может предполагать посещение 591 | одной или нескольких стран, одного или нескольких населенных пунктов. 592 | Сведения о клиентах – это фамилия, имя, отчество, номер контактного 593 | телефона, паспортные данные, дата регистрации, особые замечания. Если у 594 | клиента есть загранпаспорт, то его номер, дата выдачи, срок действия 595 | должны быть зафиксированы в БД уже при регистрации. То же касается и 596 | визы: если клиент имеет визу, то в БД должны быть указаны сроки ее 597 | действия и тип визы. Если паспорта и/или визы у клиента нет, то работник 598 | туристической фирмы должен ее оформить по существующим расценкам в 599 | установленные сроки. В обязанности работника туристической фирмы 600 | входит продажа стандартных путевок, подбор индивидуальных туров для 601 | клиентов не предусмотрен. Клиент может высказать свои пожелания 602 | относительно сроков поездки, ее стоимости, стран, которые он хотел бы 603 | посетить. Для постоянных клиентов существует система скидок. 604 | Работнику туристической фирмы могут потребоваться следующие 605 | данные: 606 | - Какие есть путевки по цене, не превышающей ту, которую указал 607 | клиент? 608 | - Можно ли отдохнуть в указанной стране в указанные сроки? Показать 609 | все возможные варианты. 610 | - Сколько будет стоить оформление визы и паспорта при условии 611 | покупки указанной путевки? 612 | - Какие путевки позволяют отдохнуть в указанные сроки и не 613 | предполагают использования самолета в качестве средства перемещения? 614 | - Какие путевки являются «горящими», то есть дата отправления, 615 | указанная в них, не более, чем на 5 дней больше текущей? 616 | - Какие скидки возможны для постоянных клиентов фирмы? 617 | - Что представляет собой самая дорогая путевка из имеющихся в 618 | продаже на текущий день? 619 | 620 | 621 | # Вариант 21 622 | 623 | Пусть требуется создать программную систему, предназначенную для 624 | продавца журналов/комиксов. Такая система должна обеспечивать хранение 625 | сведений об имеющихся в магазине журналах, о читателях журналов и 626 | списке магазинов. 627 | Для каждого журнала в БД должны храниться следующие сведения: 628 | название журнала, серия, автор (ы), издательство, год издания, число экземпляров 629 | в каждом магазине, а также ISBN и дата продажи журнала. 630 | Сведения о читателях библиотеки должны включать почту (email), 631 | ФИО покупателя, дату рождения, адрес, номер телефон. 632 | Нужно учесть, что покупатели могут делать заказы с разных магазинов, 633 | но нужно сохранять информацию, о предпочтительных магазинах (в которых чаще делают заказы). 634 | Магазин имеет несколько отделов, которые характеризуются номером, названием и кол-во журналов (вместимость). 635 | Магазин может получать новые журналы и списывать старые. ISBN 636 | может измениться в результате переклассификации, а почта в результате перерегистрации. 637 | Продавцу могут потребоваться следующие сведения о текущем 638 | состоянии библиотеки: 639 | - Какие журналы были куплены определенным покупателем? 640 | - Как называется журнал с заданным ISBN? 641 | - Какой ISBN у журнала с заданным названием? 642 | - Когда журнал был куплен? 643 | - Кто из покупателей купил журнал более месяца тому назад? 644 | - Найти покупателя самых редких журналов (по наличию в магазине)? 645 | - Какое число покупателей пользуется определенным магазином? 646 | - Сколько покупателей младше 20 лет? 647 | 648 | # Вариант 22 649 | 650 | Пусть требуется создать программную систему для поиска вакансий (аналог hh.ru). 651 | Такая система должна обеспечивать хранение сведений о работодателях и работниках. 652 | Эти сведения включают в себя (для работника) - паспортные работника, данные трудовой книжки, ИНН, дата рождения, информацию о среднем/высшем(их) образованиях, дата поступления на работу, в институт, информация об предыдущей работе(ах) из трудовой книжки. Данные трудовой книжки – это ее номер и дата выдачи, а также даты и номера приказов о зачислении и увольнении, о переходе в другое подразделение или об изменении должности. Кроме того, для работник может создать 1/несколько резюме, с указанием желаемой должности, ЗП, свои умения/навыки. Работодатель имеет возможность создавать/удалять/помещать в архив вакансии. Вакания имеет название, ЗП, должность, адрес, требования, условия, комментарий, требуемый опыт. У работодателя есть страница с указанием информации о себе - название, фото, описание, файлы презентации, сфера деятельности (IT, финансовая и т.п.), количество вакансий (формируется на основе списка вакансий). 653 | 654 | Система должна давать ответы на следующие вопросы: 655 | - Какие вакансии есть у данной компании? 656 | - Какая вакансия подходит мне по названию? 657 | - Сколько поблизости вакансий от меня (указание улицы)? 658 | - Какие вакансии были помещены в архив у компании? 659 | - Средняя ЗП каждого работодателя? 660 | - Сколько работников ищут работу, имея высшее образование? 661 | - Сколько работников имело более 3-х мест работы? 662 | - Какие вакансии имеют ЗП более 100 000р и не требуют опыта работы? 663 | -------------------------------------------------------------------------------- /lab-2/README.md: -------------------------------------------------------------------------------- 1 | # Лабораторная работа №2 2 | > Реализация базы данных в СУБД PostgreSQL 3 | 4 | Необходимо развернуть PostgreSQL локально: 5 | - Написать запросы для создания таблиц из предыдущей лабораторный работы 6 | - Заполнить тестовыми данными: 5-10 строк на каждую таблицу, обязательно наличие связи между ними, данные приближены к реальности. 7 | - Написать запросы к БД, отвечающие на вопросы из предыдущей лабораторной работы 8 | - Исходный код выложить на www.db-fiddle.com для проверки работоспособности 9 | - Исходный код в виде .sql файла запушить в виде PR в репо 10 | - В отчете описать: 11 | - Цель 12 | - Текст задания в соответствии с вариантом 13 | - Скриншоты работы с СУБД PostgreSQL ([psql](https://www.postgresql.org/docs/current/app-psql.html) / [DBeaver](https://dbeaver.io/) / [Datagrip](https://www.jetbrains.com/datagrip/), ...) 14 | - Скриншоты на каждый запрос (или группу запросов) на изменение/таблицы с выводом результатов (ответ) 15 | - Исходный код в приложении 16 | - Ссылку на исходный код www.db-fiddle.com в приложении 17 | - Ссылка на PR в приложении 18 | - Вывод 19 | -------------------------------------------------------------------------------- /lab-2/lab2.sql: -------------------------------------------------------------------------------- 1 | create table users 2 | ( 3 | id integer not null primary key AUTO_INCREMENT, 4 | username varchar(255) not null unique, 5 | email varchar(254) not null unique, 6 | avatar varchar(200), 7 | isActive bool not null, 8 | isStaff bool not null, 9 | role varchar(15) 10 | ); 11 | 12 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (1, 'name_0', 'sample_0_email@gmail.com', null, 1, 0, 'admin'); 13 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (2, 'name_1', 'sample_1_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 0, 0, 'admin'); 14 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (3, 'name_2', 'sample_2_email@gmail.com', null, 1, 0, 'admin'); 15 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (4, 'name_3', 'sample_3_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 0, 0, 'admin'); 16 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (5, 'name_4', 'sample_4_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 0, 1, 'guest'); 17 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (6, 'name_5', 'sample_5_email@gmail.com', null, 0, 1, 'admin'); 18 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (7, 'name_6', 'sample_6_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 1, 1, 'guest'); 19 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (8, 'name_7', 'sample_7_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 1, 1, 'admin'); 20 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (9, 'name_8', 'sample_8_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 1, 1, 'guest'); 21 | INSERT INTO users (id, username, email, avatar, isActive, isStaff, role) VALUES (10, 'name_9', 'sample_9_email@gmail.com', 'https://e7.pngegg.com/pngimages/340/946/png-clipart-avatar-user-computer-icons-software-developer-avatar-child-face.png', 0, 1, 'guest'); 22 | 23 | 24 | 25 | 26 | SELECT * FROM users; 27 | 28 | SELECT username, email FROM users WHERE isActive = true AND email LIKE 'sample_0%'; 29 | -------------------------------------------------------------------------------- /lab-3/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /lab-3/README.md: -------------------------------------------------------------------------------- 1 | # Лабораторная работа №3 2 | 3 | > Реализация базы данных с использованием ORM 4 | 5 | В данной лабораторной работе рекомендуется использовать [Sequelize](https://sequelize.org/) ([Node.js](https://nodejs.org/en)). В случае, если не знаете как с ним работать, то можно воспользоваться примером из репозитория. 6 | 7 | Вы можете использовать другой ORM по вашему выбору по согласованию с преподавателем, принимающим у вас практики. 8 | 9 | Необходимо развернуть [Sequelize](https://sequelize.org/) на своем ПК и выполнить следующие задачи: 10 | - Описать в виде моделей Sequelize таблицы из 1-й лабораторной работы 11 | - Написать скрипт заполнения тестовыми данными: 5-10 строк на каждую таблицу, обязательно наличие связи между ними, данные приближены к реальности. 12 | - Написать запросы к БД, отвечающие на вопросы из 1-й лабораторной работы **с использованием ORM**. Вывести результаты в консоль (или иной человеко-читабельный вывод) 13 | - Запушить в репозиторий исходный код проекта, соблюсти .gitignore, убрать исходную базу из проекта (или иные нагенерированные данные бд если они есть). 14 | - Описать процесс запуска: команды, зависимости 15 | - В отчете описать цель, текст задания в соответствии с вариантом, выбранную ORM, инструкцию по запуску, скриншоты (код) моделей ORM, скриншоты на каждый запрос (или группу запросов) на изменение/таблицы с выводом результатов (ответ), ссылку на PR в приложении, вывод 16 | 17 | # Пример структуры исходного кода 18 | 19 | TODO :3 20 | 21 | Используемые пакеты Node.js: 22 | - [sequelize](https://sequelize.org/) 23 | - [sequlize-typescript](https://github.com/sequelize/sequelize-typescript) 24 | - [yargs](https://www.npmjs.com/package/yargs) 25 | -------------------------------------------------------------------------------- /lab-4/README.md: -------------------------------------------------------------------------------- 1 | # Лабораторная работа 4 2 | 3 | > Нагрузочное тестирование БД 4 | 5 | Задачи: 6 | - Написать скрипт, заполняющий БД большим количеством тестовых данных, рекомендуется использовать [faker.js](https://github.com/faker-js/faker). 7 | - Измерить время выполнения запросов, написанных в ЛР3. 8 | - Проверить для числа записей: 9 | - 100 записей в каждой табличке 10 | - 1.000 записей 11 | - 1.0000 записей 12 | - 1.000.000 записей 13 | - можно больше. 14 | - Все запросы выполнять с фиксированным ограничением на вывод (LIMIT), т.к. запросы без LIMIT всегда будет выполняться O(n) от кол-ва записей 15 | - Проверить влияние сортировки на скорость выполнения запросов. 16 | - Для измерения использовать фактическое (не процессорное и т.п.) время. Для node.js есть [console.time и console.timeEnd](https://nodejs.org/api/console.html#console_console_time_label). 17 | - Добавить в БД индексы (хотя бы 5 штук). Измерить влияние (или его отсутствие) индексов на скорость выполнения запросов. Обратите внимание на: 18 | - Скорость сортировки больших табличек 19 | - Скорость JOIN 20 | (но остальные запросы тоже проверьте) 21 | -------------------------------------------------------------------------------- /lab-5/README.md: -------------------------------------------------------------------------------- 1 | # Лабораторная работа 5 2 | 3 | > Тестирование БД на безопасность 4 | 5 | Задачи: 6 | - Сделать простой web-сервер для выполнения запросов из ЛР3, например с [express.js](https://expressjs.com/). Не обязательно делать авторизацию и т.п., хватит одного эдпоинта на каждый запрос, с параметрами запроса как query parameters. 7 | - Намеренно сделайте несколько (2-3) запроса, подверженных SQL-инъекциям 8 | - Проверьте Ваше API с помощью [sqlmap](https://sqlmap.org/) (или чего-то аналогичного), передав эндпоинты в качестве целей атаки. Посмотрите, какие уязвимости он нашёл (и не нашёл), опишите пути к исправлению. 9 | - +2 балла, если напишете эндпоинт с уязвимостью, которая не находится sqlmap-ом. 10 | --------------------------------------------------------------------------------