student_list_yaml_gem 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 +49 -0
- data/lib/data_list_student_short.rb +13 -0
- data/lib/data_table.rb +22 -0
- data/lib/student.rb +135 -0
- data/lib/student_list_yaml.rb +116 -0
- data/lib/student_short.rb +25 -0
- data/lib/super_student.rb +41 -0
- data/lib/unique_student_error.rb +2 -0
- metadata +49 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 10576fb140bc58bc6b580ab3e74a37538d0bf6bf16b8f6eff774b1e2b5946767
|
|
4
|
+
data.tar.gz: '0779fdbb0450c06b19ec726740c233f39bca5962c5be946585edd2c6f4e13077'
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: dc656e8a694d8e60a06e701cc90410188855d6eb2d2072e4d87ad0cf1b80edfd5b81f068524e68ff3f4f6f65af399227656fa71cadf4ad267ce9342ef377eec5
|
|
7
|
+
data.tar.gz: ec2395929753ec1fbf131a339e291e4760181dcd45f61fa7d15b8b7941124d8b8cdd1a2383b9f8482693d3554b4085f289d26bd61ea4f0f2d9d4ced576f9a046
|
data/lib/data_list.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require_relative 'data_table.rb'
|
|
2
|
+
|
|
3
|
+
class DataList
|
|
4
|
+
def initialize(array)
|
|
5
|
+
self.data = array
|
|
6
|
+
@selected = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def data=(array)
|
|
10
|
+
@array = array.freeze
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def select(index)
|
|
14
|
+
raise ArgumentError if index < 0 || index >= @array.length
|
|
15
|
+
@selected << index unless @selected.include?(index)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get_selected
|
|
19
|
+
@selected.map { |i| @array[i].id }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def clear_selected
|
|
23
|
+
@selected.clear
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_names
|
|
27
|
+
["№ по порядку"] + get_custom_names
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def get_data
|
|
31
|
+
rows = []
|
|
32
|
+
@array.each_with_index do |obj, index|
|
|
33
|
+
rows << [index + 1] + get_custom_row(obj)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
DataTable.new(rows)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
protected
|
|
40
|
+
|
|
41
|
+
def get_custom_names
|
|
42
|
+
raise NotImplementedError
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_custom_row(obj)
|
|
46
|
+
raise NotImplementedError
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require_relative 'data_list.rb'
|
|
2
|
+
require_relative 'student_short.rb'
|
|
3
|
+
|
|
4
|
+
class DataListStudentShort < DataList
|
|
5
|
+
|
|
6
|
+
def get_custom_names
|
|
7
|
+
["ФИО", "Контакт", "Гит"]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get_custom_row(student)
|
|
11
|
+
[student.last_name_initials, student.contact, student.git]
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/data_table.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class DataTable
|
|
2
|
+
def initialize(rows)
|
|
3
|
+
@rows = rows.map { |x| x.freeze }
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def get(row, col)
|
|
7
|
+
@rows[row][col]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def rows
|
|
11
|
+
@rows.length
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def columns
|
|
15
|
+
return 0 if @rows.empty?
|
|
16
|
+
@rows[0].length
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_s
|
|
20
|
+
@rows.to_s
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/student.rb
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
require_relative 'super_student.rb'
|
|
2
|
+
|
|
3
|
+
class Student < SuperStudent
|
|
4
|
+
include Comparable
|
|
5
|
+
|
|
6
|
+
attr_reader :last_name, :first_name, :patronymic
|
|
7
|
+
|
|
8
|
+
def self.validated_attr_writer(attribute, validation_method)
|
|
9
|
+
define_method("#{attribute}=") do |value|
|
|
10
|
+
raise ArgumentError unless self.class.send(validation_method, value)
|
|
11
|
+
instance_variable_set("@#{attribute}", value)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
validated_attr_writer :first_name, :valid_name?
|
|
16
|
+
validated_attr_writer :last_name, :valid_name?
|
|
17
|
+
validated_attr_writer :patronymic, :valid_name?
|
|
18
|
+
validated_attr_writer :git, :valid_git?
|
|
19
|
+
|
|
20
|
+
def <=>(other)
|
|
21
|
+
[first_name, last_name, patronymic || nil] <=> [other.first_name, other.last_name, other.patronymic || nil]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(last_name:, first_name:, id: nil, patronymic: nil, phone: nil, telegram: nil, email: nil, git: nil)
|
|
25
|
+
|
|
26
|
+
raise ArgumentError, "Неверный формат гита" unless self.class.valid_git?(git)
|
|
27
|
+
super(id: id, git: git)
|
|
28
|
+
|
|
29
|
+
self.last_name = last_name
|
|
30
|
+
self.first_name = first_name
|
|
31
|
+
self.patronymic = patronymic
|
|
32
|
+
|
|
33
|
+
self.contact = {telegram: telegram, email: email, phone: phone}
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def ==(other)
|
|
38
|
+
self_data = self.to_hash
|
|
39
|
+
other_data = other.to_hash
|
|
40
|
+
|
|
41
|
+
[:telegram, :email, :phone, :git].each do |field|
|
|
42
|
+
self_value = self_data[field]
|
|
43
|
+
other_value = other_data[field]
|
|
44
|
+
|
|
45
|
+
return true if self_value && other_value && self_value == other_value
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_hash
|
|
52
|
+
{
|
|
53
|
+
id: @id,
|
|
54
|
+
first_name: @first_name,
|
|
55
|
+
last_name: @last_name,
|
|
56
|
+
patronymic: @patronymic,
|
|
57
|
+
telegram: @telegram,
|
|
58
|
+
email: @email,
|
|
59
|
+
phone: @phone,
|
|
60
|
+
git: @git
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.initialize_hash(id: nil, student_hash:)
|
|
65
|
+
new(
|
|
66
|
+
id: id,
|
|
67
|
+
last_name: student_hash[:last_name],
|
|
68
|
+
first_name: student_hash[:first_name],
|
|
69
|
+
patronymic: student_hash[:patronymic],
|
|
70
|
+
telegram: student_hash[:telegram],
|
|
71
|
+
email: student_hash[:email],
|
|
72
|
+
phone: student_hash[:phone],
|
|
73
|
+
git: student_hash[:git]
|
|
74
|
+
)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def contact
|
|
78
|
+
if @telegram && !@telegram.empty?
|
|
79
|
+
"telegram - #{@telegram}"
|
|
80
|
+
elsif @email && !@email.empty?
|
|
81
|
+
"email - #{@email}"
|
|
82
|
+
elsif @phone && !@phone.empty?
|
|
83
|
+
"phone - #{@phone}"
|
|
84
|
+
else
|
|
85
|
+
nil
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def contact=(contacts)
|
|
90
|
+
contacts.each do |type, value|
|
|
91
|
+
validator = "valid_#{type}?".to_sym
|
|
92
|
+
raise ArgumentError, "Неверный формат #{type}" unless self.class.send(validator, value)
|
|
93
|
+
instance_variable_set("@#{type}", value)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def last_name_initials
|
|
98
|
+
initials = "#{last_name} #{first_name[0]}."
|
|
99
|
+
initials += " #{patronymic[0]}." if patronymic
|
|
100
|
+
initials
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def to_s
|
|
104
|
+
info = []
|
|
105
|
+
info << "ID: #{@id}" if @id
|
|
106
|
+
info << "Фамилия: #{@last_name}"
|
|
107
|
+
info << "Имя: #{@first_name}"
|
|
108
|
+
info << "Отчество: #{@patronymic}" if @patronymic
|
|
109
|
+
info << "Телефон: #{@phone}" if @phone
|
|
110
|
+
info << "Телеграм: #{@telegram}" if @telegram
|
|
111
|
+
info << "Почта: #{@email}" if @email
|
|
112
|
+
info << "Гит: #{@git}" if @git
|
|
113
|
+
info.join("\n")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.valid_name?(name)
|
|
117
|
+
name.nil? || name.is_a?(String) && name.match?(/^([А-Я][а-я]+|[A-Z][a-z]+)$/)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def self.valid_phone?(phone)
|
|
121
|
+
phone.nil? || (phone.is_a?(String) && phone.match?(/^(\+7|8)?[\s\-\(]?(\d{3})[\s\-\)]?(\d{3})[\s\-]?(\d{2})[\s\-]?(\d{2})$/))
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def self.valid_telegram?(telegram)
|
|
125
|
+
telegram.nil? || (telegram.is_a?(String) && telegram.match?(/^@[a-zA-Z0-9_]{5,32}$/))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def self.valid_email?(email)
|
|
129
|
+
email.nil? || (email.is_a?(String) && email.match?(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/))
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.valid_git?(git)
|
|
133
|
+
git.nil? || (git.is_a?(String) && git.match?(/^https:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\/?$/))
|
|
134
|
+
end
|
|
135
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require_relative 'student.rb'
|
|
3
|
+
require_relative 'data_list_student_short.rb'
|
|
4
|
+
require_relative 'unique_student_error.rb'
|
|
5
|
+
|
|
6
|
+
# Класс для работы со списком студентов, хранящимся в YAML-файле
|
|
7
|
+
class StudentListYAML
|
|
8
|
+
|
|
9
|
+
# Инициализация списка студентов
|
|
10
|
+
# @param file_path [String]
|
|
11
|
+
def initialize(file_path:, log_path: nil)
|
|
12
|
+
@file_path = file_path
|
|
13
|
+
@logger = log_path ? AppLogger.build(log_path) : nil
|
|
14
|
+
@students = read
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Чтение студентов из файла
|
|
18
|
+
# @return [Array<Student>] массив студентов
|
|
19
|
+
def read
|
|
20
|
+
@logger.debug('read yaml')
|
|
21
|
+
|
|
22
|
+
return [] unless File.exist?(@file_path)
|
|
23
|
+
|
|
24
|
+
data = YAML.load_file(@file_path)
|
|
25
|
+
return [] unless data.is_a?(Array)
|
|
26
|
+
|
|
27
|
+
data.map do |student_hash|
|
|
28
|
+
Student.initialize_hash(id: student_hash[:id], student_hash: student_hash)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
rescue => e
|
|
32
|
+
@logger.error(e.message)
|
|
33
|
+
[]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Записывает данные студентов в YAML-файл
|
|
37
|
+
def write
|
|
38
|
+
students_hash = @students.map { |student| student.to_hash }
|
|
39
|
+
File.write(@file_path, students_hash.to_yaml)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Получить студента по ID
|
|
43
|
+
# @param id [Integer]
|
|
44
|
+
# @return [Student, nil]
|
|
45
|
+
def get_student_by_id(id)
|
|
46
|
+
@logger.debug("get_student_by_id #{id}")
|
|
47
|
+
@students.find { |student| student.id = id }
|
|
48
|
+
rescue => e
|
|
49
|
+
@logger.error(e.message)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Получить список студентов
|
|
53
|
+
# @param k [Integer] номер первого элемента
|
|
54
|
+
# @param n [Integer] количество элементов
|
|
55
|
+
# @return [DataList]
|
|
56
|
+
def get_k_n_student_short_list(k, n)
|
|
57
|
+
students = @students.slice(k - 1, n)
|
|
58
|
+
list = DataListStudentShort.new(students)
|
|
59
|
+
list.get_data
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Сортировка студентов по ФамилияИнициалы
|
|
63
|
+
def sort_by_name
|
|
64
|
+
@students.sort_by! { |student| student.last_name_initials }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Добавление студента в список
|
|
68
|
+
# @param student [Student]
|
|
69
|
+
def add_student(student)
|
|
70
|
+
@logger.info("add_student #{student.short_info}")
|
|
71
|
+
new_id = @students.map(&:id).max.to_i + 1
|
|
72
|
+
|
|
73
|
+
new_student = Student.initialize_hash(id: new_id, student_hash: student.to_hash)
|
|
74
|
+
unique(new_student)
|
|
75
|
+
|
|
76
|
+
@students << new_student
|
|
77
|
+
rescue => e
|
|
78
|
+
@logger.error(e.message)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Изменение студента по id
|
|
82
|
+
# @param id [Integer]
|
|
83
|
+
# @param new_student [Student]
|
|
84
|
+
def update_student(id:, new_student:)
|
|
85
|
+
@logger.info("update_student_id: #{id}")
|
|
86
|
+
|
|
87
|
+
index = @students.index { |student| student.id == id }
|
|
88
|
+
return unless index
|
|
89
|
+
unique(new_student)
|
|
90
|
+
@students[index] = new_student
|
|
91
|
+
|
|
92
|
+
rescue => e
|
|
93
|
+
@logger.error(e.message)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Удаление студента по id
|
|
97
|
+
# param id [Integer]
|
|
98
|
+
def delete_student(id)
|
|
99
|
+
@logger.info("delete_student_id: #{id}")
|
|
100
|
+
|
|
101
|
+
@students.reject! { |s| s.id == id }
|
|
102
|
+
|
|
103
|
+
rescue => e
|
|
104
|
+
@logger.error(e.message)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
# Проверка студентов на уникальность
|
|
110
|
+
def unique(new_student)
|
|
111
|
+
@students.each do |student|
|
|
112
|
+
raise UniqueStudentError, "Ошибка уникальности студента" if student == new_student
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative 'student.rb'
|
|
2
|
+
require_relative 'super_student.rb'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class StudentShort < SuperStudent
|
|
6
|
+
|
|
7
|
+
attr_reader :last_name_initials, :contact
|
|
8
|
+
|
|
9
|
+
def initialize(id:, last_name_initials:, contact: nil, git: nil)
|
|
10
|
+
super(id: id, git: git)
|
|
11
|
+
@last_name_initials = last_name_initials
|
|
12
|
+
@contact = contact
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.from_student(student)
|
|
16
|
+
raise ArgumentError, "Отсутствует ID" unless student.id
|
|
17
|
+
new(
|
|
18
|
+
id: student.id,
|
|
19
|
+
last_name_initials: student.last_name_initials,
|
|
20
|
+
contact: student.contact,
|
|
21
|
+
git: student.git
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class SuperStudent
|
|
2
|
+
|
|
3
|
+
attr_reader :id, :git
|
|
4
|
+
|
|
5
|
+
def initialize(id: nil, git: nil)
|
|
6
|
+
@id = id
|
|
7
|
+
@git = git
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def short_info
|
|
11
|
+
info = []
|
|
12
|
+
info << "ID: #{id}" if id
|
|
13
|
+
info << "ФИО: #{last_name_initials}"
|
|
14
|
+
info << "Контакт: #{contact}" if contact
|
|
15
|
+
info << "Гит: #{git}" if git
|
|
16
|
+
info.join("\n")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_s
|
|
20
|
+
short_info
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def has_git?
|
|
24
|
+
!@git.nil? && !@git.empty?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def has_contact?
|
|
28
|
+
!contact.nil? && !contact.empty?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
def last_name_initials
|
|
34
|
+
raise NotImplementedError
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def contact
|
|
38
|
+
raise NotImplementedError
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: student_list_yaml_gem
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- TelariL
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-04 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/student.rb
|
|
23
|
+
- lib/student_list_yaml.rb
|
|
24
|
+
- lib/student_short.rb
|
|
25
|
+
- lib/super_student.rb
|
|
26
|
+
- lib/unique_student_error.rb
|
|
27
|
+
homepage:
|
|
28
|
+
licenses: []
|
|
29
|
+
metadata: {}
|
|
30
|
+
post_install_message:
|
|
31
|
+
rdoc_options: []
|
|
32
|
+
require_paths:
|
|
33
|
+
- lib
|
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
requirements: []
|
|
45
|
+
rubygems_version: 3.4.20
|
|
46
|
+
signing_key:
|
|
47
|
+
specification_version: 4
|
|
48
|
+
summary: Students list stored in YAML
|
|
49
|
+
test_files: []
|