students_list_yaml_Quartz 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: 95c6092475db21fe4c65f122426f93af80bad40716d3c43a612ffd7a9b6700ae
4
+ data.tar.gz: 33fcb5592ee4b4c9922537ce5c9e9c43d1850714764cbbe23200c156a77789ad
5
+ SHA512:
6
+ metadata.gz: 8cc4a7aae5c8d4013323fd639e12246ff77e3342742ca44070c576283d46fe842cfbaad8cc5a5ca2682b652daa67e3387b32ac99d9d36ddbecc38e4c9015d90a
7
+ data.tar.gz: 378290c9c17c7685a217cac342d3a18ec74c53890644836ccc1c58a60d8767cfaf21165047f2dab2f09c73848ac63a65427c83df49e857c00cafe22b8bdadf23
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Quartz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # StudentsListYaml
2
+
3
+ TODO: Delete this and the text below, and describe your gem
4
+
5
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/students_list_yaml`. To experiment with that code, run `bin/console` for an interactive prompt.
6
+
7
+ ## Installation
8
+
9
+ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
+
11
+ Install the gem and add to the application's Gemfile by executing:
12
+
13
+ ```bash
14
+ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
15
+ ```
16
+
17
+ If bundler is not being used to manage dependencies, install the gem by executing:
18
+
19
+ ```bash
20
+ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/students_list_yaml. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/students_list_yaml/blob/master/CODE_OF_CONDUCT.md).
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
+
41
+ ## Code of Conduct
42
+
43
+ Everyone interacting in the StudentsListYaml project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/students_list_yaml/blob/master/CODE_OF_CONDUCT.md).
data/lib/Base.rb ADDED
@@ -0,0 +1,35 @@
1
+ class Base
2
+
3
+ def git
4
+ @git
5
+ end
6
+
7
+ def id
8
+ @id
9
+ end
10
+
11
+ def contact
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def to_s
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def short_info
20
+ string = "id: #{id.to_s}, ФИО: #{last_name_initials}, гит: #{git}, контакт: #{contact}"
21
+ end
22
+
23
+ def has_git?
24
+ @git!=nil
25
+ end
26
+
27
+ def has_contact?
28
+ contact!=nil
29
+ end
30
+
31
+ def last_name_initials
32
+ raise NotImplementedError
33
+ end
34
+
35
+ end
data/lib/README.rdoc ADDED
@@ -0,0 +1,164 @@
1
+ = Students_list_JSON — README
2
+
3
+ == Описание
4
+ Класс Students_list_JSON — лёгкий Ruby-класс для управления коллекцией студентов, сериализуемой в JSON.
5
+ Обеспечивает загрузку/сохранение из/в файла, CRUD-операции, постраничную выдачу сокращённых представлений (StudentShort) и сортировку.
6
+
7
+ == Требования
8
+
9
+ Ruby 2.5+ (или совместимая).
10
+
11
+ Стандартная библиотека json.
12
+
13
+ В проекте должны присутствовать файлы:
14
+
15
+ student.rb — класс Student.
16
+
17
+ student_short.rb — класс StudentShort.
18
+
19
+ data_list_student_short.rb — класс DataListStudentShort (или общий DataList).
20
+
21
+ == Установка
22
+ Поместите файл students_list_json.rb в проект и подключите:
23
+
24
+ require_relative 'students_list_json'
25
+ require_relative 'student'
26
+ require_relative 'student_short'
27
+ require_relative 'data_list_student_short'
28
+
29
+
30
+ == Быстрый старт — пример использования
31
+
32
+ # инициализация (загрузка при наличии файла)
33
+ list = Students_list_JSON.new('students.json')
34
+
35
+ # добавление студента (предполагается реализация Student.from_hash/to_hash)
36
+ student = Student.from_hash(first_name: 'Ivan', last_name: 'Ivanov')
37
+ added = list.add_student(student)
38
+ puts "Добавлен студент с id=#{added.id}"
39
+
40
+ # сохранить в файл
41
+ list.save_to_file
42
+
43
+ # получить первого студента по id
44
+ s = list.get_student_by_id(1)
45
+ puts s.to_hash if s
46
+
47
+ # постраничная выдача — 10 элементов, страница 1
48
+ page = list.get_k_n_student_short_list(10, 1)
49
+ puts page.data.map(&:to_hash)
50
+
51
+
52
+ == API (краткое описание методов)
53
+
54
+ Students_list_JSON.new(file_path = nil) — конструктор; при наличии существующего file_path автоматически выполняет загрузку.
55
+
56
+ load_from_file — загрузка списка из @file_path. При некорректном JSON внутренний список очищается.
57
+
58
+ save_to_file — сохраняет @students в @file_path в виде pretty JSON.
59
+
60
+ get_student_by_id(id) — возвращает Student или nil.
61
+
62
+ get_k_n_student_short_list(k, n, existing_data_list = nil) — возвращает постраничный список StudentShort. Если передан existing_data_list типа DataList, его поле data перезаписывается.
63
+
64
+ sort_by_full_name — сортирует внутренний массив по last_name_initials.downcase.
65
+
66
+ add_student(student) — добавляет студента, генерирует уникальный id, возвращает добавленный объект.
67
+
68
+ replace_student_by_id(id, new_student) — заменяет студента с указанным id; возвращает true/false.
69
+
70
+ delete_student_by_id(id) — удаляет студента(ов) по id; возвращает true/false.
71
+
72
+ get_student_short_count — возвращает количество студентов (Integer).
73
+
74
+ == Формат JSON (ожидаемый)
75
+ Класс ожидает JSON-массив объектов, каждый объект — структура, совместимая с Student.from_hash и Student#to_hash.
76
+ Пример:
77
+
78
+ [
79
+ {"id":1,"first_name":"Ivan","last_name":"Ivanov","birth_date":"2000-01-01","group":"CS-101"},
80
+ {"id":2,"first_name":"Anna","last_name":"Petrova","birth_date":"1999-05-12","group":"CS-101"}
81
+ ]
82
+
83
+
84
+ == Ожидаемый интерфейс зависимых классов
85
+ Чтобы Students_list_JSON работал, зависимые классы должны поддерживать:
86
+
87
+ Student
88
+
89
+ .from_hash(hash) — создать объект из хэша.
90
+
91
+ #to_hash — вернуть хэш для сериализации.
92
+
93
+ #id — числовой идентификатор.
94
+
95
+ #last_name_initials — строка для сортировки (например, "Ivanov I.P.").
96
+
97
+ StudentShort
98
+
99
+ .from_student(student) — создать сокращённое представление.
100
+
101
+ #to_hash — (опционально) для сериализации.
102
+
103
+ DataListStudentShort / DataList
104
+
105
+ Конструктор DataListStudentShort.new(array_of_short_students) или объект с присваиваемым полем data для записи массива StudentShort.
106
+
107
+ == Поведение и ошибки
108
+
109
+ При JSON::ParserError — внутренний список очищается (чтобы избежать неконсистентных данных).
110
+
111
+ Если file_path не указан — операции загрузки/сохранения игнорируются.
112
+
113
+ get_k_n_student_short_list безопасно возвращает пустой список, если индекс выходит за пределы.
114
+
115
+ replace_student_by_id и delete_student_by_id возвращают логические значения, не выбрасывают исключения при отсутствии записи.
116
+
117
+ == Рекомендации по улучшению
118
+
119
+ Добавить логирование ошибок при парсинге JSON вместо тихого rescue.
120
+
121
+ Ввести валидацию входных объектов (проверять наличие to_hash, id и т.п.).
122
+
123
+ Для многопоточных приложений — использовать Mutex для защиты @students.
124
+
125
+ Валидация схемы JSON (gem json-schema или аналог).
126
+
127
+ == Генерация RDoc-документации
128
+
129
+ Убедитесь, что у вас установлен rdoc (если нет — gem install rdoc).
130
+
131
+ В каталоге с проектом выполните:
132
+
133
+ rdoc -o doc students_list_json.rb student.rb student_short.rb data_list_student_short.rb
134
+
135
+
136
+ Откройте doc/index.html в браузере.
137
+
138
+ Для генерации документации по всему проекту (включая README) выполните:
139
+
140
+ rdoc -o doc .
141
+
142
+
143
+ == Тестирование
144
+ Рекомендуется покрыть тестами (RSpec/Minitest) сценарии:
145
+
146
+ * загрузка корректного JSON;
147
+
148
+ * поведение при некорректном JSON;
149
+
150
+ * добавление/замена/удаление студентов;
151
+
152
+ * постраничная выдача и граничные условия;
153
+
154
+ * сохранение и повторная загрузка.
155
+
156
+ == Лицензия
157
+ Добавьте подходящую лицензию (например, MIT). Примерный блок для LICENSE:
158
+
159
+ MIT License
160
+ Copyright (c) <year> <author>
161
+ ...
162
+
163
+
164
+ == Контакты / автор
data/lib/Rakefile.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'rdoc/task'
2
+
3
+ RDoc::Task.new do |rdoc|
4
+ rdoc.title = "StudentListJSON Documentation"
5
+ rdoc.rdoc_dir = 'doc'
6
+ rdoc.main = 'README.rdoc'
7
+ rdoc.rdoc_files.include('README.rdoc')
8
+ rdoc.rdoc_files.include('Students_list_JSON.rb')
9
+ rdoc.rdoc_files.include('examples/*.rb')
10
+
11
+ rdoc.options << '--all'
12
+ rdoc.options << '--fmt=html'
13
+ end
14
+
15
+ task :default => :rdoc
@@ -0,0 +1,86 @@
1
+ require "json"
2
+ require_relative 'student'
3
+ require_relative 'student_short'
4
+ require_relative 'data_list'
5
+
6
+ class Students_list_JSON
7
+ attr_reader :file_path
8
+
9
+ def initialize(file_path = nil)
10
+ @file_path = file_path
11
+ @students = []
12
+ load_from_file if file_path && File.exist?(file_path)
13
+ end
14
+
15
+ def load_from_file
16
+ return unless @file_path && File.exist?(@file_path)
17
+
18
+ begin
19
+ content = File.read(@file_path)
20
+ return if content.strip.empty?
21
+
22
+ data = JSON.parse(content, symbolize_names: true)
23
+ @students = data.map { |hash| Student.from_hash(hash) }
24
+ rescue JSON::ParserError
25
+ @students = []
26
+ end
27
+ end
28
+
29
+ def save_to_file
30
+ return unless @file_path
31
+
32
+ data = @students.map(&:to_hash)
33
+ File.write(@file_path, JSON.pretty_generate(data))
34
+ end
35
+
36
+ def get_student_by_id(id)
37
+ @students.find { |student| student.id == id }
38
+ end
39
+
40
+ def get_k_n_student_short_list(k, n, existing_data_list = nil)
41
+ start_index = (n - 1) * k
42
+ selected = @students[start_index, k] || []
43
+
44
+ short_students = selected.map { |student| StudentShort.from_student(student) }
45
+
46
+ if existing_data_list && existing_data_list.is_a?(Data_list)
47
+ existing_data_list.data = short_students
48
+ existing_data_list
49
+ else
50
+ Data_list_student_short.new(short_students)
51
+ end
52
+ end
53
+
54
+ def sort_by_full_name
55
+ @students.sort_by! { |student| student.last_name_initials.downcase }
56
+ end
57
+
58
+ def add_student(student)
59
+ new_id = @students.empty? ? 1 : @students.map(&:id).max + 1
60
+ student_with_id = Student.from_hash(student.to_hash.merge(id: new_id))
61
+ @students << student_with_id
62
+ student_with_id
63
+ end
64
+
65
+ def replace_student_by_id(id, new_student)
66
+ index = @students.find_index { |s| s.id == id }
67
+ return false unless index
68
+
69
+ @students[index] = Student.from_hash(new_student.to_hash.merge(id: id))
70
+ true
71
+ end
72
+
73
+ def delete_student_by_id(id)
74
+ size_before = @students.size
75
+ @students.reject! { |s| s.id == id }
76
+ size_before != @students.size
77
+ end
78
+
79
+ def get_student_short_count
80
+ @students.size
81
+ end
82
+
83
+ private
84
+
85
+ attr_writer :students
86
+ end
data/lib/data_list.rb ADDED
@@ -0,0 +1,75 @@
1
+ require_relative 'data_table'
2
+ require_relative 'student_short'
3
+ class Data_list
4
+ def initialize(data)
5
+ @data=data
6
+ @selected=[]
7
+ end
8
+
9
+ def select(index)
10
+ @selected<<@data[index]
11
+ end
12
+
13
+ def get_selected
14
+ @selected.map {|x| x.id}
15
+ end
16
+
17
+ def clear_selected
18
+ @selected.clear
19
+ end
20
+
21
+ def get_names
22
+ [*get_names_v, "last_name_initials", "contact", "git"]
23
+ end
24
+
25
+ def get_data
26
+ table_data = @data.each_with_index.map do |student, index|
27
+ [index + 1] + get_data_v(student)
28
+ end
29
+ Data_table.new(table_data)
30
+ end
31
+
32
+ def data=(data)
33
+ @data=data
34
+ end
35
+
36
+ protected
37
+
38
+ def get_data_v(student)
39
+ raise NotImplementedError
40
+ end
41
+
42
+ def get_names_v
43
+ raise NotImplementedError
44
+ end
45
+ end
46
+
47
+ class Data_list_student_short < Data_list
48
+ private
49
+ def get_names_v
50
+ ["№ по порядку"]
51
+ end
52
+
53
+ def get_data_v(student)
54
+ [
55
+ student.last_name_initials,
56
+ student.contact,
57
+ student.git
58
+ ]
59
+ end
60
+ end
61
+
62
+
63
+
64
+ # students = [
65
+ # StudentShort.new(id: 1, last_name_initials: "K.K.", contact: "kosta2005kes@gmail.com", git: "git2"),
66
+ # StudentShort.new(id: 2, last_name_initials: "L.T.", contact: "krutfortnite@gmail.com", git: "git2"),
67
+ # StudentShort.new(id: 3, last_name_initials: "K.V.", contact: "magasiay@gmail.com", git: "git3")
68
+ # ]
69
+ # list = Data_list_student_short.new(students)
70
+ # list.select(0)
71
+ # list.select(2)
72
+ # table = list.get_data
73
+ # puts table.get(0, 0)
74
+ # puts table.get(1, 1)
75
+ # puts list.get_names
@@ -0,0 +1,18 @@
1
+ require_relative 'data_list'
2
+ require_relative 'student_short'
3
+
4
+ class DataListStudentShort < DataList
5
+
6
+ private
7
+ def column_names
8
+ ["Фамилия И.О.", "Git", "Контакт"]
9
+ end
10
+
11
+ def row_values(student_short)
12
+ [
13
+ student_short.last_name_initials || "",
14
+ student_short.git || "",
15
+ student_short.contact || ""
16
+ ]
17
+ end
18
+ end
data/lib/data_table.rb ADDED
@@ -0,0 +1,17 @@
1
+ class Data_table
2
+ def initialize(data)
3
+ @data=data
4
+ end
5
+
6
+ def get(row_index, col_index)
7
+ @data[row_index][col_index]
8
+ end
9
+
10
+ def row_count
11
+ @data.length
12
+ end
13
+
14
+ def column_count
15
+ @data.first.length
16
+ end
17
+ end
data/lib/student.rb ADDED
@@ -0,0 +1,185 @@
1
+ require_relative 'Base'
2
+ class Student<Base
3
+ REGULAR_PHONE = /\A(\+7|8)?[\s\-\(]?(\d{3})[\s\-\)]?\s*(\d{3})[\s\-]?(\d{2})[\s\-]?(\d{2})\z/
4
+ REGULAR_GIT = /\Ahttps:\/\/(github|gitlab)\.com\/[a-zA-Z0-9_-]+\z/
5
+ REGULAR_NAME = /\A[A-ZА-ЯЁ][a-zа-яё]+\z/
6
+ REGULAR_EMAIL = /\A[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\z/
7
+ REGULAR_TELEGRAM = /\A@[a-zA-Z0-9_]{5,32}\z/
8
+ include Comparable
9
+ attr_reader :first_name, :last_name, :patronymic
10
+ def initialize (last_name:, first_name:, patronymic: nil, id: nil, phone: nil, telegram: nil, email: nil, git: nil)
11
+ self.first_name= first_name
12
+ self.patronymic= patronymic
13
+ self.last_name= last_name
14
+ @id= id
15
+ self.contact= {:phone => phone, :email => email, :telegram => telegram}
16
+ self.git= git
17
+
18
+ end
19
+ def first_name=(value)
20
+ raise ArgumentError, "Неверное имя" unless self.class.valid_name?(value)
21
+ @first_name = value
22
+ end
23
+
24
+ def last_name=(value)
25
+ raise ArgumentError, "Неверная фамилия" unless self.class.valid_name?(value)
26
+ @last_name = value
27
+ end
28
+
29
+ def patronymic=(value)
30
+ raise ArgumentError, "Неверное отчество" unless self.class.valid_name?(value) if !value.nil?
31
+ @patronymic = value
32
+ end
33
+
34
+ def git=(value)
35
+ raise ArgumentError, "Неверный Git" unless self.class.valid_git?(value) if !value.nil?
36
+ @git = value
37
+ end
38
+
39
+ def last_name_initials
40
+ string = "#{@last_name} #{@first_name[0]}."
41
+ if @patronymic != nil
42
+ return string + " #{@patronymic[0]}."
43
+ end
44
+ return string
45
+ end
46
+
47
+
48
+ def contact
49
+ return "telegram - #{@telegram}" if @telegram
50
+ return "email - #{@email}" if @email
51
+ return "phone - #{@phone}" if @phone
52
+ nil
53
+ end
54
+
55
+ def contact=(contacts_hash)
56
+ contacts_hash.each do |type, value|
57
+ case type.to_sym
58
+ when :telegram
59
+ raise ArgumentError, "Неверный Telegram" unless self.class.valid_telegram?(value)
60
+ @telegram = value
61
+ when :email
62
+ raise ArgumentError, "Неверный email" unless self.class.valid_email?(value)
63
+ @email = value
64
+ when :phone
65
+ raise ArgumentError, "Неверный телефон" unless self.class.valid_phone?(value)
66
+ @phone = value
67
+
68
+ end
69
+ end
70
+ end
71
+
72
+ def to_s
73
+ string = "Фамилия: #{@last_name}, Имя: #{@first_name}, Отчество: #{@patronymic.to_s} id: #{@id.to_s}, телефон: #{@phone.to_s}, телеграм: #{@telegram.to_s}, гит: #{@git.to_s}, почта: #{@email.to_s}"
74
+ end
75
+
76
+ def has_contact?
77
+ @email!=nil || @phone!=nil || @telegram!=nil
78
+ end
79
+ def self.valid_git?(git)
80
+ !!(git =~ REGULAR_GIT) || git==nil
81
+ end
82
+
83
+ def self.valid_telegram?(telegram)
84
+ !!(telegram =~ REGULAR_TELEGRAM) || telegram==nil
85
+ end
86
+
87
+ def self.valid_phone?(phone)
88
+ !!(phone =~ REGULAR_PHONE) || phone==nil
89
+ end
90
+
91
+ def self.valid_email?(email)
92
+ !!(email =~ REGULAR_EMAIL) || email==nil
93
+ end
94
+
95
+ def self.valid_name?(name)
96
+ !!(name =~ REGULAR_NAME)
97
+ end
98
+
99
+ def <=>(other)
100
+ last_name_comparison = @last_name <=> other.last_name
101
+ return last_name_comparison unless last_name_comparison == 0
102
+
103
+ first_name_comparison = @first_name <=> other.first_name
104
+ return first_name_comparison unless first_name_comparison == 0
105
+
106
+ @patronymic.to_s <=> other.patronymic.to_s
107
+ end
108
+
109
+
110
+ def ==(other)
111
+ return false unless other.is_a?(Base)
112
+
113
+ contacts_overlap = false
114
+ [@phone, @email, @telegram].each do |contact|
115
+ next if contact.nil? || contact.empty?
116
+ if [other.instance_variable_get(:@phone),
117
+ other.instance_variable_get(:@email),
118
+ other.instance_variable_get(:@telegram)].include?(contact)
119
+ contacts_overlap = true
120
+ break
121
+ end
122
+ end
123
+
124
+ comparison_key == other.comparison_key || contacts_overlap
125
+ end
126
+
127
+ alias eql? ==
128
+
129
+ def hash
130
+ comparison_key.hash
131
+ end
132
+
133
+ def to_hash
134
+ {
135
+ id: @id,
136
+ first_name: @first_name,
137
+ last_name: @last_name,
138
+ patronymic: @patronymic,
139
+ git: @git,
140
+ phone: @phone,
141
+ telegram: @telegram,
142
+ email: @email
143
+ }
144
+ end
145
+
146
+ def to_db_hash
147
+ {
148
+ first_name: @first_name,
149
+ last_name: @last_name,
150
+ patronymic: @patronymic,
151
+ git: @git,
152
+ phone: @phone,
153
+ telegram: @telegram,
154
+ email: @email
155
+ }
156
+ end
157
+
158
+ private
159
+
160
+ def fill_info_parts(info_parts)
161
+ info_parts << "Фамилия: #{last_name}"
162
+ info_parts << "Имя: #{first_name}"
163
+ info_parts << "Отчество: #{patronymic}" if patronymic
164
+ info_parts << "Телефон: #{@phone}" if @phone
165
+ info_parts << "Email: #{@email}" if @email
166
+ info_parts << "Telegram: #{@telegram}" if @telegram
167
+ info_parts << "Git: #{git}" if git
168
+ end
169
+
170
+ def comparison_key
171
+ [last_name, first_name, patronymic].map { |n| n || '' }
172
+ end
173
+ def self.from_hash(hash)
174
+ new(
175
+ id: hash[:id],
176
+ last_name: hash[:last_name],
177
+ first_name: hash[:first_name],
178
+ patronymic: hash[:patronymic],
179
+ git: hash[:git],
180
+ phone: hash[:phone],
181
+ telegram: hash[:telegram],
182
+ email: hash[:email]
183
+ )
184
+ end
185
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'Base'
2
+ class StudentShort<Base
3
+ attr_reader :last_name_initials, :contact
4
+ def initialize (id:, last_name_initials:, contact:nil, git:nil)
5
+ @last_name_initials=last_name_initials
6
+ @id = id
7
+ @contact = contact
8
+ @git = git
9
+ end
10
+
11
+ def self.from_student(student)
12
+ new(id: student.id, last_name_initials: student.last_name_initials, contact: student.contact, git: student.git)
13
+ end
14
+
15
+ def to_s
16
+ string = "id: #{@id.to_s}, ФИО: #{@last_name_initials}, гит: #{@git}, контакт: #{@contact}"
17
+ end
18
+
19
+ def last_name_initials
20
+ @last_name_initials
21
+ end
22
+ def contact
23
+ @contact
24
+ end
25
+
26
+ end
@@ -0,0 +1,3 @@
1
+ module StudentsListYaml
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require_relative "students_list_yaml/version"
5
+ require_relative "student"
6
+ require_relative "student_short"
7
+ require_relative "data_list"
8
+ require_relative "data_table"
9
+ require_relative "base"
10
+
11
+ module StudentsListYaml
12
+ class StudentsList
13
+ attr_reader :file_path
14
+
15
+ def initialize(file_path = nil)
16
+ @students = []
17
+ @file_path = file_path
18
+ load_data if file_path && File.exist?(file_path)
19
+ end
20
+
21
+ def load_data
22
+ return unless @file_path && File.exist?(@file_path)
23
+
24
+ begin
25
+ file_content = File.read(@file_path)
26
+ return if file_content.strip.empty?
27
+
28
+ data = YAML.safe_load(file_content, symbolize_names: true)
29
+ @students = data.map { |student_data| Student.from_hash(student_data) }
30
+ rescue Psych::SyntaxError
31
+ @students = []
32
+ end
33
+ end
34
+
35
+ def save_data
36
+ return unless @file_path
37
+
38
+ students_data = @students.map(&:to_hash)
39
+ File.write(@file_path, students_data.to_yaml)
40
+ end
41
+
42
+ def get_student_by_id(id)
43
+ @students.find { |student| student.id == id }
44
+ end
45
+
46
+ def get_k_n_student_short_list(k, n, existing_data_list = nil)
47
+ start_index = (n - 1) * k
48
+ selected_students = @students[start_index, k] || []
49
+
50
+ short_students = selected_students.map { |student| StudentShort.from_student(student) }
51
+
52
+ if existing_data_list && existing_data_list.is_a?(Data_list)
53
+ existing_data_list.data = short_students
54
+ existing_data_list
55
+ else
56
+ Data_list_student_short.new(short_students)
57
+ end
58
+ end
59
+
60
+ def sort_by_full_name
61
+ @students.sort_by! { |student| student.last_name_initials.downcase }
62
+ end
63
+
64
+ def add_student(student)
65
+ new_id = @students.empty? ? 1 : @students.map(&:id).max + 1
66
+ student_with_id = Student.from_hash(student.to_hash.merge(id: new_id))
67
+ @students << student_with_id
68
+ student_with_id
69
+ end
70
+
71
+ def replace_student_by_id(id, new_student)
72
+ index = @students.find_index { |s| s.id == id }
73
+ return false unless index
74
+
75
+ @students[index] = Student.from_hash(new_student.to_hash.merge(id: id))
76
+ true
77
+ end
78
+
79
+ def delete_student_by_id(id)
80
+ initial_size = @students.size
81
+ @students.reject! { |s| s.id == id }
82
+ initial_size != @students.size
83
+ end
84
+
85
+ def get_student_short_count
86
+ @students.size
87
+ end
88
+
89
+ private
90
+
91
+ attr_writer :students
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: students_list_yaml_Quartz
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kosta717
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: rspec
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '3.12'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '3.12'
26
+ description: Класс для CRUD-операций со студентами и хранением в YAML-файле
27
+ email:
28
+ - kosta2005kes@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - LICENSE.txt
34
+ - README.md
35
+ - lib/Base.rb
36
+ - lib/README.rdoc
37
+ - lib/Rakefile.rb
38
+ - lib/Students_list_JSON.rb
39
+ - lib/data_list.rb
40
+ - lib/data_list_Student_short.rb
41
+ - lib/data_table.rb
42
+ - lib/student.rb
43
+ - lib/student_short.rb
44
+ - lib/students_list_yaml.rb
45
+ - lib/students_list_yaml/version.rb
46
+ homepage: https://github.com/Kosta717/students_list_YAML
47
+ licenses:
48
+ - MIT
49
+ metadata:
50
+ homepage_uri: https://github.com/Kosta717/students_list_YAML
51
+ source_code_uri: https://github.com/Kosta717/students_list_YAML
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '2.5'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubygems_version: 4.0.3
67
+ specification_version: 4
68
+ summary: Управление списком студентов с сохранением в YAML
69
+ test_files: []