diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be0a1bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +lab2/students_test.txt diff --git a/lab2/data_list_student_short.rb b/lab2/data_list_student_short.rb index 1e03313..8a19c3b 100644 --- a/lab2/data_list_student_short.rb +++ b/lab2/data_list_student_short.rb @@ -2,8 +2,8 @@ require_relative './data_table' class DataListStudentShort < DataList def initialize(items) - filtered = items.select { |item| item.is_a?(StudentShort) } - super(filtered) + column_names = ['№', 'Фамилия и инициалы', 'Телефон', 'Telegram', 'Email'] + super(items.select { |item| item.is_a?(StudentShort) }, column_names) @items = filtered.dup end diff --git a/lab2/data_table.rb b/lab2/data_table.rb index 6c2db94..0dd753b 100644 --- a/lab2/data_table.rb +++ b/lab2/data_table.rb @@ -29,9 +29,10 @@ class DataTable end class DataList - def initialize(items) + def initialize(items, column_names = []) @items = items.dup.freeze @selected = [] + @column_names = column_names end def select(number) @@ -44,7 +45,7 @@ class DataList end def get_names - raise NotImplementedError, "Implement this method in a subclass" + @column_names end def get_data diff --git a/lab2/output_students.txt b/lab2/output_students.txt deleted file mode 100644 index e69de29..0000000 diff --git a/lab2/person.rb b/lab2/person.rb index e01ab4e..f6f71e1 100644 --- a/lab2/person.rb +++ b/lab2/person.rb @@ -40,6 +40,10 @@ class Person /\A[^@\s]+@[^@\s]+\.[^@\s]+\z/.match?(email) end + def id=(id) + @id = id + end + def phone=(phone) if phone && !self.class.valid_phone_number?(phone) raise ArgumentError, "Недопустимый номер телефона: #{phone}" diff --git a/lab2/students.txt b/lab2/students.txt deleted file mode 100644 index 8713015..0000000 --- a/lab2/students.txt +++ /dev/null @@ -1,3 +0,0 @@ -Иванов Иван Иванович | ID: 1 | Phone: +12345678901 | Telegram: @ivanov_user | Email: ivanov@example.com | Git: https://github.com/ivanov -Петров Петр Петрович | ID: 2 | Phone: +98765432101 | Telegram: @petrov_user | Email: petrov@example.com | Git: https://github.com/petrov -Сидоров Сидор Сидорович | ID: 3 | Phone: +56789012345 | Telegram: @sidorov_user | Email: sidorov@example.com | Git: https://github.com/sidorov diff --git a/lab2/students_list_txt.rb b/lab2/students_list_txt.rb new file mode 100644 index 0000000..4f3f931 --- /dev/null +++ b/lab2/students_list_txt.rb @@ -0,0 +1,119 @@ +require_relative 'data_list_student_short' + +class Students_list_txt + attr_reader :students + + def initialize(filename) + @filename = filename + @students = [] + end + + # Чтение всех значений из файла. + # Предполагается, что каждая строка файла соответствует формату, + # который понимает метод Student.from_string. + def load_from_file + if File.exist?(@filename) + File.open(@filename, 'r') do |file| + @students = file.each_line.map do |line| + line = line.strip + next if line.empty? + begin + Student.from_string(line) + rescue ArgumentError => e + warn "Ошибка при парсинге строки: #{line}. #{e.message}" + nil + end + end.compact + end + else + @students = [] + end + self + end + + # Запись всех значений в файл. + # Для записи используется формат, возвращаемый методом to_s у объекта Student. + def save_to_file + File.open(@filename, 'w') do |file| + @students.each do |student| + file.puts student.to_s + end + end + self + end + + # Получить объект класса Student по ID. + def get_student_by_id(id) + @students.find { |s| s.id.to_s == id.to_s } + end + + # Получить список из k элементов, начиная с (n-1)*k-й записи, в виде объекта DataList. + # Если передан существующий объект data_list, то его список обновляется. + # При выборке сначала выполняется сортировка по фамилии и инициалам. + # + # Пример: k = 20, n = 2 даст вторую «страницу» из 20 элементов. + def get_k_n_student_short_list(k, n, data_list = nil) + start_index = (n - 1) * k + # Сортировка по ФамилияИнициалы + sorted_students = @students.sort_by { |s| s.surname_initials } + selected_students = sorted_students[start_index, k] || [] + # Преобразуем объекты Student в StudentShort + short_objects = selected_students.map { |s| StudentShort.from_student(s) } + + if data_list && data_list.is_a?(DataList) + if data_list.respond_to?(:items=) + data_list.items = short_objects + else + data_list = DataListStudentShort.new(short_objects) + end + data_list + else + DataListStudentShort.new(short_objects) + end + end + + # Сортировать список студентов по ФамилияИнициалы. + def sort_students! + @students.sort_by! { |s| s.surname_initials } + end + + # Добавить объект Student в список (при добавлении формируется новый ID). + # Новый ID вычисляется как (максимальный существующий id + 1) или 1, если список пуст. + def add_student(student) + new_id = if @students.empty? + 1 + else + max_id = @students.map { |s| s.id.to_i }.max + max_id + 1 + end + student.id = new_id.to_s + @students << student + student + end + + # Заменить элемент списка по ID. + # Если элемент найден, новый объект получает тот же ID. + def update_student_by_id(id, new_student) + index = @students.find_index { |s| s.id.to_s == id.to_s } + if index + new_student.id = @students[index].id + @students[index] = new_student + true + else + false + end + end + + # Удалить элемент списка по ID. + # Возвращает true, если удаление прошло успешно. + def delete_student_by_id(id) + initial_count = @students.size + @students.reject! { |s| s.id.to_s == id.to_s } + initial_count != @students.size + end + + # Получить количество студентов в списке. + def get_student_short_count + @students.size + end +end diff --git a/lab2/test_students_list_txt.rb b/lab2/test_students_list_txt.rb new file mode 100644 index 0000000..5c17848 --- /dev/null +++ b/lab2/test_students_list_txt.rb @@ -0,0 +1,71 @@ +require 'date' +require_relative 'students_list_txt' +require_relative 'student' +require_relative 'student_short' + +def run_tests + filename = 'students_test.txt' + students_list = Students_list_txt.new(filename) + + # 1. Добавление студентов. Передаём временный ID '0', который будет заменён. + student1 = Student.new( + id: '0', git: 'gituser1', surname: 'Иванов', name: 'Иван', patronymic: 'Иванович', + birth_date: Date.new(2000, 5, 14), phone: '1234567890', telegram: '@ivanov', email: 'ivanov@example.com' + ) + student2 = Student.new( + id: '0', git: 'gituser2', surname: 'Петров', name: 'Петр', patronymic: 'Петрович', + birth_date: Date.new(1999, 8, 22), phone: '0987654321', telegram: '@petrov', email: 'petrov@example.com' + ) + + students_list.add_student(student1) + students_list.add_student(student2) + + puts "Добавленные студенты:\n#{students_list.students.map(&:to_s).join("\n")}" + + # 2. Сохранение и загрузка из файла + students_list.save_to_file + students_list.load_from_file + + puts "\nЗагруженные студенты из файла:\n#{students_list.students.map(&:to_s).join("\n")}" + + # 3. Получение студента по ID + student = students_list.get_student_by_id(1) + puts "\nНайден студент по ID 1: #{student}" + + # 4. Получение "страничного" списка StudentShort (1 элемент на страницу, 1-я страница) + short_list = students_list.get_k_n_student_short_list(1, 1) + puts "\nПервая страница списка StudentShort:" + short_list.get_data.rows_count.times do |row| + puts short_list.get_data.item(row, 1) # выводим Фамилия и инициалы + end + + # 5. Обновление студента + updated_student = Student.new( + id: '0', git: 'gituser1_updated', surname: 'Иванов', name: 'Иван', patronymic: 'Иванович', + birth_date: Date.new(2000, 5, 14), phone: '1112223333', telegram: '@ivanov_updated', email: 'ivanov@newmail.com' + ) + students_list.update_student_by_id(1, updated_student) + puts "\nОбновленный студент с ID 1: #{students_list.get_student_by_id(1)}" + + # 6. Удаление студента + students_list.delete_student_by_id(2) + puts "\nСтуденты после удаления студента с ID 2:\n#{students_list.students.map(&:to_s).join("\n")}" + + # 7. Проверка сортировки + student3 = Student.new( + id: '0', git: 'gituser3', surname: 'Алексеев', name: 'Алексей', patronymic: 'Алексеевич', + birth_date: Date.new(2001, 12, 5), phone: '2223334444', telegram: '@alekseev', email: 'alekseev@example.com' + ) + students_list.add_student(student3) + students_list.sort_students! + + puts "\nСписок студентов после сортировки:" + students_list.students.each do |st| + puts st.to_s + end + + # 8. Количество студентов + puts "\nОбщее количество студентов: #{students_list.get_student_short_count}" +end + +run_tests