students_list_yaml_tik 0.1.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/demo_yaml_gem.rb +17 -0
- data/lib/students_list.rb +69 -0
- data/lib/students_list_yaml/abstract_student.rb +34 -0
- data/lib/students_list_yaml/data_list.rb +51 -0
- data/lib/students_list_yaml/data_list_student_short.rb +17 -0
- data/lib/students_list_yaml/data_table.rb +27 -0
- data/lib/students_list_yaml/student.rb +131 -0
- data/lib/students_list_yaml/student_short.rb +24 -0
- data/lib/students_list_yaml.rb +32 -0
- metadata +60 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 88d1cbdb534c615d3b07b01615eb7ac3088c76d650eca5ed929d69c97b2faee4
|
|
4
|
+
data.tar.gz: 987badbccf07737241c2f282793f3c9fc3efa0bc232b6ca13380c6dc66bf0607
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3c4483eec191c965af7ff6196310bb361ff20c65344875bcd9340d928feabffc4df5a36d05eda6155f3f279bad3a9f18d8d2730dcab7458e2e1d580612462dce
|
|
7
|
+
data.tar.gz: a4d9f957aea15c974de4cf86926fcb024433ab6da118d1e568e8c186f34e122cb8baf4725f1c80bcac565c548274848f732c7c5071218e2070affd9384b6d5a4
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'students_list_yaml_1'
|
|
2
|
+
|
|
3
|
+
students = StudentsListYAML.new("../data/students.yaml")
|
|
4
|
+
|
|
5
|
+
student = Student.new(
|
|
6
|
+
first_name: "Иван",
|
|
7
|
+
last_name: "Иванов",
|
|
8
|
+
patronymic: "Иванович",
|
|
9
|
+
git: "https://github.com/ivan"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
students.add_student(student)
|
|
13
|
+
|
|
14
|
+
puts "Всего студентов: #{students.get_student_short_count}"
|
|
15
|
+
|
|
16
|
+
s = students.get_student_by_id(1)
|
|
17
|
+
puts "#{s.last_name} #{s.first_name}"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require_relative '../models/student'
|
|
2
|
+
require_relative '../models/student_short'
|
|
3
|
+
require_relative '../models/data_list_student_short'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StudentsList
|
|
7
|
+
def initialize(file_path)
|
|
8
|
+
@file_path = file_path
|
|
9
|
+
@students = []
|
|
10
|
+
read_from_file
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_student_by_id(id)
|
|
14
|
+
@students.find { |s| s.id == id }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_student_short_count
|
|
18
|
+
@students.size
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def sort_by_fio!
|
|
22
|
+
@students.sort!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_student(student)
|
|
26
|
+
max_id = @students.map(&:id).compact.max || 0
|
|
27
|
+
student.instance_variable_set(:@id, max_id + 1)
|
|
28
|
+
@students << student
|
|
29
|
+
write_to_file
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def replace_student_by_id(id, student)
|
|
33
|
+
begin
|
|
34
|
+
index = @students.index { |s| s.id == id }
|
|
35
|
+
raise ArgumentError, "Student with ID #{id} not found" unless index
|
|
36
|
+
student.instance_variable_set(:@id, id)
|
|
37
|
+
@students[index] = student
|
|
38
|
+
write_all
|
|
39
|
+
true
|
|
40
|
+
rescue ArgumentError => e
|
|
41
|
+
puts "Error in replace_student_by_id: #{e.message}"
|
|
42
|
+
false
|
|
43
|
+
rescue => e
|
|
44
|
+
puts "Unexpected error in replace_student_by_id: #{e.message}"
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def delete_student_by_id(id)
|
|
50
|
+
@students.reject! { |s| s.id == id }
|
|
51
|
+
write_to_file
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def get_k_n_student_short_list(k, n, data_list = nil)
|
|
55
|
+
slice = @students.slice(n, k) || []
|
|
56
|
+
short = slice.map { |s| StudentShort.from_student(s) }
|
|
57
|
+
data_list ? data_list.data = short : DataListStudentShort.new(short)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
protected
|
|
61
|
+
|
|
62
|
+
def read_from_file
|
|
63
|
+
raise NotImplementedError
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def write_to_file
|
|
67
|
+
raise NotImplementedError
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class AbstructStudent
|
|
2
|
+
attr_reader :id, :git
|
|
3
|
+
|
|
4
|
+
def initialize(id:, git: nil)
|
|
5
|
+
@id = id
|
|
6
|
+
@git = git
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def has_git?
|
|
10
|
+
!@git.nil?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def has_contact?
|
|
14
|
+
!contact.nil?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def contact
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def last_name_initials
|
|
22
|
+
raise NotImplementedError
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def short_info
|
|
26
|
+
result = []
|
|
27
|
+
result << "ID: #{self.id} "
|
|
28
|
+
result << "ФИО: #{last_name_initials} "
|
|
29
|
+
result << "#{contact} " if contact
|
|
30
|
+
result << "Git-репозиторий: #{self.git} "
|
|
31
|
+
result.join(", ")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
class DataList
|
|
2
|
+
def initialize(data)
|
|
3
|
+
@data = data.freeze if valid_data?(data)
|
|
4
|
+
@indxes = Set.new
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def data=(data)
|
|
8
|
+
@data = data.freeze if valid_data?(data)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def select(number)
|
|
12
|
+
return unless number.between?(0, @data.size - 1)
|
|
13
|
+
|
|
14
|
+
@indxes.add(number)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_selected
|
|
18
|
+
@indxes.map { |ind| @data[ind].id }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get_names
|
|
22
|
+
['№ по порядку'] + make_names
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def get_data
|
|
26
|
+
|
|
27
|
+
matrix = (0..@data.size - 1).map { |ind| [ind] + make_matrix(ind) }
|
|
28
|
+
DataTable.new(matrix)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def clear_selected
|
|
32
|
+
@indxes.clear
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def valid_data?(data)
|
|
38
|
+
raise ArgumentError unless data.is_a?(Array)
|
|
39
|
+
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def make_names
|
|
44
|
+
raise NotImplementedError
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def make_matrix(matix)
|
|
48
|
+
raise NotImplementedError
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative 'data_list'
|
|
2
|
+
require_relative 'data_table'
|
|
3
|
+
require_relative 'student_short'
|
|
4
|
+
#require_relative 'student'
|
|
5
|
+
|
|
6
|
+
class DataListStudentShort < DataList
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def make_matrix(ind)
|
|
10
|
+
[ @data[ind].last_name_initials, @data[ind].contact, @data[ind].git]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def make_names
|
|
14
|
+
%w[ФИО Контакт Git]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class DataTable
|
|
2
|
+
|
|
3
|
+
def initialize(data)
|
|
4
|
+
@data = data.freeze if valid_matrix?(data)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def get_element_by_id(row, column)
|
|
8
|
+
@data[row][column]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def column_count
|
|
12
|
+
@data.empty? ? 0 : @data[0].size
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def row_count
|
|
16
|
+
@data.size
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def valid_matrix?(data)
|
|
22
|
+
raise ArgumentError unless data.is_a?(Array) && data.all? { |x| x.is_a?(Array) }
|
|
23
|
+
|
|
24
|
+
true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
require_relative 'abstract_student'
|
|
2
|
+
|
|
3
|
+
class Student < AbstructStudent
|
|
4
|
+
include Comparable
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
attr_reader :first_name, :last_name, :patronymic
|
|
8
|
+
|
|
9
|
+
def initialize(first_name:, last_name:, patronymic: nil, id: nil, phone: nil, telegram: nil, email: nil, git: nil)
|
|
10
|
+
super(id: id, git: nil)
|
|
11
|
+
self.last_name = last_name
|
|
12
|
+
self.first_name = first_name
|
|
13
|
+
self.patronymic = patronymic
|
|
14
|
+
self.phone = phone
|
|
15
|
+
self.telegram = telegram
|
|
16
|
+
self.email = email
|
|
17
|
+
self.git = git
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
def self.valid_attr(field, valid, is_nil: false)
|
|
22
|
+
define_method("#{field}=") do |value|
|
|
23
|
+
if value.nil?
|
|
24
|
+
raise ArgumentError unless is_nil
|
|
25
|
+
else
|
|
26
|
+
raise ArgumentError unless self.class.send(valid, value)
|
|
27
|
+
end
|
|
28
|
+
case field
|
|
29
|
+
when :last_name then @last_name = value
|
|
30
|
+
when :first_name then @first_name = value
|
|
31
|
+
when :patronymic then @patronymic = value
|
|
32
|
+
when :phone then @phone = value
|
|
33
|
+
when :telegram then @telegram = value
|
|
34
|
+
when :email then @email = value
|
|
35
|
+
when :git then @git = value
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
valid_attr :phone, :valid_phone?, is_nil: true
|
|
41
|
+
valid_attr :telegram, :valid_telegram?, is_nil: true
|
|
42
|
+
valid_attr :email, :valid_email?, is_nil: true
|
|
43
|
+
|
|
44
|
+
public
|
|
45
|
+
|
|
46
|
+
valid_attr :last_name, :valid_name?
|
|
47
|
+
valid_attr :first_name, :valid_name?
|
|
48
|
+
valid_attr :patronymic, :valid_name?, is_nil: true
|
|
49
|
+
valid_attr :git, :valid_git?, is_nil: true
|
|
50
|
+
|
|
51
|
+
def contact=(contacts)
|
|
52
|
+
raise TypeError unless contacts.is_a?(Hash)
|
|
53
|
+
|
|
54
|
+
self.phone = contacts[:phone]
|
|
55
|
+
self.email = contacts[:email]
|
|
56
|
+
self.telegram = contacts[:telegram]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def contact
|
|
60
|
+
return "telegram - #{@telegram}" unless @telegram.nil?
|
|
61
|
+
return "email - #{@email}" unless @email.nil?
|
|
62
|
+
return "phone - #{@phone}" unless @phone.nil?
|
|
63
|
+
|
|
64
|
+
nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def last_name_initials
|
|
68
|
+
initials = "#{@last_name} #{@first_name[0]}."
|
|
69
|
+
initials += " #{@patronymic[0]}." unless @patronymic.nil?
|
|
70
|
+
initials
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def to_s
|
|
74
|
+
info = []
|
|
75
|
+
info << "ID: #{@id}" if @id
|
|
76
|
+
info << "Фамилия: #{@last_name}"
|
|
77
|
+
info << "Имя: #{@first_name}"
|
|
78
|
+
info << "Отчество: #{@patronymic}" if @patronymic && !@patronymic.empty?
|
|
79
|
+
info << "Телефон: #{@phone}" if @phone
|
|
80
|
+
info << "Телеграм: #{@telegram}" if @telegram
|
|
81
|
+
info << "Почта: #{@email}" if @email
|
|
82
|
+
info << "Гит: #{@git}" if @git
|
|
83
|
+
info.join(", ")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def to_h
|
|
87
|
+
{
|
|
88
|
+
id: @id,
|
|
89
|
+
first_name: @first_name,
|
|
90
|
+
last_name: @last_name,
|
|
91
|
+
patronymic: @patronymic,
|
|
92
|
+
phone: @phone,
|
|
93
|
+
telegram: @telegram,
|
|
94
|
+
email: @email,
|
|
95
|
+
git: @git
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class << self
|
|
102
|
+
def valid_name?(val)
|
|
103
|
+
!val.nil? && val.match?(/\A[А-ЯA-ZЁ][а-яa-zё]+\z/)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def valid_email?(val)
|
|
107
|
+
return true if val.nil? || val.empty?
|
|
108
|
+
val.match?(/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def valid_phone?(val)
|
|
112
|
+
return true if val.nil? || val.empty?
|
|
113
|
+
val.match?(/^(\+7|8)?[\s\-\(]?(\d{3})[\s\-\)]?(\d{3})[\s\-]?(\d{2})[\s\-]?(\d{2})$/)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def valid_telegram?(val)
|
|
117
|
+
return true if val.nil? || val.empty?
|
|
118
|
+
val.match?(/^@[A-Za-z0-9_]{5,32}$/)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def valid_git?(val)
|
|
122
|
+
return true if val.nil? || val.empty?
|
|
123
|
+
val.is_a?(String) && val.match?(/^https:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\/?$/)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def <=>(other)
|
|
129
|
+
[last_name, first_name, patronymic] <=> [other.last_name, other.first_name, other.patronymic]
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'abstract_student'
|
|
2
|
+
require_relative 'student'
|
|
3
|
+
|
|
4
|
+
class StudentShort < AbstructStudent
|
|
5
|
+
attr_reader :last_name_initials, :contact
|
|
6
|
+
|
|
7
|
+
def initialize(id:, last_name_initials:, contact: nil, git: nil)
|
|
8
|
+
super(id: id, git: git)
|
|
9
|
+
@last_name_initials = last_name_initials
|
|
10
|
+
@contact = contact
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.from_student(student)
|
|
14
|
+
new(id: student.id, last_name_initials: student.last_name_initials, contact: student.contact, git: student.git)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_s
|
|
18
|
+
"ID: #{@id}, ФИО: #{@last_name_initials}, Контакт: #{@contact}, Git-репозиторий: #{@git}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def short_info
|
|
22
|
+
to_s
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require_relative 'students_list.rb'
|
|
4
|
+
|
|
5
|
+
class StudentsListYAML < StudentsList
|
|
6
|
+
|
|
7
|
+
def read_from_file
|
|
8
|
+
return unless File.exist?(@file_path)
|
|
9
|
+
data = YAML.load_file(@file_path, symbolize_names: true)
|
|
10
|
+
@students = data.map { |h| Student.new(**h) }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def write_to_file
|
|
14
|
+
dir = File.dirname(@file_path)
|
|
15
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
|
16
|
+
|
|
17
|
+
data = @students.map do |s|
|
|
18
|
+
{
|
|
19
|
+
id: s.id,
|
|
20
|
+
first_name: s.first_name,
|
|
21
|
+
last_name: s.last_name,
|
|
22
|
+
patronymic: s.patronymic,
|
|
23
|
+
phone: s.instance_variable_get(:@phone),
|
|
24
|
+
telegram: s.instance_variable_get(:@telegram),
|
|
25
|
+
email: s.instance_variable_get(:@email),
|
|
26
|
+
git: s.git
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
File.write(@file_path, data.to_yaml)
|
|
31
|
+
end
|
|
32
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: students_list_yaml_tik
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- tik
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: yaml
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
description: Gem для управления списками студентов с помощью файлов YAML
|
|
27
|
+
email: tigran_205@mail.ru
|
|
28
|
+
executables: []
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- lib/demo_yaml_gem.rb
|
|
33
|
+
- lib/students_list.rb
|
|
34
|
+
- lib/students_list_yaml.rb
|
|
35
|
+
- lib/students_list_yaml/abstract_student.rb
|
|
36
|
+
- lib/students_list_yaml/data_list.rb
|
|
37
|
+
- lib/students_list_yaml/data_list_student_short.rb
|
|
38
|
+
- lib/students_list_yaml/data_table.rb
|
|
39
|
+
- lib/students_list_yaml/student.rb
|
|
40
|
+
- lib/students_list_yaml/student_short.rb
|
|
41
|
+
licenses: []
|
|
42
|
+
metadata: {}
|
|
43
|
+
rdoc_options: []
|
|
44
|
+
require_paths:
|
|
45
|
+
- lib
|
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: '3.0'
|
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
56
|
+
requirements: []
|
|
57
|
+
rubygems_version: 4.0.3
|
|
58
|
+
specification_version: 4
|
|
59
|
+
summary: YAML-хранилище для списка студентов
|
|
60
|
+
test_files: []
|