Урок 81. Практикум 20: Данные о сотрудниках. Часть 2

📁 Блок: Базы данных ⏱️ Время изучения: ~90 мин 🎯 Сложность: Практикум
#for #in #with #as #enumerate #from #print

⚡ Суть задания

Выполнить пять практических задач по работе с базой hr через PyMySQL: сортировка, выбор по номеру, пустой отдел, фильтрация по зарплате и повторный ввод при ошибке.

Результат: файл employees_report.py, который корректно обрабатывает ввод и выводит данные о сотрудниках.

📋 Формулировка задания

Исходное задание из LMS:

  1. Список сотрудников по убыванию зарплаты. Добавьте сортировку сотрудников выбранного отдела по убыванию зарплаты. Выведите имя, фамилию, должность и зарплату с нумерацией.
  2. Выбор отдела по номеру. Пользователь выбирает отдел по номеру из списка, а не вводит название.
  3. Пустой отдел. Если в отделе нет сотрудников, выведите сообщение No employees found in this department..
  4. Фильтрация по зарплате. Добавьте возможность фильтровать сотрудников по зарплате с проверкой оператора сравнения.
  5. Повторный ввод при ошибке. При некорректном номере отдела программа просит ввести его снова.

🔧 Шаг 0. Подготовка окружения

Эти шаги стандартны для практических работ курса.

📁 Структура репозитория: мы используем один репозиторий для всех практических работ курса.
1

Создайте (или откройте) рабочую папку

В VS Code нажмите Ctrl+K Ctrl+O → выберите или создайте папку python-fundamentals-practice.

# Или в терминале VS Code (Ctrl + `):
mkdir python-fundamentals-practice
cd python-fundamentals-practice
2

Создайте папку для урока

mkdir -p lesson-81
cd lesson-81
3

Создайте виртуальное окружение

# Windows
python -m venv venv
venv\Scripts\activate

# Mac / Linux
python3 -m venv venv
source venv/bin/activate

После активации в начале строки появится (venv).

4

Установите PyMySQL

pip install pymysql
pip freeze > requirements.txt

🛠️ Шаги выполнения задания

1

Создайте файл employees_report.py

В папке lesson-81 создайте файл employees_report.py.

2

Реализуйте задания по порядку

Начните с задания 1: подключение, список отделов, запрос с сортировкой. После успешного запуска добавляйте задание 2, затем 3, 4 и 5. Запускайте файл после каждого шага.

3

Проверьте работу в VS Code

python lesson-81/employees_report.py

Проверьте следующие сценарии:

  • Корректный номер отдела → выводится список сотрудников.
  • Номер пустого отдела → сообщение об отсутствии сотрудников.
  • Некорректный номер или текст → программа просит повторить ввод.
  • Фильтр по зарплате с недопустимым оператором → сообщение об ошибке.

✅ Полное решение

Ниже приведено полное решение всех пяти задач. Совет: попробуйте выполнить самостоятельно, прежде чем смотреть ответ.

import pymysql

VALID_OPERATORS = {'>', '<', '=', '>=', '<='}


def print_employees(rows):
    for i, (first, last, title, salary) in enumerate(rows, start=1):
        print(f"{i}. {first} {last} — {title} — {salary}")


def read_department_number(departments):
    while True:
        try:
            selected_index = int(input("Enter department number: "))
            if 1 <= selected_index <= len(departments):
                return selected_index
            print("Invalid department number. Please try again.")
        except ValueError:
            print("Invalid input. Please enter a number.")


def filter_by_salary(cursor, selected_department):
    condition = input("Enter condition (>, <, =, >=, <=): ").strip()
    if condition not in VALID_OPERATORS:
        print("Invalid condition.")
        return

    try:
        value = float(input("Enter salary: "))
    except ValueError:
        print("Invalid salary input.")
        return

    query = f"""
        SELECT first_name, last_name, job_title, salary
        FROM employees
        JOIN departments ON employees.department_id = departments.department_id
        JOIN jobs ON employees.job_id = jobs.job_id
        WHERE departments.department_name = %s AND salary {condition} %s
        ORDER BY salary DESC
    """
    cursor.execute(query, (selected_department, value))
    return cursor.fetchall()


def main():
    config = {
        "host": "ich-db.edu.itcareerhub.de",
        "user": "ich1",
        "password": "password",
        "database": "hr",
        "charset": "utf8mb4",
    }

    with pymysql.connect(**config) as connection:
        with connection.cursor() as cursor:
            cursor.execute("SELECT department_name FROM departments")
            departments = [row[0] for row in cursor]
            for i, name in enumerate(departments, start=1):
                print(f"{i}. {name}")

            selected_index = read_department_number(departments)
            selected_department = departments[selected_index - 1]
            print(f"You selected: {selected_department}")

            cursor.execute("""
                SELECT first_name, last_name, job_title, salary
                FROM employees
                JOIN departments ON employees.department_id = departments.department_id
                JOIN jobs ON employees.job_id = jobs.job_id
                WHERE departments.department_name = %s
            """, (selected_department,))

            results = cursor.fetchall()

            if not results:
                print("No employees found in this department.")
                return

            filter_choice = input("Would you like to filter employees by salary? (y/n) ").strip().lower()
            if filter_choice == 'y':
                filtered_results = filter_by_salary(cursor, selected_department)
                if filtered_results is None:
                    return
                if not filtered_results:
                    print("No employees match the given condition.")
                else:
                    print_employees(filtered_results)
            else:
                print_employees(results)


if __name__ == "__main__":
    main()

🧪 Как проверить решение

  1. Активируйте venv: venv\Scripts\activate (Windows) или source venv/bin/activate (Mac/Linux).
  2. Запустите файл: python lesson-81/employees_report.py.
  3. Введите номер отдела, например 2 (Marketing), и убедитесь, что вывод соответствует примеру.
  4. Проверьте обработку ошибок: введите текст, 0, номер больше количества отделов.
  5. Проверьте фильтр по зарплате с операторами >, <, =.

🐛 Отладка в VS Code

Если что-то не работает:

  1. Поставьте точку останова на строке с cursor.execute(...).
  2. Нажмите F5 или выберите «Run → Start Debugging».
  3. В панели Debug посмотрите значения selected_index, selected_department и condition.
  4. Проверьте Terminal — traceback укажет номер строки с ошибкой.

💾 Сохранение работы

git add lesson-81/
git commit -m "lesson-81: данные о сотрудниках, часть 2"
git push

💡 Советы и типичные ошибки

  • Не забудьте запятую в кортеже из одного параметра: (value,).
  • Пользовательский номер отдела начинается с 1, индекс списка — с 0.
  • Оператор сравнения нельзя передавать через %s — проверяйте его по белому списку.
  • Не коммитьте папку venv/ — она должна быть в .gitignore.