refactor: rename student list classes for consistency and improve code structure (LAB 4 TASK 4)

lab4
Artem-Darius Weber 2 months ago
parent 9f98ff8eed
commit c586e3ed93

@ -0,0 +1,89 @@
require_relative 'student'
require_relative 'student_short'
require_relative 'data_list_student_short'
require_relative 'data_table'
class StudentsListBase
attr_reader :students
def initialize(filename)
@filename = filename
@students = []
end
# Абстрактный метод для загрузки данных.
def load_from_file
raise NotImplementedError, "Метод load_from_file должен быть реализован в подклассе"
end
# Абстрактный метод для сохранения данных.
def save_to_file
raise NotImplementedError, "Метод save_to_file должен быть реализован в подклассе"
end
# Получить объект Student по ID.
def get_student_by_id(id)
@students.find { |s| s.id.to_s == id.to_s }
end
# Получить список из k студентов (страница n) в виде объекта DataList.
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] || []
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).
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.
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.
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

@ -1,20 +1,9 @@
require 'json'
require 'date'
require_relative 'students_list_base'
require_relative 'student'
require_relative 'student_short'
require_relative 'data_list_student_short'
require_relative 'data_table'
class Students_list_JSON
attr_reader :students
def initialize(filename)
@filename = filename
@students = []
end
# Чтение всех значений из JSON-файла.
# Файл должен содержать массив хэшей, где каждый хэш представляет студента.
class StudentsListJSON < StudentsListBase
def load_from_file
if File.exist?(@filename)
file_content = File.read(@filename)
@ -31,8 +20,6 @@ class Students_list_JSON
self
end
# Запись всех значений в JSON-файл.
# Преобразуем каждый объект Student в хэш.
def save_to_file
data = @students.map { |student| student_to_hash(student) }
File.open(@filename, 'w') do |file|
@ -44,81 +31,8 @@ class Students_list_JSON
self
end
# Получить объект Student по ID.
def get_student_by_id(id)
@students.find { |s| s.id.to_s == id.to_s }
end
# Получить список из k студентов (на "странице" n) в виде DataList объекта.
# При этом сначала список студентов сортируется по ФамилияИнициалы,
# а затем из него выбирается срез нужного размера.
# Если передан существующий объект data_list, то его список обновляется.
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] || []
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
private
# Преобразование объекта Student в хэш для записи в JSON.
def student_to_hash(student)
{
'id' => student.id,
@ -133,7 +47,6 @@ class Students_list_JSON
}
end
# Преобразование хэша в объект Student.
def hash_to_student(hash)
Student.new(
id: hash['id'],

@ -1,21 +1,12 @@
require_relative 'data_list_student_short'
require_relative 'students_list_base'
require_relative 'student'
class Students_list_txt
attr_reader :students
def initialize(filename)
@filename = filename
@students = []
end
# Чтение всех значений из файла.
# Предполагается, что каждая строка файла соответствует формату,
# который понимает метод Student.from_string.
class StudentsListTXT < StudentsListBase
def load_from_file
if File.exist?(@filename)
File.open(@filename, 'r') do |file|
@students = file.each_line.map do |line|
line = line.strip
line.strip!
next if line.empty?
begin
Student.from_string(line)
@ -31,8 +22,6 @@ class Students_list_txt
self
end
# Запись всех значений в файл.
# Для записи используется формат, возвращаемый методом to_s у объекта Student.
def save_to_file
File.open(@filename, 'w') do |file|
@students.each do |student|
@ -41,79 +30,4 @@ class Students_list_txt
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

@ -1,20 +1,10 @@
# students_list_yaml.rb
require 'yaml'
require 'date'
require_relative 'students_list_base'
require_relative 'student'
require_relative 'student_short'
require_relative 'data_list_student_short'
require_relative 'data_table'
class Students_list_YAML
attr_reader :students
def initialize(filename)
@filename = filename
@students = []
end
# Чтение всех значений из YAML-файла.
# Файл должен содержать массив хэшей, каждый из которых представляет студента.
class StudentsListYAML < StudentsListBase
def load_from_file
if File.exist?(@filename)
begin
@ -30,8 +20,6 @@ class Students_list_YAML
self
end
# Запись всех значений в YAML-файл.
# Каждый объект Student преобразуется в хэш.
def save_to_file
data = @students.map { |student| student_to_hash(student) }
File.open(@filename, 'w') do |file|
@ -43,79 +31,8 @@ class Students_list_YAML
self
end
# Получить объект Student по ID.
def get_student_by_id(id)
@students.find { |s| s.id.to_s == id.to_s }
end
# Получить список из k студентов (страница n) в виде объекта DataList.
# Сначала список сортируется по ФамилияИнициалы, затем выбирается нужный срез.
# Результат преобразуется в объекты StudentShort.
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] || []
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).
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
private
# Преобразование объекта Student в хэш для записи в YAML.
def student_to_hash(student)
{
'id' => student.id,
@ -130,7 +47,6 @@ class Students_list_YAML
}
end
# Преобразование хэша в объект Student.
def hash_to_student(hash)
Student.new(
id: hash['id'],

@ -1,4 +1,3 @@
# test_students_list_json.rb
require 'minitest/autorun'
require 'json'
require 'date'
@ -12,7 +11,7 @@ class TestStudentsListJSON < Minitest::Test
def setup
# Удаляем временный файл перед каждым тестом, если он существует
File.delete(TEMP_FILE) if File.exist?(TEMP_FILE)
@students_list = Students_list_JSON.new(TEMP_FILE)
@students_list = StudentsListJSON.new(TEMP_FILE)
# Создаём несколько объектов Student для тестирования
@student1 = Student.new(
@ -65,7 +64,7 @@ class TestStudentsListJSON < Minitest::Test
@students_list.save_to_file
# Создаём новый объект, который загрузит данные из файла
new_list = Students_list_JSON.new(TEMP_FILE)
new_list = StudentsListJSON.new(TEMP_FILE)
new_list.load_from_file
# Проверяем, что количество студентов совпадает

@ -5,7 +5,7 @@ require_relative '../student_short'
def run_tests
filename = 'students_test.txt'
students_list = Students_list_txt.new(filename)
students_list = StudentsListTXT.new(filename)
# 1. Добавление студентов. Передаём временный ID '0', который будет заменён.
student1 = Student.new(
@ -32,11 +32,11 @@ def run_tests
student = students_list.get_student_by_id(1)
puts "\nНайден студент по ID 1: #{student}"
# 4. Получение "страничного" списка StudentShort (1 элемент на страницу, 1-я страница)
# 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) # выводим Фамилия и инициалы
puts short_list.get_data.item(row, 1) # выводим Фамилию и инициалы
end
# 5. Обновление студента

@ -1,4 +1,3 @@
# test_students_list_yaml.rb
require 'minitest/autorun'
require 'yaml'
require 'date'
@ -12,7 +11,7 @@ class TestStudentsListYAML < Minitest::Test
def setup
# Удаляем временный файл перед каждым тестом, если он существует
File.delete(TEMP_FILE) if File.exist?(TEMP_FILE)
@students_list = Students_list_YAML.new(TEMP_FILE)
@students_list = StudentsListYAML.new(TEMP_FILE)
# Создаём несколько объектов Student для тестирования
@student1 = Student.new(
@ -65,7 +64,7 @@ class TestStudentsListYAML < Minitest::Test
@students_list.save_to_file
# Создаём новый объект, который загрузит данные из файла
new_list = Students_list_YAML.new(TEMP_FILE)
new_list = StudentsListYAML.new(TEMP_FILE)
new_list.load_from_file
# Проверяем, что количество студентов совпадает

Loading…
Cancel
Save