students_list_yaml_silerhofe 0.2.5
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/README.md +55 -0
- data/lib/students_list_yaml/Data_list.rb +56 -0
- data/lib/students_list_yaml/Data_table.rb +36 -0
- data/lib/students_list_yaml/contact.rb +58 -0
- data/lib/students_list_yaml/data_list_student_short.rb +17 -0
- data/lib/students_list_yaml/student.rb +110 -0
- data/lib/students_list_yaml/student_base.rb +122 -0
- data/lib/students_list_yaml/student_short.rb +25 -0
- data/lib/students_list_yaml/super_student.rb +48 -0
- data/lib/students_list_yaml/validated_setter.rb +20 -0
- data/lib/students_list_yaml/version.rb +3 -0
- data/lib/students_list_yaml.rb +16 -0
- metadata +69 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fbbd30ecddec6dddd28cc35d5005c180a19a09a6b10c328231a2ddfae8e71bd2
|
|
4
|
+
data.tar.gz: 6b60b60f2d94c3093146bb20deb6e8a46af7937e47030595d0296f8e08395244
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 63fa7c3053e504d20c3a3eaae366b472fdeb19ca02fbfce6fe392987b7eb97d87f9210cafe38f4196e8fd904b4cb84654b00b62dfaf9fb243b52c8f46fb17b53
|
|
7
|
+
data.tar.gz: '09e799ae055223e1f7d6a66442a36c927ff9b65a6b4dc009ade13adae873e48002a7fc4ec42c927058c3f09217a668ea5eb55feeb70027fa94c2dd5ca061a454'
|
data/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# StudentsListYAML Gem
|
|
2
|
+
|
|
3
|
+
Простой gem для работы со списками студентов в формате YAML.
|
|
4
|
+
|
|
5
|
+
## Установка
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Собрать gem
|
|
9
|
+
gem build students_list_yaml.gemspec
|
|
10
|
+
|
|
11
|
+
# Установить
|
|
12
|
+
gem install students_list_yaml-0.1.2.gem
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Использование
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
require 'students_list_yaml'
|
|
19
|
+
|
|
20
|
+
# Создаем экземпляр
|
|
21
|
+
list = StudentsListYAML::StudentsListYAML.new('test_students.yaml')
|
|
22
|
+
|
|
23
|
+
# Записываем в файл
|
|
24
|
+
list.write_to_file(students_data)
|
|
25
|
+
puts "Данные записаны в test_students.yaml"
|
|
26
|
+
|
|
27
|
+
# Читаем из файла
|
|
28
|
+
loaded_data = list.read_from_file()
|
|
29
|
+
puts "Прочитано #{list.count} студентов:"
|
|
30
|
+
loaded_data.each { |s| puts " - #{s[:name]} (#{s[:group]})" }
|
|
31
|
+
|
|
32
|
+
# Добавляем нового студента
|
|
33
|
+
list.add_student({ id: 3, name: "Сидорова А.В.", group: "ИВТ-303" })
|
|
34
|
+
list.write_to_file()
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
### StudentsListYAML::StudentsListYAML
|
|
41
|
+
|
|
42
|
+
Класс для управления списком студентов в YAML формате.
|
|
43
|
+
|
|
44
|
+
#### Методы
|
|
45
|
+
|
|
46
|
+
- `read_from_file(file_path)` - чтение из YAML файла
|
|
47
|
+
- `write_to_file(file_path, data = @students)` - запись в YAML файл
|
|
48
|
+
- `count` - получение количества студентов
|
|
49
|
+
- `add_student(student_data)` - добавление студента
|
|
50
|
+
- `find_by_id(id)` - поиск студента по ID
|
|
51
|
+
- `filter_by_group(group)` - фильтрация студентов по группе
|
|
52
|
+
|
|
53
|
+
## Лицензия
|
|
54
|
+
|
|
55
|
+
MIT
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require_relative 'Data_table'
|
|
2
|
+
|
|
3
|
+
class Data_list
|
|
4
|
+
|
|
5
|
+
def initialize(list)
|
|
6
|
+
@list = list
|
|
7
|
+
@selected =[]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def select(number)
|
|
11
|
+
check_bounds(number)
|
|
12
|
+
@selected << number if !@selected.include?(number)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def get_selected
|
|
16
|
+
@selected.map{ |number| @list[number].id}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def get_names
|
|
20
|
+
headers =["№ по порядку"]
|
|
21
|
+
headers.concat(get_fields || [])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_data
|
|
25
|
+
list_clone = @list.dup
|
|
26
|
+
table = []
|
|
27
|
+
list_clone.each_with_index.map do |entity, index|
|
|
28
|
+
row = [index+1] + get_values(entity)
|
|
29
|
+
table << row
|
|
30
|
+
end
|
|
31
|
+
Data_table.new(table)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def clear_selected
|
|
35
|
+
@selected.clear
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def list=(value)
|
|
41
|
+
@list = value
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def get_values(entity)
|
|
45
|
+
raise NotImplementedError, "Метод должен быть реализован в подклассе"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def get_fields
|
|
49
|
+
raise NotImplementedError, "Метод должен быть реализован в подклассе"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def check_bounds(number)
|
|
53
|
+
raise IndexError, "Выход за границы строки" if number<0 || number>=@list.size
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
class Data_table
|
|
2
|
+
def initialize(matrix)
|
|
3
|
+
self.matrix = matrix
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def countRow
|
|
7
|
+
@matrix.size
|
|
8
|
+
end
|
|
9
|
+
def countColumn
|
|
10
|
+
@matrix.empty? ? 0 : @matrix[0].size
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def [](row, column = nil)
|
|
14
|
+
return @matrix[row] if column.nil?
|
|
15
|
+
@matrix[row,column]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def checkIndex(row,column)
|
|
19
|
+
raise IndexError, "Выход за границы строки" if row<0 || row>=countRow
|
|
20
|
+
raise IndexError, "Выход за границы столбца" if column<0 || column>=countColumn
|
|
21
|
+
end
|
|
22
|
+
private
|
|
23
|
+
def matrix=(value)
|
|
24
|
+
unless value.is_a?(Array) && value.all? { |row| row.is_a?(Array)}
|
|
25
|
+
raise ArgumentError, "Значение должно быть двумерным массивом"
|
|
26
|
+
end
|
|
27
|
+
unless value.empty?
|
|
28
|
+
length = value[0].length
|
|
29
|
+
unless value.all? { |row| row.length == length}
|
|
30
|
+
raise ArgumentError, "Строки должны быть одного размера"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
@matrix = Marshal.load(Marshal.dump(value))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative 'validated_setter'
|
|
2
|
+
|
|
3
|
+
class ContactInfo
|
|
4
|
+
extend ValidatedSetter
|
|
5
|
+
|
|
6
|
+
validated_attr_writer :phone, validatedMethod: :valid_phone?, must_nil: true
|
|
7
|
+
validated_attr_writer :email, validatedMethod: :valid_email?, must_nil: true
|
|
8
|
+
validated_attr_writer :telegram, validatedMethod: :valid_telegram?, must_nil: true
|
|
9
|
+
|
|
10
|
+
private :phone=, :telegram=, :email=
|
|
11
|
+
|
|
12
|
+
def initialize(phone: nil, telegram: nil, email: nil)
|
|
13
|
+
self.phone = phone
|
|
14
|
+
self.telegram = telegram
|
|
15
|
+
self.email = email
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def contact=(hash)
|
|
19
|
+
self.phone = hash[:phone]
|
|
20
|
+
self.telegram = hash[:telegram]
|
|
21
|
+
self.email = hash[:email]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def contact
|
|
25
|
+
return "telegram - #{@telegram}" if @telegram
|
|
26
|
+
return "email - #{@email}" if @email
|
|
27
|
+
return "phone - #{@phone}" if @phone
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def has_contact?
|
|
31
|
+
!contact.nil?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def ==(other)
|
|
35
|
+
fields = [:@phone, :@telegram, :@email]
|
|
36
|
+
fields.any? do |field|
|
|
37
|
+
value1 = instance_variable_get(field)
|
|
38
|
+
value2 = other.instance_variable_get(field)
|
|
39
|
+
value1 && value2 && value1 == value2
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_s
|
|
44
|
+
"phone: #{@phone || "нет"} telegram: #{@telegram || "нет"} email: #{@email || "нет"}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.valid_phone?(phone)
|
|
48
|
+
phone.nil? || phone.match?(/^(\+7|8)?[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}$/)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.valid_telegram?(telegram)
|
|
52
|
+
telegram.nil? || telegram.match?(/^@[A-Za-z0-9_]{5,32}$/)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.valid_email?(email)
|
|
56
|
+
email.nil? || email.match?(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative 'Data_table'
|
|
2
|
+
require_relative 'Data_list'
|
|
3
|
+
require_relative 'student_short'
|
|
4
|
+
|
|
5
|
+
class Data_list_student_short < Data_list
|
|
6
|
+
def get_fields
|
|
7
|
+
["Фамилия И. О.", "Контакт", "Git"]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get_values(student_short)
|
|
11
|
+
[
|
|
12
|
+
student_short.last_name_initials || "Null",
|
|
13
|
+
student_short.contact || "Null",
|
|
14
|
+
student_short.git || "Null"
|
|
15
|
+
]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require_relative 'super_student'
|
|
2
|
+
require_relative 'validated_setter'
|
|
3
|
+
require_relative 'contact'
|
|
4
|
+
|
|
5
|
+
class Student < SuperStudent
|
|
6
|
+
extend ValidatedSetter
|
|
7
|
+
include Comparable
|
|
8
|
+
attr_reader :last_name, :first_name, :patronymic
|
|
9
|
+
validated_attr_writer :first_name, validatedMethod: :valid_name?
|
|
10
|
+
validated_attr_writer :last_name, validatedMethod: :valid_name?
|
|
11
|
+
validated_attr_writer :patronymic, validatedMethod: :valid_name?, must_nil: true
|
|
12
|
+
validated_attr_writer :git, validatedMethod: :valid_git?, must_nil: true
|
|
13
|
+
|
|
14
|
+
# Основной конструктор
|
|
15
|
+
def initialize(first_name:, last_name:, id: nil, patronymic: nil, git: nil, phone: nil, email: nil,telegram: nil)
|
|
16
|
+
if last_name.nil? or first_name.nil? then
|
|
17
|
+
raise ArgumentError, "Имя и Фамилия обезательны"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
super(id: id, git: git)
|
|
21
|
+
self.last_name = last_name
|
|
22
|
+
self.first_name = first_name
|
|
23
|
+
self.patronymic = patronymic
|
|
24
|
+
@contact_info = ContactInfo.new(phone: phone, telegram: telegram, email: email)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Альтернативный конструктор, принимающий хеш
|
|
28
|
+
def self.from_hash(hash)
|
|
29
|
+
new(
|
|
30
|
+
id: hash[:id],
|
|
31
|
+
first_name: hash[:first_name],
|
|
32
|
+
last_name: hash[:last_name],
|
|
33
|
+
patronymic: hash[:patronymic],
|
|
34
|
+
git: hash[:git],
|
|
35
|
+
phone: hash[:phone],
|
|
36
|
+
email: hash[:email],
|
|
37
|
+
telegram: hash[:telegram]
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def <=>(other)
|
|
42
|
+
[last_name, first_name, patronymic] <=> [other.last_name, other.first_name, other.patronymic]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def ==(other)
|
|
46
|
+
(@git && other.git && @git == other.git) || @contact_info == other.instance_variable_get(:@contact_info)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def contact=(hash)
|
|
50
|
+
@contact_info.contact = hash
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.valid_name?(name)
|
|
54
|
+
!name.nil? && name.match?(/^[A-ZА-Я]+[a-zа-яё]+$/)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.valid_phone?(phone)
|
|
58
|
+
ContactInfo.valid_phone?(phone)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.valid_telegram?(telegram)
|
|
62
|
+
ContactInfo.valid_telegram?(telegram)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.valid_email?(email)
|
|
66
|
+
ContactInfo.valid_email?(email)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.valid_git?(git)
|
|
70
|
+
git.match?(%r{^https://(github|gitlab)\.com/[A-Za-z0-9_\-]+$})
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def contact
|
|
74
|
+
@contact_info.contact
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def last_name_initials()
|
|
78
|
+
if patronymic then
|
|
79
|
+
result = "#{@last_name} " + "#{@first_name[0]}. " + "#{@patronymic[0]}."
|
|
80
|
+
else
|
|
81
|
+
result = "#{@last_name} " + "#{@first_name[0]}."
|
|
82
|
+
end
|
|
83
|
+
result
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def to_s
|
|
87
|
+
result = "
|
|
88
|
+
id: #{format_field(@id)},
|
|
89
|
+
Имя: #{@first_name},
|
|
90
|
+
Фамилия: #{@last_name},
|
|
91
|
+
Отчество: #{format_field(@patronymic)},
|
|
92
|
+
#{@contact_info.to_s},
|
|
93
|
+
Git: #{format_field(@git)}
|
|
94
|
+
"
|
|
95
|
+
result
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def to_hash()
|
|
99
|
+
{
|
|
100
|
+
id: self.id,
|
|
101
|
+
last_name: self.last_name,
|
|
102
|
+
first_name: self.first_name,
|
|
103
|
+
patronymic: self.patronymic,
|
|
104
|
+
git: self.git,
|
|
105
|
+
phone: @contact_info.instance_variable_get(:@phone),
|
|
106
|
+
email: @contact_info.instance_variable_get(:@email),
|
|
107
|
+
telegram: @contact_info.instance_variable_get(:@telegram)
|
|
108
|
+
}
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require_relative 'student'
|
|
2
|
+
require_relative 'student_short'
|
|
3
|
+
require_relative 'data_list_student_short'
|
|
4
|
+
|
|
5
|
+
class StudentsListBase
|
|
6
|
+
def initialize(file_path)
|
|
7
|
+
self.file_path = file_path
|
|
8
|
+
read_from_file
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def read_from_file
|
|
12
|
+
content = File.read(@file_path)
|
|
13
|
+
return [] if content.strip.empty?
|
|
14
|
+
@array_list = load(content).map { |element| Student.new(**element) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def write_to_file()
|
|
18
|
+
new_data = @array_list.map { |element| element.to_hash}
|
|
19
|
+
write_in(new_data)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_student_by_id(id)
|
|
24
|
+
@array_list.find { |e| e.id == id }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get_k_n_student_short_list(k, n, data_list = nil)
|
|
28
|
+
start_index = (k - 1) * n
|
|
29
|
+
end_index = start_index + n - 1
|
|
30
|
+
range = @array_list[start_index..end_index] || []
|
|
31
|
+
|
|
32
|
+
student_shorts = range.map { |student| StudentShort.from_student(student)}
|
|
33
|
+
|
|
34
|
+
if data_list
|
|
35
|
+
data_list.list = student_shorts
|
|
36
|
+
data_list
|
|
37
|
+
else
|
|
38
|
+
Data_list_student_short.new(student_shorts)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def sort_by_fio
|
|
43
|
+
@array_list.sort_by! { |student| student.last_name_initials}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def add_student(student)
|
|
48
|
+
if duplicate_exist?(student)
|
|
49
|
+
raise ArgumentError, "Студент с такими контактными данными (git, phone, telegram, email) уже существует"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
new_id = @array_list.empty? ? 1 : @array_list.map { |student| student.id}.max + 1
|
|
53
|
+
student.instance_variable_set(:@id, new_id)
|
|
54
|
+
@array_list << student
|
|
55
|
+
new_id
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def replace_student_by_id(id, new_student)
|
|
60
|
+
index = @array_list.index { |student| student.id == id}
|
|
61
|
+
|
|
62
|
+
if duplicate_exist?(new_student, exclude_id: id)
|
|
63
|
+
raise ArgumentError, "Студент с такими контактными данными (git, phone, telegram, email) уже существует"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
@array_list[index] = new_student.instance_variable_set(:@id, id)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def delete_student_by_id(id)
|
|
71
|
+
@array_list.reject! { |student| student.id == id}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def get_student_short_count
|
|
75
|
+
@array_list.length
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
protected
|
|
79
|
+
|
|
80
|
+
def parse_student_data(data)
|
|
81
|
+
Student.new(
|
|
82
|
+
id: data['id'] || data[:id],
|
|
83
|
+
last_name: data['last_name'] || data[:last_name],
|
|
84
|
+
first_name: data['first_name'] || data[:first_name],
|
|
85
|
+
patronymic: data['patronymic'] || data[:patronymic],
|
|
86
|
+
git: data['git'] || data[:git],
|
|
87
|
+
phone: data['phone'] || data[:phone],
|
|
88
|
+
email: data['email'] || data[:email],
|
|
89
|
+
telegram: data['telegram'] || data[:telegram]
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def duplicate_exist?(student, exclude_id: nil)
|
|
96
|
+
@array_list.any? do |other|
|
|
97
|
+
next if exclude_id && other.id == exclude_id
|
|
98
|
+
student == other
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def load(content)
|
|
103
|
+
raise ArgumentError, "Метод должен быть определен в потомках"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def write_in(extended_data)
|
|
107
|
+
raise ArgumentError, "Метод должен быть определен в потомках"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def file_path=(path)
|
|
111
|
+
normalized_path = File.expand_path(path.to_s)
|
|
112
|
+
|
|
113
|
+
unless File.exist?(normalized_path) || File.file?(normalized_path)
|
|
114
|
+
raise ArgumentError, "Файл: #{normalized_path} не существует лиюбо неправильно указан путь"
|
|
115
|
+
end
|
|
116
|
+
@file_path = path
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def clear
|
|
120
|
+
File.write(@file_path, '')
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_relative 'super_student'
|
|
2
|
+
class StudentShort < SuperStudent
|
|
3
|
+
attr_reader :last_name_initials, :contact, :git
|
|
4
|
+
|
|
5
|
+
def initialize(id:, git: nil, last_name_initials:, contact: nil)
|
|
6
|
+
if id.nil? then
|
|
7
|
+
raise ArgumentError, "ID обязательный"
|
|
8
|
+
end
|
|
9
|
+
if last_name_initials.nil? then
|
|
10
|
+
raise ArgumentError, "Фамилия и инициалы обязательны"
|
|
11
|
+
end
|
|
12
|
+
super(id:id, git:git)
|
|
13
|
+
@last_name_initials = last_name_initials
|
|
14
|
+
@contact = contact
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.from_student(student)
|
|
18
|
+
new(
|
|
19
|
+
id: student.id,
|
|
20
|
+
last_name_initials: student.last_name_initials,
|
|
21
|
+
contact: student.contact,
|
|
22
|
+
git: student.git
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class SuperStudent
|
|
2
|
+
|
|
3
|
+
attr_reader :id, :git
|
|
4
|
+
def initialize(id: nil, git: nil)
|
|
5
|
+
@id = id
|
|
6
|
+
@git = git
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def has_git?
|
|
10
|
+
not_empty?(@git)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def has_contact?
|
|
14
|
+
!contact.nil?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def last_name_initials
|
|
18
|
+
raise NotImplementedError, "Метод должен быть реализован в подклассе"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def contact
|
|
22
|
+
raise NotImplementedError, "Метод должен быть реализован в подклассе"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def short_info
|
|
26
|
+
result ="
|
|
27
|
+
ID: #{id}
|
|
28
|
+
Фамилия Инициалы: #{last_name_initials}
|
|
29
|
+
Гит: #{format_field(@git)}
|
|
30
|
+
Контакт: #{format_field(contact)}
|
|
31
|
+
"
|
|
32
|
+
result
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
short_info
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
def not_empty?(value)
|
|
41
|
+
!value.nil? && !value.to_s.empty?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def format_field(value)
|
|
45
|
+
value || 'Отсутствует'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module ValidatedSetter
|
|
2
|
+
private
|
|
3
|
+
def validated_attr_writer(attribute, validatedMethod: nil, must_nil:false)
|
|
4
|
+
define_method("#{attribute}=") do |value|
|
|
5
|
+
if value.nil?
|
|
6
|
+
if must_nil
|
|
7
|
+
instance_variable_set("@#{attribute}", value)
|
|
8
|
+
return
|
|
9
|
+
end
|
|
10
|
+
raise ArgumentError, "Поле #{attribute} обязательно"
|
|
11
|
+
end
|
|
12
|
+
unless validatedMethod.nil?
|
|
13
|
+
unless self.class.send(validatedMethod,value)
|
|
14
|
+
raise ArgumentError, "Некорректное значение #{attribute}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
instance_variable_set("@#{attribute}",value)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative 'students_list_yaml/version'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require_relative 'students_list_yaml/student_base'
|
|
4
|
+
|
|
5
|
+
module StudentsListYAML
|
|
6
|
+
class StudentsList < StudentsListBase
|
|
7
|
+
|
|
8
|
+
def load(content)
|
|
9
|
+
YAML.safe_load(content, permitted_classes: [Symbol], symbolize_names: true) || []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def write_in(extended_data)
|
|
13
|
+
File.write(@file_path, YAML.dump(extended_data))
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: students_list_yaml_silerhofe
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.5
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- SilerHofe
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '13.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '13.0'
|
|
27
|
+
description: Реализация паттерна Repository для работы с данными студентов
|
|
28
|
+
email:
|
|
29
|
+
- Siler.Hofe@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- README.md
|
|
35
|
+
- lib/students_list_yaml.rb
|
|
36
|
+
- lib/students_list_yaml/Data_list.rb
|
|
37
|
+
- lib/students_list_yaml/Data_table.rb
|
|
38
|
+
- lib/students_list_yaml/contact.rb
|
|
39
|
+
- lib/students_list_yaml/data_list_student_short.rb
|
|
40
|
+
- lib/students_list_yaml/student.rb
|
|
41
|
+
- lib/students_list_yaml/student_base.rb
|
|
42
|
+
- lib/students_list_yaml/student_short.rb
|
|
43
|
+
- lib/students_list_yaml/super_student.rb
|
|
44
|
+
- lib/students_list_yaml/validated_setter.rb
|
|
45
|
+
- lib/students_list_yaml/version.rb
|
|
46
|
+
homepage: https://zhuk.k-lab.su/SilerHofe/design-patterns-template/students_list_yaml
|
|
47
|
+
licenses:
|
|
48
|
+
- MIT
|
|
49
|
+
metadata: {}
|
|
50
|
+
post_install_message:
|
|
51
|
+
rdoc_options: []
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: 2.7.0
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
requirements: []
|
|
65
|
+
rubygems_version: 3.4.20
|
|
66
|
+
signing_key:
|
|
67
|
+
specification_version: 4
|
|
68
|
+
summary: Класс для работы со списками студентов в формате YAML
|
|
69
|
+
test_files: []
|