feat: enhance DataList and DataListStudentShort to support column names and improve data handling

lab4
Artem-Darius Weber 2 months ago
parent 67e0c0561e
commit b2cf71804a

1
.gitignore vendored

@ -0,0 +1 @@
lab2/students_test.txt

@ -2,8 +2,8 @@ require_relative './data_table'
class DataListStudentShort < DataList class DataListStudentShort < DataList
def initialize(items) def initialize(items)
filtered = items.select { |item| item.is_a?(StudentShort) } column_names = ['№', 'Фамилия и инициалы', 'Телефон', 'Telegram', 'Email']
super(filtered) super(items.select { |item| item.is_a?(StudentShort) }, column_names)
@items = filtered.dup @items = filtered.dup
end end

@ -29,9 +29,10 @@ class DataTable
end end
class DataList class DataList
def initialize(items) def initialize(items, column_names = [])
@items = items.dup.freeze @items = items.dup.freeze
@selected = [] @selected = []
@column_names = column_names
end end
def select(number) def select(number)
@ -44,7 +45,7 @@ class DataList
end end
def get_names def get_names
raise NotImplementedError, "Implement this method in a subclass" @column_names
end end
def get_data def get_data

@ -40,6 +40,10 @@ class Person
/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/.match?(email) /\A[^@\s]+@[^@\s]+\.[^@\s]+\z/.match?(email)
end end
def id=(id)
@id = id
end
def phone=(phone) def phone=(phone)
if phone && !self.class.valid_phone_number?(phone) if phone && !self.class.valid_phone_number?(phone)
raise ArgumentError, "Недопустимый номер телефона: #{phone}" raise ArgumentError, "Недопустимый номер телефона: #{phone}"

@ -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

@ -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

@ -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
Loading…
Cancel
Save