students_list_yaml_umar 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: c6cf3cea4a4c0eecc30199e75d69f093dee9657684afaeaed3046bd9412fedb1
4
+ data.tar.gz: 482d43f20481811a8037f2f0008f47cefd27cfbc4fefe026dc7caed288e90a95
5
+ SHA512:
6
+ metadata.gz: c83b57405e0cb5e493efa3d04a22cb89792463e8335807dc67cd549e0c5eeefbc749c29ea769c6588139fc679ac4bc9ea7d443fdec19d35c03f73c84703f54c5
7
+ data.tar.gz: 93b67acd32108a1d167c314aa0fb2771ae705a47d9b14106f033917e3578eb1bce00bdf6ee23f9b1396c52c180241c09eca815fcfa3e35b070b9c8b5db76da45
data/lib/Data.png ADDED
Binary file
Binary file
Binary file
data/lib/data_list.rb ADDED
@@ -0,0 +1,51 @@
1
+ require_relative 'data_table.rb'
2
+ class DataList
3
+ def initialize(array)
4
+ self.data = array
5
+ @selected = []
6
+ end
7
+
8
+ def data=(array)
9
+ @data = array.dup.freeze
10
+ end
11
+
12
+ def select(number)
13
+ raise ArgumentError if number < 0 || number >= @data.size
14
+ @selected << number unless @selected.include?(number)
15
+ end
16
+
17
+
18
+ def get_selected
19
+ @selected.map { |i| @data[i].id }
20
+ end
21
+
22
+
23
+ def clear_selected
24
+ @selected.clear
25
+ end
26
+
27
+ def get_names
28
+ ["№ по порядку"] + get_custom_names
29
+ end
30
+
31
+
32
+ def get_data
33
+ rows = []
34
+ @data.each_with_index do |obj, index|
35
+ rows << [index + 1] + get_custom_row(obj)
36
+ end
37
+ DataTable.new(rows)
38
+ end
39
+
40
+ protected
41
+
42
+ def get_custom_names
43
+ raise NotImplementedError, "Метод get_custom_names должен быть реализован в наследнике"
44
+ end
45
+
46
+ def get_custom_row(obj)
47
+ raise NotImplementedError, "Метод get_custom_row должен быть реализован в наследнике"
48
+ end
49
+
50
+ attr_reader :data, :selected
51
+ end
@@ -0,0 +1,14 @@
1
+ require_relative 'data_list.rb'
2
+ require_relative 'student_short.rb'
3
+
4
+ class DataListStudentShort < DataList
5
+ protected
6
+
7
+ def get_custom_names
8
+ ["ФИО", "Контакт", "Git"]
9
+ end
10
+
11
+ def get_custom_row(student_short)
12
+ [student_short.last_name_initials, student_short.contact, student_short.git]
13
+ end
14
+ end
data/lib/data_table.rb ADDED
@@ -0,0 +1,23 @@
1
+ class DataTable
2
+ def initialize(rows)
3
+ @rows = rows.map(&:dup).freeze
4
+
5
+ end
6
+
7
+ def get(row, col)
8
+ @rows.fetch(row).fetch(col)
9
+ end
10
+
11
+ def rows
12
+ @rows.length
13
+ end
14
+
15
+ def columns
16
+ return 0 if @rows.empty?
17
+ @rows[0].length
18
+ end
19
+
20
+ def to_s
21
+ @rows.to_s
22
+ end
23
+ end
data/lib/student.rb ADDED
@@ -0,0 +1,140 @@
1
+ require_relative 'superstudent.rb'
2
+ class Student < SuperStudent
3
+ attr_reader :last_name, :first_name, :patronymic
4
+ include Comparable
5
+
6
+ def self.validated_attr_writer(attribute, validation_method)
7
+ define_method("#{attribute}=") do |value|
8
+ raise ArgumentError unless self.class.send(validation_method, value)
9
+ instance_variable_set("@#{attribute}", value)
10
+ end
11
+ end
12
+
13
+ def <=>(other)
14
+ [first_name, last_name, patronymic || nil] <=> [other.first_name, other.last_name, other.patronymic || nil]
15
+ end
16
+
17
+ def ==(other)
18
+ self_data = to_hash
19
+ other_data = other.to_hash
20
+
21
+ [:telegram, :email, :phone, :git].each do |field|
22
+ a = self_data[field]
23
+ b = other_data[field]
24
+
25
+ next if a.nil? || b.nil?
26
+ a = a.to_s.strip
27
+ b = b.to_s.strip
28
+ next if a.empty? || b.empty?
29
+
30
+ return true if a == b
31
+ end
32
+
33
+ false
34
+ end
35
+
36
+ validated_attr_writer :first_name, :valid_name?
37
+ validated_attr_writer :last_name, :valid_name?
38
+ validated_attr_writer :patronymic, :valid_name?
39
+ validated_attr_writer :git, :valid_git?
40
+
41
+ def initialize(last_name:, first_name:, id: nil, patronymic: nil, git: nil, phone: nil, telegram: nil, email: nil)
42
+ raise ArgumentError, "Неверный формат гита" unless self.class.valid_git?(git)
43
+ super(id: id, git: git)
44
+
45
+ self.last_name = last_name
46
+ self.first_name = first_name
47
+ self.patronymic = patronymic
48
+ self.contact = { phone: phone, telegram: telegram, email: email }
49
+ end
50
+
51
+
52
+ def to_hash
53
+ {
54
+ id: @id,
55
+ last_name: @last_name,
56
+ first_name: @first_name,
57
+ patronymic: @patronymic,
58
+ telegram: @telegram,
59
+ email: @email,
60
+ phone: @phone,
61
+ git: @git
62
+ }
63
+ end
64
+
65
+ def self.from_hash(hash)
66
+ hash = hash.transform_keys(&:to_sym)
67
+
68
+ new(
69
+ id: hash[:id],
70
+ last_name: hash[:last_name] || "",
71
+ first_name: hash[:first_name] || "",
72
+ patronymic: hash[:patronymic] || "",
73
+ telegram: hash[:telegram],
74
+ email: hash[:email],
75
+ phone: hash[:phone],
76
+ git: hash[:git]
77
+ )
78
+ end
79
+
80
+
81
+ def last_name_initials
82
+ initials = ''
83
+ initials += "#{@first_name[0].upcase}." if @first_name
84
+ initials += " #{@patronymic[0].upcase}." if @patronymic
85
+ "#{@last_name} #{initials}"
86
+ end
87
+
88
+ def contact
89
+ if @telegram && !@telegram.empty?
90
+ "telegram - #{@telegram}"
91
+ elsif @email && !@email.empty?
92
+ "email - #{@email}"
93
+ elsif @phone && !@phone.empty?
94
+ "phone - #{@phone}"
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ def contact=(contacts)
101
+ contacts.each do |type, value|
102
+ validator = "valid_#{type}?".to_sym
103
+ raise ArgumentError, "Неверный формат #{type}" unless self.class.send(validator, value)
104
+ instance_variable_set("@#{type}", value)
105
+ end
106
+ end
107
+
108
+ def to_s
109
+ "ID: #{@id}\n
110
+ ФИО: #{last_name} #{first_name} #{patronymic}\n
111
+ Git: #{@git}\n
112
+ Телефон: #{@phone}\n
113
+ Telegram: #{@telegram}\n
114
+ Email: #{@email}"
115
+ end
116
+
117
+
118
+ class << self
119
+ def valid_name?(val)
120
+ !val.nil? && val.match?(/\A[А-ЯA-ZЁ][а-яa-zё]+\z/)
121
+ end
122
+
123
+ def valid_email?(val)
124
+ val.nil? || val.match?(/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i)
125
+ end
126
+
127
+ def valid_phone?(val)
128
+ val.nil? || val.match?(/^(\+7|8)?[\s\-\(]?(\d{3})[\s\-\)]?(\d{3})[\s\-]?(\d{2})[\s\-]?(\d{2})$/)
129
+ end
130
+
131
+ def valid_telegram?(val)
132
+ val.nil? || val.match?(/^@[A-Za-z0-9_]{5,32}$/)
133
+ end
134
+
135
+ def valid_git?(val)
136
+ val.nil? || (val.is_a?(String) && val.match?(/^https:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\/?$/))
137
+ end
138
+ end
139
+
140
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'student'
2
+ require_relative 'superstudent.rb'
3
+ class StudentShort < SuperStudent
4
+ attr_reader :id, :last_name_initials, :contact, :git
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
+ new(
14
+ id: student.id,
15
+ last_name_initials: student.last_name_initials,
16
+ contact: student.contact,
17
+ git: student.git
18
+ )
19
+ end
20
+
21
+ def to_s
22
+ "ID: #{@id}\nФИО: #{last_name_initials}\nКонтакт: #{contact}\nGit: #{@git}"
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,27 @@
1
+ require_relative "student_tree.rb"
2
+ require_relative "student.rb"
3
+
4
+ array = [Student.new(first_name: "Иван", last_name: "Смирнов", patronymic: "Алексеевич", telegram: "@ivan_smirnov", git: "https://github.com/ivan"),
5
+ Student.new(first_name: "Анна", last_name: "Иванова", email: "anna@example.com"),
6
+ Student.new(first_name: "Ольга", last_name: "Борисова", telegram: "@olga_bor", email: "olga@example.com"),
7
+ Student.new(first_name: "Максим", last_name: "Зайцев", git: "https://github.com/max"),
8
+ Student.new(first_name: "Елена", last_name: "Кузнецова", patronymic: "Игоревна", phone: "+79161234567"),
9
+ Student.new(first_name: "Дмитрий", last_name: "Новиков", telegram: "@d_novikov"),
10
+ Student.new(first_name: "Светлана", last_name: "Орлова", patronymic: "Владимировна", email: "svetlana@edu.ru", git: "https://github.com/svetlana"),
11
+ Student.new(first_name: "Алексей", last_name: "Попов", phone: "+79201112233"),
12
+ Student.new(first_name: "Татьяна", last_name: "Романова", email: "tatiana@corp.ru", git: "https://github.com/tatiana"),
13
+ Student.new(first_name: "Сергей", last_name: "Сидоров", patronymic: "Геннадьевич", telegram: "@serg_sid", phone: "+79005556677"),
14
+ Student.new(first_name: "Юлия", last_name: "Тихонова", git: "https://github.com/yulia", email: "yulia@domain.com"),
15
+ Student.new(first_name: "Виктор", last_name: "Умаров", telegram: "@vik_uvarov"),
16
+ Student.new(first_name: "Мария", last_name: "Федорова")]
17
+
18
+ tree = StudentTree.new
19
+
20
+ petr = Student.new(first_name: "Петр", last_name: "Алексеев", patronymic: "Олегович", phone: "+79001234567", git: "https://github.com/petr")
21
+ target = petr
22
+
23
+ tree.append(petr)
24
+ array.each { |x| tree.append(x) }
25
+
26
+ puts tree.select { |x| x == petr },"\n"
27
+ puts tree.min,"\n"
@@ -0,0 +1,69 @@
1
+ require_relative "student.rb"
2
+
3
+ class StudentTree
4
+ include Enumerable
5
+
6
+ attr_reader :root, :left, :right
7
+
8
+ def initialize(root = nil, left = nil, right = nil)
9
+ @root = root
10
+ @left = left
11
+ @right = right
12
+ end
13
+
14
+ def append(other)
15
+ if @root.nil?
16
+ @root = other
17
+ else
18
+ case other < @root
19
+ when true
20
+ if @left.nil?
21
+ @left = StudentTree.new(other)
22
+ else
23
+ @left.append(other)
24
+ end
25
+ when false
26
+ if @right.nil?
27
+ @right = StudentTree.new(other)
28
+ else
29
+ @right.append(other)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def remove(other)
36
+ case compare(other, @root)
37
+ when -1
38
+ @left = @left&.remove(other)
39
+ when 1
40
+ @right = @right&.remove(other)
41
+ when 0
42
+ return @right if @left.nil?
43
+ return @left if @right.nil?
44
+
45
+ min_value = @right.min
46
+ @root = min_value
47
+ @right = @right.remove(min_value)
48
+ end
49
+ end
50
+
51
+ def find(&block)
52
+ return @root if !@root.nil? && block.call(@root)
53
+
54
+ left_result = @left&.find(&block)
55
+ return left_result unless left_result.nil?
56
+
57
+ @right&.find(&block)
58
+ end
59
+
60
+ def each(&block)
61
+ @left&.each(&block)
62
+ block.call(@root) unless root.nil?
63
+ @right&.each(&block)
64
+ end
65
+
66
+ def compare(a, b)
67
+ a <=> b
68
+ end
69
+ end
@@ -0,0 +1,33 @@
1
+ class SuperStudent
2
+ attr_reader :id, :git
3
+
4
+ def initialize(id:nil, git:nil)
5
+ @id = id
6
+ @git = git
7
+ end
8
+
9
+ def has_git?
10
+ !git.nil? && !git.strip.empty?
11
+ end
12
+
13
+ def has_contact?
14
+ !contact.nil? && !contact.strip.empty?
15
+ end
16
+
17
+ def short_info
18
+ "ID: #{@id}\nФИО: #{last_name_initials}\nКонтакт: #{contact}\nGit: #{@git}"
19
+ end
20
+
21
+ protected
22
+ def to_s
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def contact
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def last_name_initials
31
+ raise NotImplementedError
32
+ end
33
+ end
data/lib/uniq_error.rb ADDED
@@ -0,0 +1,2 @@
1
+ class UniqueError < ArgumentError
2
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: students_list_yaml_umar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Umar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-01-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Gem for working with students stored in YAML files
14
+ email:
15
+ - umar@student.local
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/Data.png
21
+ - lib/StudentBeforeRefactoring.png
22
+ - lib/SuperStudentrefactoring.png
23
+ - lib/data_list.rb
24
+ - lib/data_list_student_short.rb
25
+ - lib/data_table.rb
26
+ - lib/student.rb
27
+ - lib/student_short.rb
28
+ - lib/student_test_tree.rb
29
+ - lib/student_tree.rb
30
+ - lib/superstudent.rb
31
+ - lib/uniq_error.rb
32
+ homepage:
33
+ licenses:
34
+ - MIT
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '2.7'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubygems_version: 3.4.20
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Students list YAML storage
55
+ test_files: []