students_list_yaml_gems 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/data_list.rb +42 -0
- data/lib/data_list_student_short.rb +24 -0
- data/lib/data_table.rb +24 -0
- data/lib/logger.rb +63 -0
- data/lib/student.rb +131 -0
- data/lib/student_short.rb +23 -0
- data/lib/student_superclass.rb +40 -0
- data/lib/students_list_base.rb +149 -0
- data/lib/students_list_yaml.rb +60 -0
- metadata +51 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 24550a4c94d1481f0231db32635e5f6065ce116bb1db7d2617780e1f2f31f6eb
|
|
4
|
+
data.tar.gz: 20753b23b4029e82c7f6b1be5a44a31e45c5db36b7e883b6d0ac71a3bbac7ba5
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 75df2aa0f5c7f3cf46b0cdfcdc978c40ad522dbaab586ded7caf2748d02256f064fde1fe1a0c88a98ba562e5d99d1b8570944b0c118b22a5a190f117ef25522c
|
|
7
|
+
data.tar.gz: 621f9b6c890d1c4ff44d6fb5b997753c84a88107d6733bb3546ed996f5e19a075ac50a9f5f7519b1428cb9861d43ede8b35d3c17e3cd78f8024299beab11e8a9
|
data/lib/data_list.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require_relative 'data_table'
|
|
2
|
+
class Data_list
|
|
3
|
+
def initialize(array)
|
|
4
|
+
@selected = []
|
|
5
|
+
@elements = array
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def select(number)
|
|
9
|
+
@selected << @elements[number]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_selected
|
|
13
|
+
@selected.map{ |x| x.id }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def get_names
|
|
17
|
+
get_names = ["№ по порядку"] + template_get_names()
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def get_data
|
|
21
|
+
get_data = []
|
|
22
|
+
@elements.each_with_index do |item, index|
|
|
23
|
+
get_data << [index] + template_get_data(item)
|
|
24
|
+
end
|
|
25
|
+
Data_table.new(get_data)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def clear_selected
|
|
29
|
+
@selected.clear
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
|
|
34
|
+
def template_get_data(item)
|
|
35
|
+
raise 'NotImplementedError'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def template_get_names
|
|
39
|
+
raise 'NotImplementedError'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'data_list'
|
|
2
|
+
require_relative 'student_short'
|
|
3
|
+
class Data_list_student_short < Data_list
|
|
4
|
+
|
|
5
|
+
def array=(array)
|
|
6
|
+
@array = array
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(array)
|
|
10
|
+
super
|
|
11
|
+
self.array=array
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def template_get_names
|
|
17
|
+
names = [ "Last name initialize", "Contact", "Git" ]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def template_get_data(value)
|
|
21
|
+
data = [ value.last_name_initials, value.contact || "", value.git || "" ]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
data/lib/data_table.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Data_table
|
|
2
|
+
def initialize(array)
|
|
3
|
+
@elements = []
|
|
4
|
+
array.each do |item|
|
|
5
|
+
@elements << item
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_s
|
|
10
|
+
@elements
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_element(i, j)
|
|
14
|
+
@elements[i][j].dup
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_count_rows
|
|
18
|
+
@elements.length.dup
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get_count_column
|
|
22
|
+
@elements[0].length.dup
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/logger.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
class Logger
|
|
2
|
+
LOG_LEVELS = {
|
|
3
|
+
debug: 0,
|
|
4
|
+
info: 1,
|
|
5
|
+
warn: 2,
|
|
6
|
+
error: 3,
|
|
7
|
+
fatal: 4
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
def initialize(log_file = 'application.log', level = :info)
|
|
11
|
+
@log_file = log_file
|
|
12
|
+
@level = LOG_LEVELS[level] || LOG_LEVELS[:info]
|
|
13
|
+
@mutex = Mutex.new
|
|
14
|
+
ensure_log_file
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def debug(message)
|
|
18
|
+
log(:debug, message) if @level <= LOG_LEVELS[:debug]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def info(message)
|
|
22
|
+
log(:info, message) if @level <= LOG_LEVELS[:info]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def warn(message)
|
|
26
|
+
log(:warn, message) if @level <= LOG_LEVELS[:warn]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def error(message)
|
|
30
|
+
log(:error, message) if @level <= LOG_LEVELS[:error]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def fatal(message)
|
|
34
|
+
log(:fatal, message) if @level <= LOG_LEVELS[:fatal]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def level=(new_level)
|
|
38
|
+
@level = LOG_LEVELS[new_level] || LOG_LEVELS[:info]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def ensure_log_file
|
|
44
|
+
return if File.exist?(@log_file)
|
|
45
|
+
File.write(@log_file, '')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def log(level, message)
|
|
49
|
+
@mutex.synchronize do
|
|
50
|
+
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")
|
|
51
|
+
log_entry = "[#{timestamp}] #{level.to_s.upcase}: #{message}\n"
|
|
52
|
+
|
|
53
|
+
File.open(@log_file, 'a') do |file|
|
|
54
|
+
file.write(log_entry)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Также выводим в консоль для отладки
|
|
58
|
+
puts log_entry.strip if @level <= LOG_LEVELS[:info]
|
|
59
|
+
end
|
|
60
|
+
rescue => e
|
|
61
|
+
STDERR.puts "Ошибка записи в лог: #{e.message}"
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/student.rb
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
require_relative 'student_superclass'
|
|
2
|
+
|
|
3
|
+
class Student < StudentSuper
|
|
4
|
+
include Comparable
|
|
5
|
+
attr_reader :last_name, :first_name, :patronymic, :phone, :telegram, :email
|
|
6
|
+
|
|
7
|
+
# Основной конструктор
|
|
8
|
+
def initialize(last_name:, first_name:, patronymic: nil, id: nil, phone: nil, telegram: nil, email: nil, git: nil)
|
|
9
|
+
raise ArgumentError, "Неверный git: #{git}" unless self.class.valid_git?(git)
|
|
10
|
+
|
|
11
|
+
super(id: id, git: git)
|
|
12
|
+
|
|
13
|
+
self.last_name = last_name
|
|
14
|
+
self.first_name = first_name
|
|
15
|
+
self.patronymic = patronymic
|
|
16
|
+
set_contact(phone: phone, telegram: telegram, email: email)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Конструктор из хеша (Задание 2.5)
|
|
20
|
+
def self.from_hash(hash)
|
|
21
|
+
new(
|
|
22
|
+
id: hash['id'] || hash[:id],
|
|
23
|
+
last_name: hash['last_name'] || hash[:last_name],
|
|
24
|
+
first_name: hash['first_name'] || hash[:first_name],
|
|
25
|
+
patronymic: hash['patronymic'] || hash[:patronymic] || hash['middle_name'] || hash[:middle_name],
|
|
26
|
+
phone: hash['phone'] || hash[:phone],
|
|
27
|
+
telegram: hash['telegram'] || hash[:telegram],
|
|
28
|
+
email: hash['email'] || hash[:email],
|
|
29
|
+
git: hash['git'] || hash[:git]
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.validated_attr_writer(attribute, validation_method)
|
|
34
|
+
define_method("#{attribute}=") do |value|
|
|
35
|
+
raise ArgumentError unless self.class.send(validation_method, value)
|
|
36
|
+
instance_variable_set("@#{attribute}", value)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
validated_attr_writer :first_name, :valid_name?
|
|
41
|
+
validated_attr_writer :last_name, :valid_name?
|
|
42
|
+
validated_attr_writer :patronymic, :valid_name?
|
|
43
|
+
validated_attr_writer :git, :valid_git?
|
|
44
|
+
|
|
45
|
+
def <=>(other)
|
|
46
|
+
[last_name, first_name, patronymic || nil] <=> [other.last_name, other.first_name, other.patronymic || nil]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def contact
|
|
50
|
+
return "telegram - #{@telegram}" if @telegram and !@telegram.empty?
|
|
51
|
+
return "email - #{@email}" if @email and !@email.empty?
|
|
52
|
+
return "phone - #{@phone}" if @phone and !@phone.empty?
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def set_contact(phone: nil, telegram: nil, email: nil)
|
|
57
|
+
@phone = phone if phone && self.class.valid_phone?(phone)
|
|
58
|
+
@telegram = telegram if telegram && self.class.valid_telegram?(telegram)
|
|
59
|
+
@email = email if email && self.class.valid_email?(email)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def contact=(contacts)
|
|
63
|
+
contacts.each do |type, value|
|
|
64
|
+
validator = "valid_#{type}?".to_sym
|
|
65
|
+
raise ArgumentError, "Неверный формат #{type}" unless self.class.send(validator, value)
|
|
66
|
+
instance_variable_set("@#{type}", value)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def last_name_initials
|
|
71
|
+
initials = ""
|
|
72
|
+
if first_name and patronymic
|
|
73
|
+
initials = "#{first_name[0]}. #{patronymic[0]}." if first_name and patronymic
|
|
74
|
+
elsif first_name
|
|
75
|
+
initials = "#{first_name[0]}."
|
|
76
|
+
else
|
|
77
|
+
initials = ""
|
|
78
|
+
end
|
|
79
|
+
"#{last_name} #{initials}".strip
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def to_s
|
|
83
|
+
info = []
|
|
84
|
+
info << "ID: #{id}" if id
|
|
85
|
+
info << "Фамилия: #{last_name}"
|
|
86
|
+
info << "Имя: #{first_name}"
|
|
87
|
+
info << "Отчество: #{patronymic}" if patronymic
|
|
88
|
+
info << "Телефон: #{@phone}" if @phone
|
|
89
|
+
info << "Telegram: #{@telegram}" if @telegram
|
|
90
|
+
info << "Email: #{@email}" if @email
|
|
91
|
+
info << "Git: #{git}" if git
|
|
92
|
+
info.join(", ")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def to_hash
|
|
96
|
+
{
|
|
97
|
+
id: @id,
|
|
98
|
+
last_name: @last_name,
|
|
99
|
+
first_name: @first_name,
|
|
100
|
+
patronymic: @patronymic,
|
|
101
|
+
phone: @phone,
|
|
102
|
+
telegram: @telegram,
|
|
103
|
+
email: @email,
|
|
104
|
+
git: @git
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.valid_name?(name)
|
|
109
|
+
name.nil? || name.is_a?(String) && name.match?(/\A[A-ZА-ЯЁ][a-zа-яё]+\z/)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.valid_phone?(phone)
|
|
113
|
+
return true if phone.nil? or phone.empty?
|
|
114
|
+
phone.match?(/^(\+7|8)?[\s\-\(]?(\d{3})[\s\-\)]?(\d{3})[\s\-]?(\d{2})[\s\-]?(\d{2})$/)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.valid_telegram?(telegram)
|
|
118
|
+
return true if telegram.nil? or telegram.empty?
|
|
119
|
+
telegram.match?(/^@[a-zA-Z0-9_]{5,32}$/)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.valid_email?(email)
|
|
123
|
+
return true if email.nil? or email.empty?
|
|
124
|
+
email.match?(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def self.valid_git?(git)
|
|
128
|
+
return true if git.nil? or git.empty?
|
|
129
|
+
git.match?(/^https:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\/?$/)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative 'student'
|
|
2
|
+
require_relative 'student_superclass'
|
|
3
|
+
class StudentShort < StudentSuper
|
|
4
|
+
attr_reader :last_name_initials, :contact
|
|
5
|
+
def initialize(id:, last_name_initials:, contact: nil, git: nil)
|
|
6
|
+
super(id: id, git: git)
|
|
7
|
+
@last_name_initials = last_name_initials
|
|
8
|
+
@contact = contact
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.from_student(student)
|
|
12
|
+
raise ArgumentError, "Student must not be nil" unless student
|
|
13
|
+
|
|
14
|
+
raise ArgumentError, "ID not found" unless student.id
|
|
15
|
+
|
|
16
|
+
new(
|
|
17
|
+
id: student.id,
|
|
18
|
+
last_name_initials: student.last_name_initials,
|
|
19
|
+
contact: student.contact,
|
|
20
|
+
git: student.git
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class StudentSuper
|
|
2
|
+
attr_reader :id, :git
|
|
3
|
+
|
|
4
|
+
def initialize(id: nil, git: nil)
|
|
5
|
+
@id = id
|
|
6
|
+
@git = git
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_s
|
|
10
|
+
short_info
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def short_info
|
|
14
|
+
info = []
|
|
15
|
+
info << "ID: #{id}" if id
|
|
16
|
+
info << "ФИО: #{last_name_initials}"
|
|
17
|
+
info << contact if contact
|
|
18
|
+
info << "Git: #{git}" if git
|
|
19
|
+
info
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def has_git?
|
|
23
|
+
!@git.nil? and !@git.empty?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def has_contact?
|
|
27
|
+
!@contact.nil? and !@contact.empty?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
protected
|
|
31
|
+
|
|
32
|
+
def contact
|
|
33
|
+
raise 'NotImplementedError'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def last_name_initials
|
|
37
|
+
raise 'NotImplementedError'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require_relative 'student'
|
|
2
|
+
require_relative 'student_short'
|
|
3
|
+
require_relative 'data_list_student_short'
|
|
4
|
+
|
|
5
|
+
class Students_list_base
|
|
6
|
+
def initialize
|
|
7
|
+
@students = []
|
|
8
|
+
@filename = nil
|
|
9
|
+
@logger = Logger.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Абстрактные методы
|
|
13
|
+
def read_from_file(filename)
|
|
14
|
+
raise NotImplementedError, "Метод read_from_file должен быть реализован в подклассе"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def write_to_file(filename)
|
|
18
|
+
raise NotImplementedError, "Метод write_to_file должен быть реализован в подклассе"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Получить объект класса Student по ID
|
|
22
|
+
def get_student_by_id(id)
|
|
23
|
+
@logger.debug("Поиск студента с ID: #{id}")
|
|
24
|
+
student = @students.find { |s| s.id == id }
|
|
25
|
+
if student
|
|
26
|
+
@logger.debug("Найден студент: #{student.last_name_initials}")
|
|
27
|
+
else
|
|
28
|
+
@logger.debug("Студент с ID #{id} не найден")
|
|
29
|
+
end
|
|
30
|
+
student
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Получить список k по счету n объектов класса Student_short
|
|
34
|
+
def get_k_n_student_short_list(k, n, existing_list = nil)
|
|
35
|
+
@logger.debug("Получение списка: страница #{k}, элементов #{n}")
|
|
36
|
+
|
|
37
|
+
# Сортируем по ФамилияИнициалы
|
|
38
|
+
sorted_students = @students.sort_by(&:last_name_initials)
|
|
39
|
+
|
|
40
|
+
# Преобразуем в Student_short
|
|
41
|
+
short_students = sorted_students.map { |s| StudentShort.from_student(s) }
|
|
42
|
+
|
|
43
|
+
# Вычисляем диапазон
|
|
44
|
+
start_index = (k - 1) * n
|
|
45
|
+
end_index = start_index + n - 1
|
|
46
|
+
|
|
47
|
+
# Получаем срез
|
|
48
|
+
result_data = short_students[start_index..end_index] || []
|
|
49
|
+
|
|
50
|
+
# Возвращаем или изменяем существующий список
|
|
51
|
+
if existing_list
|
|
52
|
+
existing_list.instance_variable_set(:@elements, result_data)
|
|
53
|
+
@logger.debug("Обновлен существующий список, элементов: #{result_data.size}")
|
|
54
|
+
existing_list
|
|
55
|
+
else
|
|
56
|
+
@logger.debug("Создан новый список, элементов: #{result_data.size}")
|
|
57
|
+
Data_list_student_short.new(result_data)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Сортировать элементы по набору ФамилияИнициалы
|
|
62
|
+
def sort_by_name
|
|
63
|
+
@logger.info("Сортировка списка студентов по ФамилияИнициалы")
|
|
64
|
+
@students.sort_by!(&:last_name_initials)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Добавить объект класса Student в список (при добавлении сформировать новый ID)
|
|
68
|
+
def add_student(student)
|
|
69
|
+
@logger.info("Добавление нового студента: #{student.last_name}")
|
|
70
|
+
|
|
71
|
+
# Генерация нового ID
|
|
72
|
+
new_id = @students.empty? ? 1 : @students.map(&:id).compact.max + 1
|
|
73
|
+
|
|
74
|
+
# Создаем нового студента с новым ID
|
|
75
|
+
new_student = Student.new(
|
|
76
|
+
id: new_id,
|
|
77
|
+
last_name: student.last_name,
|
|
78
|
+
first_name: student.first_name,
|
|
79
|
+
patronymic: student.patronymic,
|
|
80
|
+
phone: student.phone,
|
|
81
|
+
telegram: student.telegram,
|
|
82
|
+
email: student.email,
|
|
83
|
+
git: student.git
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
@students << new_student
|
|
87
|
+
save_changes
|
|
88
|
+
@logger.info("Студент добавлен с ID: #{new_id}")
|
|
89
|
+
new_id
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Заменить элемент списка по ID
|
|
93
|
+
def replace_student(id, student)
|
|
94
|
+
@logger.info("Замена студента с ID: #{id}")
|
|
95
|
+
|
|
96
|
+
index = @students.find_index { |s| s.id == id }
|
|
97
|
+
|
|
98
|
+
if index
|
|
99
|
+
updated_student = Student.new(
|
|
100
|
+
id: id,
|
|
101
|
+
last_name: student.last_name,
|
|
102
|
+
first_name: student.first_name,
|
|
103
|
+
patronymic: student.patronymic,
|
|
104
|
+
phone: student.phone,
|
|
105
|
+
telegram: student.telegram,
|
|
106
|
+
email: student.email,
|
|
107
|
+
git: student.git
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
@students[index] = updated_student
|
|
111
|
+
save_changes
|
|
112
|
+
@logger.info("Студент с ID #{id} успешно заменен")
|
|
113
|
+
true
|
|
114
|
+
else
|
|
115
|
+
@logger.warn("Студент с ID #{id} не найден")
|
|
116
|
+
false
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Удалить элемент списка по ID
|
|
121
|
+
def delete_student(id)
|
|
122
|
+
@logger.info("Удаление студента с ID: #{id}")
|
|
123
|
+
|
|
124
|
+
initial_size = @students.size
|
|
125
|
+
@students.reject! { |student| student.id == id }
|
|
126
|
+
|
|
127
|
+
if @students.size < initial_size
|
|
128
|
+
save_changes
|
|
129
|
+
@logger.info("Студент с ID #{id} успешно удален")
|
|
130
|
+
true
|
|
131
|
+
else
|
|
132
|
+
@logger.warn("Студент с ID #{id} не найден")
|
|
133
|
+
false
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Получить количество элементов
|
|
138
|
+
def get_student_short_count
|
|
139
|
+
count = @students.size
|
|
140
|
+
@logger.debug("Текущее количество студентов: #{count}")
|
|
141
|
+
count
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def save_changes
|
|
147
|
+
write_to_file(@filename) if @filename
|
|
148
|
+
end
|
|
149
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require_relative 'students_list_base'
|
|
3
|
+
require_relative 'logger'
|
|
4
|
+
|
|
5
|
+
class Students_list_YAML < Students_list_base
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@logger = Logger.new('students_yaml.log', :debug)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# a. Чтение всех значений из файла
|
|
12
|
+
def read_from_file(filename)
|
|
13
|
+
@logger.info("Чтение из YAML файла: #{filename}")
|
|
14
|
+
@filename = filename
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
if File.exist?(filename)
|
|
18
|
+
data_array = YAML.load_file(filename)
|
|
19
|
+
|
|
20
|
+
@students = data_array.map do |hash|
|
|
21
|
+
Student.from_hash(hash)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@logger.info("Успешно загружено #{@students.size} студентов")
|
|
25
|
+
else
|
|
26
|
+
@students = []
|
|
27
|
+
@logger.warn("Файл #{filename} не существует. Создан пустой список.")
|
|
28
|
+
end
|
|
29
|
+
rescue Psych::SyntaxError => e
|
|
30
|
+
@logger.error("Ошибка парсинга YAML: #{e.message}")
|
|
31
|
+
@students = []
|
|
32
|
+
rescue => e
|
|
33
|
+
@logger.error("Ошибка чтения файла: #{e.message}")
|
|
34
|
+
@students = []
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# b. Запись всех значений в файл
|
|
39
|
+
def write_to_file(filename)
|
|
40
|
+
@logger.info("Запись в YAML файл: #{filename}")
|
|
41
|
+
|
|
42
|
+
begin
|
|
43
|
+
data_array = @students.map(&:to_hash)
|
|
44
|
+
yaml_data = YAML.dump(data_array)
|
|
45
|
+
File.write(filename, yaml_data)
|
|
46
|
+
@logger.info("Успешно записано #{@students.size} студентов")
|
|
47
|
+
rescue => e
|
|
48
|
+
@logger.error("Ошибка записи в файл: #{e.message}")
|
|
49
|
+
raise
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def save_changes
|
|
56
|
+
return unless @filename
|
|
57
|
+
@logger.debug("Автосохранение изменений")
|
|
58
|
+
write_to_file(@filename)
|
|
59
|
+
end
|
|
60
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: students_list_yaml_gems
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Мари
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-10 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description:
|
|
14
|
+
email:
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- lib/data_list.rb
|
|
20
|
+
- lib/data_list_student_short.rb
|
|
21
|
+
- lib/data_table.rb
|
|
22
|
+
- lib/logger.rb
|
|
23
|
+
- lib/student.rb
|
|
24
|
+
- lib/student_short.rb
|
|
25
|
+
- lib/student_superclass.rb
|
|
26
|
+
- lib/students_list_base.rb
|
|
27
|
+
- lib/students_list_yaml.rb
|
|
28
|
+
homepage:
|
|
29
|
+
licenses:
|
|
30
|
+
- MIT
|
|
31
|
+
metadata: {}
|
|
32
|
+
post_install_message:
|
|
33
|
+
rdoc_options: []
|
|
34
|
+
require_paths:
|
|
35
|
+
- lib
|
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
requirements: []
|
|
47
|
+
rubygems_version: 3.4.20
|
|
48
|
+
signing_key:
|
|
49
|
+
specification_version: 4
|
|
50
|
+
summary: Управление списками студентов в YAML
|
|
51
|
+
test_files: []
|