You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kubsu-sm5-ruby/lab2/student.rb

133 lines
4.6 KiB

require_relative 'person'
class Student < Person
attr_accessor :surname, :name, :patronymic
def initialize(args = {})
super(args)
@surname = args.fetch(:surname) { raise ArgumentError, "Surname is required" }
raise ArgumentError, "Invalid surname format: #{@surname}" unless self.class.valid_name?(@surname)
@name = args.fetch(:name) { raise ArgumentError, "Name is required" }
raise ArgumentError, "Invalid name format: #{@name}" unless self.class.valid_name?(@name)
@patronymic = args.fetch(:patronymic) { raise ArgumentError, "Patronymic is required" }
raise ArgumentError, "Invalid patronymic format: #{@patronymic}" unless self.class.valid_name?(@patronymic)
set_contacts(
phone: args[:phone],
telegram: args[:telegram],
email: args[:email]
)
end
def self.from_string(student_string)
raise ArgumentError, "Input string cannot be nil or empty" if student_string.nil? || student_string.strip.empty?
parts = student_string.split('|').map(&:strip)
# Ожидается формат: "Фамилия Имя Отчество | ID: X | Phone: ... | Telegram: ... | Email: ... | Git: ..."
# Проверяем, что частей как минимум 6: ФИО, ID, Phone, Telegram, Email, Git
unless parts.size == 6
raise ArgumentError, "Expected 6 parts separated by '|', got #{parts.size} in '#{student_string}'"
end
fio_part = parts[0]
raise ArgumentError, "FIO part is empty" if fio_part.nil? || fio_part.strip.empty?
fio_elements = fio_part.split(' ')
raise ArgumentError, "Expected Surname Name Patronymic in '#{fio_part}'" unless fio_elements.size == 3
surname, name, patronymic = fio_elements
id_part = parts[1]
raise ArgumentError, "ID part is empty or invalid" if id_part.nil? || !id_part.include?('ID:')
id_str = id_part.split(': ').last
raise ArgumentError, "ID value is missing in '#{id_part}'" if id_str.nil? || id_str.strip.empty?
id = id_str.to_i
raise ArgumentError, "ID must be a valid integer: '#{id_str}'" if id == 0 && id_str != "0"
phone_part = parts[2]
raise ArgumentError, "Phone part is invalid or missing" if phone_part.nil? || !phone_part.include?('Phone:')
phone = phone_part.split(': ').last
phone = nil if phone == 'N/A'
telegram_part = parts[3]
raise ArgumentError, "Telegram part is invalid or missing" if telegram_part.nil? || !telegram_part.include?('Telegram:')
telegram = telegram_part.split(': ').last
telegram = nil if telegram == 'N/A'
email_part = parts[4]
raise ArgumentError, "Email part is invalid or missing" if email_part.nil? || !email_part.include?('Email:')
email = email_part.split(': ').last
email = nil if email == 'N/A'
git_part = parts[5]
raise ArgumentError, "Git part is invalid or missing" if git_part.nil? || !git_part.include?('Git:')
git = git_part.split(': ').last
git = nil if git == 'N/A'
new(
surname: surname,
name: name,
patronymic: patronymic,
id: id,
phone: phone,
telegram: telegram,
email: email,
git: git
)
end
def self.read_from_txt(file_path)
raise IOError, "File path is invalid or file does not exist: #{file_path}" unless File.exist?(file_path)
students = []
File.foreach(file_path) do |line|
line.strip!
next if line.empty?
begin
student = from_string(line)
students << student
rescue ArgumentError => e
puts "Error processing line: '#{line}'. Reason: #{e.message}"
rescue StandardError => e
puts "An unexpected error occurred while processing line: '#{line}'. Reason: #{e.message}"
end
end
students
end
def self.write_to_txt(file_path, students)
raise ArgumentError, "Expected an array of Student objects" unless students.is_a?(Array) && students.all? { |s| s.is_a?(Student) }
File.open(file_path, 'w') do |file|
students.each do |student|
file.puts student.to_s
end
end
puts "Data successfully written to #{file_path}"
rescue IOError => e
puts "An error occurred while writing to the file: #{e.message}"
rescue StandardError => e
puts "An unexpected error occurred while writing to the file: #{e.message}"
end
def surname_and_initials
"#{@surname} #{name[0]}.#{patronymic[0]}."
end
def to_s
"#{@surname} #{@name} #{@patronymic} | ID: #{@id || 'N/A'} | " \
"Phone: #{@phone || 'N/A'} | Telegram: #{@telegram || 'N/A'} | " \
"Email: #{@email || 'N/A'} | Git: #{@git || 'N/A'}"
end
def get_info
"#{surname_and_initials}, Git: #{git_info}, Contact: #{contact_info}"
end
end