You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kubsu-sm5-ruby/lab2/students_list_json.rb

151 lines
4.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

require 'json'
require 'date'
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-файла.
# Файл должен содержать массив хэшей, где каждый хэш представляет студента.
def load_from_file
if File.exist?(@filename)
file_content = File.read(@filename)
begin
data = JSON.parse(file_content)
@students = data.map { |student_hash| hash_to_student(student_hash) }
rescue JSON::ParserError => e
warn "Ошибка парсинга JSON: #{e.message}"
@students = []
end
else
@students = []
end
self
end
# Запись всех значений в JSON-файл.
# Преобразуем каждый объект Student в хэш.
def save_to_file
data = @students.map { |student| student_to_hash(student) }
File.open(@filename, 'w') do |file|
file.write(JSON.pretty_generate(data))
end
self
rescue IOError => e
warn "Ошибка при записи в файл: #{e.message}"
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,
'git' => student.git,
'surname' => student.surname,
'name' => student.name,
'patronymic' => student.patronymic,
'birth_date' => student.birth_date.to_s,
'phone' => student.phone,
'telegram' => student.telegram,
'email' => student.email
}
end
# Преобразование хэша в объект Student.
def hash_to_student(hash)
Student.new(
id: hash['id'],
git: hash['git'],
surname: hash['surname'],
name: hash['name'],
patronymic: hash['patronymic'],
birth_date: Date.parse(hash['birth_date']),
phone: hash['phone'],
telegram: hash['telegram'],
email: hash['email']
)
end
end