student_list 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 +58 -0
- data/lib/data_list_student_short.rb +20 -0
- data/lib/data_table.rb +96 -0
- data/lib/student.rb +137 -0
- data/lib/student_list.rb +93 -0
- data/lib/student_list_file.rb +66 -0
- data/lib/student_list_json.rb +83 -0
- data/lib/student_list_yaml.rb +83 -0
- data/lib/student_short.rb +30 -0
- data/lib/student_template.rb +34 -0
- data/lib/students_list.rb +14 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c73afb232da5b5b584617cc799aff8d41f4143ccd97cd61fca69bb2617c8d7cb
|
|
4
|
+
data.tar.gz: ff75edc9d6bb9ea223d1b45eccbae397d110792ace37961140a9daa1bba3ffd7
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 93ed939b37348e7ff691ad7e589e29aca82a303eed09031556b90e274e807e58aa30123ac062d4cb1bc024415e92f3b988691f9cacd74d259adc4555fd67b4f6
|
|
7
|
+
data.tar.gz: 03b7cc945f1e3c87b8940b5070c360dfd29a42187aff9554cdb0e165883e9cc2428a025f5b50b21c7196a6e0d7b58a624a940c1359bcebad7d031d9644d1fd7e
|
data/lib/data_list.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative "data_table"
|
|
2
|
+
|
|
3
|
+
class DataList
|
|
4
|
+
|
|
5
|
+
def object_list=(new_object_list)
|
|
6
|
+
@object_list = new_object_list
|
|
7
|
+
clear_selected
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_reader :object_list, :selected
|
|
11
|
+
|
|
12
|
+
def initialize(object_list: )
|
|
13
|
+
@object_list = object_list
|
|
14
|
+
@selected = []
|
|
15
|
+
@atribute_names = get_atribute_names unless object_list.empty?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def select(number)
|
|
19
|
+
if number >= 0 && number < @object_list.size
|
|
20
|
+
@selected << number unless @selected.include?(number)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_selected(numbers)
|
|
25
|
+
@selected.map { |index| @object_list[index].id }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def get_names()
|
|
29
|
+
["№"] + @atribute_names
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_data()
|
|
33
|
+
result_data = []
|
|
34
|
+
name_columns = get_atribute_names()
|
|
35
|
+
@object_list.each do |elem|
|
|
36
|
+
hash = Hash.new
|
|
37
|
+
atribute_data = get_atribute_data(elem)
|
|
38
|
+
(0..name_columns.size).each do |index|
|
|
39
|
+
hash[name_columns[index]] = atribute_data[index]
|
|
40
|
+
end
|
|
41
|
+
result_data.append(hash)
|
|
42
|
+
end
|
|
43
|
+
return DataTable.new(result_data)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def clear_selected()
|
|
47
|
+
@selected.clear
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
def get_atribute_data(elem)
|
|
52
|
+
raise NotImplementedError, "Метод должен быть реализован в наследнике"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def get_atribute_names()
|
|
56
|
+
raise NotImplementedError, "Метод должен быть реализован в наследнике"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require_relative "data_list"
|
|
2
|
+
require_relative "student_short"
|
|
3
|
+
|
|
4
|
+
class DataListStudentShort < DataList
|
|
5
|
+
def initialize(student_list)
|
|
6
|
+
super(object_list: student_list)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def get_atribute_names
|
|
12
|
+
["last_name_initials", "contact", "git"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get_atribute_data(elem)
|
|
16
|
+
[elem.last_name_initials, elem.contact, elem.git]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
data/lib/data_table.rb
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
class DataTable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
attr_reader :columns
|
|
5
|
+
|
|
6
|
+
def initialize(objects)
|
|
7
|
+
@table = []
|
|
8
|
+
index = 0
|
|
9
|
+
@columns = []
|
|
10
|
+
return if objects.empty?
|
|
11
|
+
objects.each do |obj|
|
|
12
|
+
if @columns.empty?
|
|
13
|
+
@columns = obj.keys
|
|
14
|
+
@columns.unshift("№")
|
|
15
|
+
end
|
|
16
|
+
if obj.is_a?(Hash)
|
|
17
|
+
record = []
|
|
18
|
+
obj.each do |k, v|
|
|
19
|
+
record.append(v)
|
|
20
|
+
end
|
|
21
|
+
record.unshift(index)
|
|
22
|
+
@table.append(record)
|
|
23
|
+
index += 1
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def [](row,col)
|
|
29
|
+
@table[row.to_i][1..][[col.to_i]]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def count_row
|
|
33
|
+
@table.size
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def count_column
|
|
37
|
+
return 0 if @table.empty?
|
|
38
|
+
@columns.size
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_s
|
|
42
|
+
return puts "Таблица пуста" if @table.empty?
|
|
43
|
+
column_widths = calculate_column_widths
|
|
44
|
+
print_border(column_widths)
|
|
45
|
+
print_row(@columns, column_widths)
|
|
46
|
+
print_separator(column_widths)
|
|
47
|
+
@table.each do |row|
|
|
48
|
+
print_row(row, column_widths)
|
|
49
|
+
end
|
|
50
|
+
print_border(column_widths)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def calculate_column_widths
|
|
56
|
+
widths = []
|
|
57
|
+
(0...count_column).each do |col|
|
|
58
|
+
max_width = @columns[col].to_s.length
|
|
59
|
+
|
|
60
|
+
@table.each do |row|
|
|
61
|
+
cell_length = row[col].to_s.length
|
|
62
|
+
max_width = cell_length if cell_length > max_width
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
widths << max_width
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
widths
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def print_border(widths)
|
|
72
|
+
border = "+"
|
|
73
|
+
widths.each do |width|
|
|
74
|
+
border += "#{'-' * (width + 2)}+"
|
|
75
|
+
end
|
|
76
|
+
puts border
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def print_separator(widths)
|
|
80
|
+
separator = "+"
|
|
81
|
+
widths.each do |width|
|
|
82
|
+
separator += "#{'=' * (width + 2)}+"
|
|
83
|
+
end
|
|
84
|
+
puts separator
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def print_row(row, widths)
|
|
88
|
+
line = "|"
|
|
89
|
+
row.each_with_index do |cell, index|
|
|
90
|
+
line += " #{cell.to_s.ljust(widths[index])} |"
|
|
91
|
+
end
|
|
92
|
+
puts line
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
end
|
data/lib/student.rb
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require_relative 'student_template'
|
|
2
|
+
|
|
3
|
+
class Student < TemplateStudent
|
|
4
|
+
include Comparable
|
|
5
|
+
|
|
6
|
+
attr_reader :patronymic, :last_name, :first_name
|
|
7
|
+
def initialize(id: nil,
|
|
8
|
+
first_name: ,
|
|
9
|
+
last_name: ,
|
|
10
|
+
patronymic: nil,
|
|
11
|
+
phone: nil,
|
|
12
|
+
telegram: nil,
|
|
13
|
+
email: nil,
|
|
14
|
+
git: nil)
|
|
15
|
+
self.patronymic = patronymic
|
|
16
|
+
self.last_name = last_name
|
|
17
|
+
self.first_name = first_name
|
|
18
|
+
self.git = git
|
|
19
|
+
self.contact = {telegram: telegram, phone: phone, email: email}
|
|
20
|
+
super(id: id, git: git, contact: contact)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def <=>(other)
|
|
24
|
+
return nil unless other.is_a?(Student)
|
|
25
|
+
|
|
26
|
+
self_name = "#{@first_name} #{@last_name} #{@patronymic}".downcase
|
|
27
|
+
other_name = "#{other.first_name} #{other.last_name} #{other.patronymic}".downcase
|
|
28
|
+
|
|
29
|
+
self_name <=> other_name
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def last_name_initials()
|
|
33
|
+
initials = "#{@first_name[0].upcase}."
|
|
34
|
+
initials += " #{@patronymic[0].upcase}." if @patronymic && !@patronymic.empty?
|
|
35
|
+
return "#{@last_name} #{initials}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def contact()
|
|
39
|
+
if not @telegram.nil?
|
|
40
|
+
return "telegram - #{@telegram}"
|
|
41
|
+
elsif not @email.nil?
|
|
42
|
+
return "email - #{@email}"
|
|
43
|
+
elsif not @phone.nil?
|
|
44
|
+
return "phone - #{@phone}"
|
|
45
|
+
else return nil
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def contact=(contact)
|
|
50
|
+
contact.each do |contact_type, contact_value|
|
|
51
|
+
case contact_type
|
|
52
|
+
when :telegram
|
|
53
|
+
validator_contact(telegram: contact_value)
|
|
54
|
+
@telegram = contact_value
|
|
55
|
+
when :phone
|
|
56
|
+
validator_contact(phone: contact_value)
|
|
57
|
+
@phone = contact_value
|
|
58
|
+
when :email
|
|
59
|
+
validator_contact(email: contact_value)
|
|
60
|
+
@email = contact_value
|
|
61
|
+
else
|
|
62
|
+
raise ArgumentError, "Указан верный тип контакта, допустимы контакты с типом tg, email, phone. Вы ввели тип #{contact_type}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def to_s
|
|
68
|
+
info = ["ID: #{@id}", "Фамилия: #{@last_name}", "Имя: #{@first_name}"]
|
|
69
|
+
info << "Отчество: #{@patronymic}" if @patronymic
|
|
70
|
+
info << "Телефон: #{@phone}" if @phone
|
|
71
|
+
info << "Телеграм: #{@telegram}" if @telegram
|
|
72
|
+
info << "Почта: #{@email}" if @email
|
|
73
|
+
info << "Гит: #{self.git}" if self.git
|
|
74
|
+
info.join("\n")
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def self.valid_email?(email)
|
|
80
|
+
return (email.nil? or email =~ /\A[\p{L}0-9+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/ui)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.valid_phone?(phone)
|
|
84
|
+
return (phone.nil? or phone =~ /^(\+7|8)?[\s-]?\(?(\d{3})\)?[\s-]?(\d{3})[\s-]?(\d{2})[\s-]?(\d{2})$/)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.valid_telegram?(telegram)
|
|
88
|
+
return telegram.nil? || telegram.empty? || telegram.match?(/^@[a-zA-Z0-9_]{5,32}$/)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.valid_git?(git)
|
|
92
|
+
return (git.nil? or git =~ /^https:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\/?$/)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.valid_name?(student_names)
|
|
96
|
+
return (not student_names.nil? and student_names =~ /^[A-ZА-Я][a-zа-я]*$/)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
def self.attr_writer_with_validation(*attributes)
|
|
102
|
+
attributes.each do |attr|
|
|
103
|
+
define_method("#{attr}=") do |val|
|
|
104
|
+
valid_method = "valid_#{attr}?"
|
|
105
|
+
if [:patronymic, :last_name, :first_name].include?(attr)
|
|
106
|
+
valid_method = "valid_name?"
|
|
107
|
+
if val.nil? and [:patronymic].include?(attr)
|
|
108
|
+
return
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
if self.class.respond_to?(valid_method) && self.class.send(valid_method, val)
|
|
112
|
+
instance_variable_set("@#{attr}", val)
|
|
113
|
+
else
|
|
114
|
+
raise ArgumentError, "Невалидное значение #{attr}"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def validator_contact(**kwargs)
|
|
121
|
+
kwargs.each do |arg, val|
|
|
122
|
+
next if val.nil?
|
|
123
|
+
case arg
|
|
124
|
+
when :phone
|
|
125
|
+
raise ArgumentError, "Ошибка валидации #{arg}" if not Student.valid_phone?(val)
|
|
126
|
+
when :email
|
|
127
|
+
raise ArgumentError, "Ошибка валидации #{arg}" if not Student.valid_email?(val)
|
|
128
|
+
when :telegram
|
|
129
|
+
raise ArgumentError, "Ошибка валидации #{arg}" if not Student.valid_telegram?(val)
|
|
130
|
+
else
|
|
131
|
+
raise ArgumentError, "Ошибка данный аргумент не предусмотрен как поле класса - #{arg}"
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
attr_writer_with_validation :first_name, :last_name, :patronymic, :git
|
|
136
|
+
end
|
|
137
|
+
|
data/lib/student_list.rb
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'data_list_student_short'
|
|
2
|
+
require 'student'
|
|
3
|
+
require 'student_short'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StudentList
|
|
7
|
+
def initialize()
|
|
8
|
+
@students_list = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def excecute_data
|
|
12
|
+
raise NoMethodError, "Обязателен к переопределению"
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def commit_data
|
|
17
|
+
raise NoMethodError, "Обязателен к переопределению"
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get_sudent_for_id(id)
|
|
22
|
+
@students_list.find{|student| student.id == id}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_k_n_student_short_list(k, n, exists_data_list=false)
|
|
26
|
+
start_index = (k - 1) * n
|
|
27
|
+
end_index = start_index + n - 1
|
|
28
|
+
students_slice = @students_list[start_index..end_index] || []
|
|
29
|
+
students_slice.map{|student| StudentShort.from_student(student)}
|
|
30
|
+
if exists_data_list
|
|
31
|
+
exists_data_list.object_list = students_slice
|
|
32
|
+
return exists_data_list
|
|
33
|
+
else
|
|
34
|
+
DataListStudentShort.new(students_slice)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def sort_by_initials
|
|
39
|
+
@students_list.sort_by! { |student| student.last_name_initials }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def add_student(last_name:, first_name:, patronymic: nil, phone: nil, telegram: nil, email: nil, git: nil)
|
|
43
|
+
new_id = generate_new_id
|
|
44
|
+
student = Student.new(
|
|
45
|
+
id: new_id,
|
|
46
|
+
first_name: first_name,
|
|
47
|
+
last_name: last_name,
|
|
48
|
+
patronymic: patronymic,
|
|
49
|
+
phone: phone,
|
|
50
|
+
telegram: telegram,
|
|
51
|
+
email: email,
|
|
52
|
+
git: git
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@students_list << student
|
|
56
|
+
commit_data # Сохраняем изменения
|
|
57
|
+
student
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def update_student(id, last_name:, first_name:, patronymic: nil, phone: nil, telegram: nil, email: nil, git: nil)
|
|
61
|
+
student = get_sudent_for_id(id)
|
|
62
|
+
return false unless student
|
|
63
|
+
student.last_name = last_name
|
|
64
|
+
student.first_name = first_name
|
|
65
|
+
student.patronymic = patronymic if patronymic
|
|
66
|
+
student.git = git if git
|
|
67
|
+
contact = {}
|
|
68
|
+
contact[:phone] = phone if phone
|
|
69
|
+
contact[:telegram] = telegram if telegram
|
|
70
|
+
contact[:email] = email if email
|
|
71
|
+
student.contact = contact unless contact.empty?
|
|
72
|
+
commit_data
|
|
73
|
+
true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def delete_student(id)
|
|
78
|
+
deleted = @students_list.reject! { |student| student.id == id }
|
|
79
|
+
commit_data if deleted
|
|
80
|
+
!deleted.nil?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def get_student_short_count
|
|
84
|
+
@students_list.count
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
def generate_new_id
|
|
89
|
+
max_id = @students_list.map { |s| s.id.to_i }.max || 0
|
|
90
|
+
(max_id + 1).to_s
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require_relative "student_list"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class StudentListFile < StudentList
|
|
5
|
+
def file_path=(val)
|
|
6
|
+
if File.exist?(val)
|
|
7
|
+
@file_path = val
|
|
8
|
+
return
|
|
9
|
+
end
|
|
10
|
+
raise ArgumentError, "Такого файла не существует"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :file_path, :students_list
|
|
14
|
+
|
|
15
|
+
def initialize(file_path: )
|
|
16
|
+
self.file_path = file_path
|
|
17
|
+
super()
|
|
18
|
+
file_read
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load_file()
|
|
22
|
+
raise NoMethodError, "Обязателен к переопределению"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_data_write(data)
|
|
26
|
+
raise NoMethodError, "Обязателен к переопределению"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def file_read()
|
|
30
|
+
data = load_file
|
|
31
|
+
data.each do |student_data|
|
|
32
|
+
begin
|
|
33
|
+
self.students_list << Student.new(**student_data)
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
puts "Ошибка создания студента #{student_data}: #{e.message}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def file_write()
|
|
41
|
+
data = self.students_list.map { |student| student_to_hash(student) }
|
|
42
|
+
File.write(@file_path, get_data_write(data))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def commit_data
|
|
46
|
+
file_write
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def read_data
|
|
50
|
+
file_read
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def student_to_hash(student)
|
|
54
|
+
{
|
|
55
|
+
id: student.id,
|
|
56
|
+
first_name: student.first_name,
|
|
57
|
+
last_name: student.last_name,
|
|
58
|
+
patronymic: student.patronymic,
|
|
59
|
+
phone: student.instance_variable_get(:@phone),
|
|
60
|
+
telegram: student.instance_variable_get(:@telegram),
|
|
61
|
+
email: student.instance_variable_get(:@email),
|
|
62
|
+
git: student.git
|
|
63
|
+
}.compact
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require_relative 'student_list_file'
|
|
3
|
+
|
|
4
|
+
class StudentListJSON < StudentListFile
|
|
5
|
+
def initialize(file_path: )
|
|
6
|
+
super(file_path: file_path)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def load_file()
|
|
10
|
+
JSON.parse(File.read(@file_path), symbolize_names: true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_data_write(data)
|
|
14
|
+
JSON.pretty_generate(data)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Основная программа
|
|
19
|
+
if __FILE__ == $0
|
|
20
|
+
filename = '/home/danil/design-patterns-template/src/lab_4/students.json'
|
|
21
|
+
|
|
22
|
+
# Создаем экземпляр класса
|
|
23
|
+
student_list = StudentListJSON.new(file_path: filename)
|
|
24
|
+
|
|
25
|
+
puts "Загружено студентов: #{student_list.get_student_short_count}"
|
|
26
|
+
|
|
27
|
+
# Выводим исходный порядок
|
|
28
|
+
puts "\nИсходный список студентов:"
|
|
29
|
+
student_list.students_list.each do |student|
|
|
30
|
+
puts "#{student.last_name_initials} (ID: #{student.id})"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Сортируем по инициалам
|
|
34
|
+
puts "\nПосле сортировки по инициалам:"
|
|
35
|
+
student_list.sort_by_initials
|
|
36
|
+
student_list.students_list.each do |student|
|
|
37
|
+
puts student.last_name_initials
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Получаем список (первые 2 элемента)
|
|
41
|
+
puts "\nПолучаем первые 2 студента:"
|
|
42
|
+
short_list = student_list.get_k_n_student_short_list(1, 2)
|
|
43
|
+
puts short_list.get_data()
|
|
44
|
+
# Добавляем нового студента
|
|
45
|
+
puts "\nДобавляем нового студента:"
|
|
46
|
+
new_student = student_list.add_student(
|
|
47
|
+
last_name: "Павлов",
|
|
48
|
+
first_name: "Артем",
|
|
49
|
+
patronymic: "Викторович",
|
|
50
|
+
phone: "+79165554433",
|
|
51
|
+
)
|
|
52
|
+
puts "Добавлен: #{new_student.last_name_initials}"
|
|
53
|
+
|
|
54
|
+
# Получаем студента по ID
|
|
55
|
+
puts "\nПоиск студента по ID 2:"
|
|
56
|
+
found_student = student_list.get_sudent_for_id("2")
|
|
57
|
+
if found_student
|
|
58
|
+
puts "Найден: #{found_student.last_name_initials}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Обновляем студента
|
|
62
|
+
puts "\nОбновляем студента с ID 3:"
|
|
63
|
+
if student_list.update_student("3",
|
|
64
|
+
last_name: "Волкова",
|
|
65
|
+
first_name: "Мария",
|
|
66
|
+
patronymic: "Александровна",
|
|
67
|
+
)
|
|
68
|
+
puts "Студент обновлен"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Выводим финальный список
|
|
72
|
+
puts "\nФинальный список студентов (#{student_list.get_student_short_count} чел.):"
|
|
73
|
+
student_list.students_list.each do |student|
|
|
74
|
+
puts "#{student.last_name_initials} (ID: #{student.id})"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Демонстрация пагинации
|
|
78
|
+
puts "\nДемонстрация пагинации (по 2 студента на странице):"
|
|
79
|
+
(1..3).each do |page|
|
|
80
|
+
short_list = student_list.get_k_n_student_short_list(page, 2, short_list)
|
|
81
|
+
puts "Страница #{page}: #{short_list.get_data}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require_relative 'student_list_file'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
class StudentListYAML < StudentListFile
|
|
5
|
+
def initialize(file_path: )
|
|
6
|
+
super(file_path: file_path)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def load_file()
|
|
10
|
+
YAML.load_file(@file_path, symbolize_names: true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_data_write(data)
|
|
14
|
+
data.to_yaml
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Основная программа
|
|
19
|
+
if __FILE__ == $0
|
|
20
|
+
filename = '/home/danil/design-patterns-template/src/lab_4/students.yaml'
|
|
21
|
+
|
|
22
|
+
# Создаем экземпляр класса
|
|
23
|
+
student_list = StudentListYAML.new(file_path: filename)
|
|
24
|
+
|
|
25
|
+
puts "Загружено студентов: #{student_list.get_student_short_count}"
|
|
26
|
+
|
|
27
|
+
# Выводим исходный порядок
|
|
28
|
+
puts "\nИсходный список студентов:"
|
|
29
|
+
student_list.students_list.each do |student|
|
|
30
|
+
puts "#{student.last_name_initials} (ID: #{student.id})"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Сортируем по инициалам
|
|
34
|
+
puts "\nПосле сортировки по инициалам:"
|
|
35
|
+
student_list.sort_by_initials
|
|
36
|
+
student_list.students_list.each do |student|
|
|
37
|
+
puts student.last_name_initials
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Получаем список (первые 2 элемента)
|
|
41
|
+
puts "\nПолучаем первые 2 студента:"
|
|
42
|
+
short_list = student_list.get_k_n_student_short_list(1, 2)
|
|
43
|
+
puts short_list.get_data()
|
|
44
|
+
# Добавляем нового студента
|
|
45
|
+
puts "\nДобавляем нового студента:"
|
|
46
|
+
new_student = student_list.add_student(
|
|
47
|
+
last_name: "Павлов",
|
|
48
|
+
first_name: "Артем",
|
|
49
|
+
patronymic: "Викторович",
|
|
50
|
+
phone: "+79165554433",
|
|
51
|
+
)
|
|
52
|
+
puts "Добавлен: #{new_student.last_name_initials}"
|
|
53
|
+
|
|
54
|
+
# Получаем студента по ID
|
|
55
|
+
puts "\nПоиск студента по ID 2:"
|
|
56
|
+
found_student = student_list.get_sudent_for_id("2")
|
|
57
|
+
if found_student
|
|
58
|
+
puts "Найден: #{found_student.last_name_initials}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Обновляем студента
|
|
62
|
+
puts "\nОбновляем студента с ID 3:"
|
|
63
|
+
if student_list.update_student("3",
|
|
64
|
+
last_name: "Волкова",
|
|
65
|
+
first_name: "Мария",
|
|
66
|
+
patronymic: "Александровна",
|
|
67
|
+
)
|
|
68
|
+
puts "Студент обновлен"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Выводим финальный список
|
|
72
|
+
puts "\nФинальный список студентов (#{student_list.get_student_short_count} чел.):"
|
|
73
|
+
student_list.students_list.each do |student|
|
|
74
|
+
puts "#{student.last_name_initials} (ID: #{student.id})"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Демонстрация пагинации
|
|
78
|
+
puts "\nДемонстрация пагинации (по 2 студента на странице):"
|
|
79
|
+
(1..3).each do |page|
|
|
80
|
+
short_list = student_list.get_k_n_student_short_list(page, 2, short_list)
|
|
81
|
+
puts "Страница #{page}: #{short_list.get_data}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative 'student'
|
|
2
|
+
require_relative 'student_template'
|
|
3
|
+
|
|
4
|
+
class StudentShort < TemplateStudent
|
|
5
|
+
def initialize(id:, last_name_initials:, contact: nil, git: nil)
|
|
6
|
+
@last_name_initials = last_name_initials
|
|
7
|
+
@contact = contact
|
|
8
|
+
super(id: id, contact: contact, git: git)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def contact()
|
|
12
|
+
@contact
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def last_name_initials()
|
|
16
|
+
@last_name_initials
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.from_student(student)
|
|
20
|
+
new(
|
|
21
|
+
id: student.id,
|
|
22
|
+
last_name_initials: student.last_name_initials(),
|
|
23
|
+
contact: student.contact,
|
|
24
|
+
git: student.git)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
self.short_info
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class TemplateStudent
|
|
2
|
+
|
|
3
|
+
def contact()
|
|
4
|
+
raise NoMethodError, "Обязателен к переопределению"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def last_name_initials()
|
|
8
|
+
raise NoMethodError, "Обязателен к переопределению"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :id, :git
|
|
12
|
+
|
|
13
|
+
def initialize(id: , contact: nil, git: nil)
|
|
14
|
+
@id = id
|
|
15
|
+
@contact = contact
|
|
16
|
+
@git = git
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def short_info()
|
|
20
|
+
info = ["ID: #{@id}", "ФИО: #{last_name_initials()}"]
|
|
21
|
+
info << (@contact || "нет контакта")
|
|
22
|
+
info << "Гит: #{@git || 'нет'}"
|
|
23
|
+
info.join(", ")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def has_git?
|
|
27
|
+
!git.nil? && !git.empty?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def has_contact?
|
|
31
|
+
!contact.nil? && !contact.empty?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Главный файл gem - загружает все зависимости
|
|
2
|
+
require_relative 'data_list'
|
|
3
|
+
require_relative 'data_table'
|
|
4
|
+
require_relative 'data_list_student_short'
|
|
5
|
+
require_relative 'student'
|
|
6
|
+
require_relative 'student_short'
|
|
7
|
+
require_relative 'students_list'
|
|
8
|
+
require_relative 'student_template'
|
|
9
|
+
require_relative 'student_list'
|
|
10
|
+
require_relative 'student_list_file'
|
|
11
|
+
require_relative 'student_list_json'
|
|
12
|
+
require_relative 'student_list_yaml'
|
|
13
|
+
|
|
14
|
+
puts "✅ StudentList gem loaded successfully!"
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: student_list
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- KotDev
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-10-31 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: psych
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.0'
|
|
27
|
+
description: Manage student lists with YAML and JSON storage
|
|
28
|
+
email:
|
|
29
|
+
- kotikov.lil@bk.ru
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- lib/data_list.rb
|
|
35
|
+
- lib/data_list_student_short.rb
|
|
36
|
+
- lib/data_table.rb
|
|
37
|
+
- lib/student.rb
|
|
38
|
+
- lib/student_list.rb
|
|
39
|
+
- lib/student_list_file.rb
|
|
40
|
+
- lib/student_list_json.rb
|
|
41
|
+
- lib/student_list_yaml.rb
|
|
42
|
+
- lib/student_short.rb
|
|
43
|
+
- lib/student_template.rb
|
|
44
|
+
- lib/students_list.rb
|
|
45
|
+
homepage:
|
|
46
|
+
licenses:
|
|
47
|
+
- MIT
|
|
48
|
+
metadata: {}
|
|
49
|
+
post_install_message:
|
|
50
|
+
rdoc_options: []
|
|
51
|
+
require_paths:
|
|
52
|
+
- lib
|
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0'
|
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
requirements: []
|
|
64
|
+
rubygems_version: 3.5.11
|
|
65
|
+
signing_key:
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Student list management
|
|
68
|
+
test_files: []
|