students_list_yaml_gem_ahverdyan 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cd6731b2df1327950c3aca7bf6fa8ddd125b3fe0daee02b978be0b23f4e65709
4
+ data.tar.gz: b6644cf7cb7bdfd23b0533f0d128768bcd67d7ccebd217a7e3a622413de94ee1
5
+ SHA512:
6
+ metadata.gz: 91bde1ef9bdf4e45de8e40084f9fd368600873394ee7c7ee77beb9e7eb4974eb7edfcf16b35881777f357595dde42f034e6dca8236544703385106cb22b39ab0
7
+ data.tar.gz: 2a09ff3a222064a2643da847f73c177938b27d85500d6138ff83bd3509636f150f3cd090f9b56c44eafa4a2980c10390f3b3fa24b871d49ae31112e4f60b8ea8
@@ -0,0 +1,49 @@
1
+ require_relative 'data_table'
2
+ class DataList
3
+ def initialize(array)
4
+ self.data = array
5
+ @selected = []
6
+ end
7
+
8
+ def data=(array)
9
+ @array = array.freeze
10
+ end
11
+
12
+ def select(number)
13
+ @selected << @array[number]
14
+ end
15
+
16
+ def get_selected
17
+ @selected.map { |i| i.id }
18
+ end
19
+
20
+ def get_names
21
+ ["№ по порядку"] + get_custom_names
22
+ end
23
+
24
+ def get_data
25
+ rows = []
26
+ @array.each_with_index do |object, index|
27
+ rows << [index + 1] + get_custom_row(object)
28
+ end
29
+ DataTable.new(rows)
30
+ end
31
+
32
+ def clear_selected
33
+ @selected.clear
34
+ end
35
+
36
+ def to_s
37
+ get_data.to_s
38
+ end
39
+
40
+ protected
41
+ def get_custom_names
42
+ raise NotImplementedError
43
+ end
44
+
45
+ def get_custom_row(object)
46
+ raise NotImplementedError
47
+ end
48
+
49
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'data_list'
2
+ require_relative 'student_short'
3
+ class DataListStudentShort < DataList
4
+ def get_custom_names
5
+ ["ФИО", "Контакт", "Гит"]
6
+ end
7
+
8
+ def get_custom_row(student)
9
+ [student.last_name_initials, student.contact, student.git]
10
+ end
11
+ end
@@ -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
@@ -0,0 +1,38 @@
1
+ class ParentStudent
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
+ array = []
15
+ array << "id студента:#{id}" if id
16
+ array << "Фамилия и инициалы: #{last_name_initials}"
17
+ array << "Контакт: #{contact}" if has_contact?
18
+ array << "Гит:#{git}" if has_git?
19
+ array.join(", ")
20
+ end
21
+
22
+ def has_contact?
23
+ !contact.nil? && !contact.empty?
24
+ end
25
+
26
+ def has_git?
27
+ !git.nil? && !git.empty?
28
+ end
29
+
30
+ protected
31
+ def last_name_initials
32
+ raise NotImplementedError
33
+ end
34
+
35
+ def contact
36
+ raise NotImplementedError
37
+ end
38
+ end
@@ -0,0 +1,127 @@
1
+ require_relative 'parent_student'
2
+ class Student < ParentStudent
3
+ attr_reader :last_name, :first_name, :patronymic
4
+ include Comparable
5
+
6
+ def initialize(id: nil, last_name:, first_name:, patronymic: nil, phone: nil, telegram: nil, email: nil, git: nil)
7
+ raise ArgumentError, "Неверный формат гита #{git}" unless self.class.valid_git?(git)
8
+ super(id:id, git: git)
9
+ self.last_name = last_name
10
+ self.first_name = first_name
11
+ self.patronymic = patronymic
12
+ self.contact = {phone: phone, telegram: telegram, email: email}
13
+ end
14
+
15
+ def contact
16
+ if @telegram && !@telegram.empty?
17
+ "telegram - #{@telegram}"
18
+ elsif @email && !@email.empty?
19
+ "email - #{@email}"
20
+ elsif @phone && !@phone.empty?
21
+ "phone - #{@phone}"
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ def contact=(contacts)
28
+ contacts.each do |type, value|
29
+ validator = "valid_#{type}?".to_sym
30
+ raise ArgumentError, "Неверный формат #{type}" unless self.class.send(validator, value)
31
+ instance_variable_set("@#{type}", value)
32
+ end
33
+ end
34
+
35
+ def self.validated_attr_writer(attribute, validation_name)
36
+ define_method("#{attribute}=") do |value|
37
+ raise ArgumentError unless self.class.send(validation_name, value)
38
+ instance_variable_set("@#{attribute}", value)
39
+ end
40
+ end
41
+
42
+ validated_attr_writer :first_name, :valid_name?
43
+ validated_attr_writer :last_name, :valid_name?
44
+ validated_attr_writer :patronymic, :valid_name?
45
+ validated_attr_writer :git, :valid_git?
46
+
47
+ def last_name_initials
48
+ if patronymic
49
+ "#{last_name} #{first_name[0]}. #{patronymic[0]}."
50
+ else
51
+ "#{last_name} #{first_name[0]}."
52
+ end
53
+ end
54
+
55
+ def self.valid_name?(name)
56
+ name.nil? || (name.is_a?(String) && name.match?(/^[А-ЯA-Z][а-яa-z]+$/))
57
+ end
58
+
59
+ def self.valid_phone?(phone)
60
+ phone.nil? || (phone.is_a?(String) && phone.match?(/^(\+7|8)?[\s\-\(]?(\d{3})[\s\-\)]?(\d{3})[\s\-]?(\d{2})[\s\-]?(\d{2})$/))
61
+ end
62
+
63
+ def self.valid_telegram?(telegram)
64
+ telegram.nil? || (telegram.is_a?(String) && telegram.match?(/^@[a-zA-Z0-9_]{5,32}$/))
65
+ end
66
+
67
+ def self.valid_email?(email)
68
+ email.nil? || (email.is_a?(String) && email.match?(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/))
69
+ end
70
+
71
+ def self.valid_git?(git)
72
+ git.nil? || (git.is_a?(String) && git.match?(/^https:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\/?$/))
73
+ end
74
+
75
+ def to_s
76
+ array = []
77
+ array << "id студента: #{id}" if id
78
+ array << "Фамилия: #{last_name}"
79
+ array << "Имя: #{first_name}"
80
+ array << "Отчество: #{patronymic}" if patronymic
81
+ array << "Номер телефона: #{@phone}" if @phone
82
+ array << "Телеграм: #{@telegram}" if @telegram
83
+ array << "Почта: #{@email}" if @email
84
+ array << "Гит: #{git}" if has_git?
85
+ array.join(", ")
86
+ end
87
+
88
+ def to_h
89
+ {
90
+ id: id,
91
+ last_name: last_name,
92
+ first_name: first_name,
93
+ patronymic: patronymic,
94
+ phone: @phone,
95
+ telegram: @telegram,
96
+ email: @email,
97
+ git: git
98
+ }.compact
99
+ end
100
+
101
+ def self.from_h(id: nil, hash:)
102
+ new(
103
+ id: id,
104
+ last_name: hash[:last_name],
105
+ first_name: hash[:first_name],
106
+ patronymic: hash[:patronymic],
107
+ phone: hash[:phone],
108
+ telegram: hash[:telegram],
109
+ email: hash[:email],
110
+ git: hash[:git]
111
+ )
112
+ end
113
+
114
+ def <=>(value)
115
+ [last_name, first_name, patronymic || nil] <=> [value.last_name, value.first_name, value.patronymic || nil]
116
+ end
117
+
118
+ def ==(other)
119
+ return false unless other.is_a?(Student)
120
+ [:telegram, :email, :phone, :git].any? do |field|
121
+ self_val = to_h[field]
122
+ other_val = other.to_h[field]
123
+ self_val && other_val && self_val == other_val
124
+ end
125
+ end
126
+
127
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'student'
2
+ require_relative 'parent_student'
3
+ class StudentShort < ParentStudent
4
+ attr_reader :last_name_initials, :contact
5
+
6
+ def initialize (id:, last_name_initials:, contact: nil, git: nil)
7
+ super(id: id, git: git)
8
+ @last_name_initials = last_name_initials
9
+ @contact = contact
10
+ end
11
+
12
+ def self.from_student(student)
13
+ raise ArgumentError, "id не существует" if student.id.nil?
14
+ new(
15
+ id: student.id,
16
+ last_name_initials: student.last_name_initials,
17
+ contact: student.contact,
18
+ git: student.git
19
+ )
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ require 'yaml'
2
+ require_relative "student"
3
+ require_relative "data_list"
4
+ require_relative "student_short"
5
+ require_relative "data_list_student_short"
6
+
7
+
8
+ class DuplicateStudentError < StandardError; end
9
+
10
+ class StudentsListYAML
11
+ def initialize(file)
12
+ @file = file
13
+ @students = []
14
+ read_file
15
+ end
16
+
17
+ def read_file
18
+ yaml_ex = File.read(@file)
19
+ data = YAML.safe_load(yaml_ex, permitted_classes: [Symbol], symbolize_names: true)
20
+ @students = data.map { |h| Student.from_h(id: h[:id], hash: h) }
21
+ end
22
+
23
+ def write_file
24
+ data = @students.map { |s| s.to_h }
25
+ File.write(@file, YAML.dump(data))
26
+ end
27
+
28
+ def get_student_by_id(id)
29
+ @students.find { |s| s.id == id }
30
+ end
31
+
32
+ def get_k_n_student_short_list(k, n, data_list = nil)
33
+ start_index = (n - 1) * k
34
+ slice = @students[start_index, k] || []
35
+
36
+ student_shorts = slice.map do |s|
37
+ StudentShort.new(
38
+ id: s.id,
39
+ last_name_initials: s.last_name_initials,
40
+ contact: s.contact,
41
+ git: s.git
42
+ )
43
+ end
44
+
45
+ if data_list
46
+ data_list.data = student_shorts
47
+ data_list
48
+ else
49
+ DataListStudentShort.new(student_shorts)
50
+ end
51
+ end
52
+
53
+ def sort_by_surname_initials!
54
+ @students.sort_by! { |s| s.last_name_initials }
55
+ end
56
+
57
+ def unique(student)
58
+ raise DuplicateStudentError, "Студент с таким контактом уже существует" unless !@students.any? { |s| s == student }
59
+ end
60
+
61
+ def add_student(student)
62
+ unique(student)
63
+ max_id = @students.map { |s| s.id }.max || 0
64
+ value = student.to_h
65
+ @students << Student.from_h(id: max_id + 1, hash: value)
66
+ end
67
+
68
+ def replace_student_by_id(id, new_student)
69
+ unique(new_student)
70
+ index = @students.index { |s| s.id == id }
71
+ return unless index
72
+ @students[index] = Student.from_h(id: id, hash: new_student.to_h)
73
+ end
74
+
75
+ def delete_student_by_id(id)
76
+ @students.reject! { |s| s.id == id }
77
+ end
78
+
79
+ def get_student_short_count
80
+ @students.size
81
+ end
82
+ end
@@ -0,0 +1 @@
1
+ VERSION = "0.1.0"
@@ -0,0 +1,8 @@
1
+ require_relative "students_list_yaml/version"
2
+ require_relative "students_list_yaml/student"
3
+ require_relative "students_list_yaml/student_short"
4
+ require_relative "students_list_yaml/parent_student"
5
+ require_relative "students_list_yaml/data_list"
6
+ require_relative "students_list_yaml/data_list_student_short"
7
+ require_relative "students_list_yaml/data_table"
8
+ require_relative "students_list_yaml/students_list_yaml"
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: students_list_yaml_gem_ahverdyan
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - six6hroun
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-01-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Класс для работы со списком студентов, хранение в YAML, добавление, удаление,
14
+ обновление и проверка уникальности
15
+ email:
16
+ - gura0516@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/students_list_yaml.rb
22
+ - lib/students_list_yaml/data_list.rb
23
+ - lib/students_list_yaml/data_list_student_short.rb
24
+ - lib/students_list_yaml/data_table.rb
25
+ - lib/students_list_yaml/parent_student.rb
26
+ - lib/students_list_yaml/student.rb
27
+ - lib/students_list_yaml/student_short.rb
28
+ - lib/students_list_yaml/students_list_yaml.rb
29
+ - lib/students_list_yaml/version.rb
30
+ homepage:
31
+ licenses: []
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubygems_version: 3.4.20
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Управление списком студентов в YAML файле
52
+ test_files: []