feat: add BinarySearchTree class and integrate birth_date handling in Student class LAB 3 TASK 4

lab2
Artem-Darius Weber 2 weeks ago
parent b9ffeb8d0d
commit dbd1dfe45d

@ -0,0 +1,46 @@
class BinarySearchTree
include Enumerable
class Node
attr_accessor :student, :left, :right
def initialize(student)
@student = student
@left = nil
@right = nil
end
end
def initialize
@root = nil
end
def add(student)
@root = insert(@root, student)
end
def each(&block)
in_order_traversal(@root, &block)
end
private
def insert(node, student)
return Node.new(student) if node.nil?
if student.birth_date < node.student.birth_date
node.left = insert(node.left, student)
else
node.right = insert(node.right, student)
end
node
end
def in_order_traversal(node, &block)
return if node.nil?
in_order_traversal(node.left, &block)
yield node.student
in_order_traversal(node.right, &block)
end
end

@ -1,8 +1,10 @@
require 'date'
require_relative 'contact'
require_relative 'person'
require_relative 'student'
require_relative 'student_short'
require_relative 'student_repository'
require_relative 'binary_search_tree'
def test_classes
contact = Contact.new(phone: '+798912465', telegram: '@example_user', email: 'test@example.com')
@ -11,38 +13,34 @@ def test_classes
person = Person.new(id: '1', git: 'https://github.com/example', contact: contact)
puts "Person Contact Info: #{person.contact_info}"
student = Student.new(
id: '2',
git: 'https://github.com/student_example',
contact: contact,
surname: 'Иванов',
name: 'Иван',
patronymic: 'Иванович'
patronymic: 'Иванович',
birth_date: Date.new(2000, 5, 15)
)
puts "Student Full Info: #{student.to_s}"
puts "Student Initials: #{student.surname_and_initials}"
puts "Student Contact Info: #{student.contact_info}"
student_short = StudentShort.from_student(student)
puts "Student Short Info: #{student_short.to_s}"
file_path = 'students.txt'
students = StudentRepository.read_from_txt(file_path)
puts "Read Students from File:"
students.each { |s| puts s.to_s }
output_path = 'output_students.txt'
StudentRepository.write_to_txt(output_path, students)
puts "Students written to file: #{output_path}"
end
def test_parsing
student_string = 'Иванов Иван Иванович | ID: 3 | Phone: +79876543210 | Telegram: @ivan_user | Email: ivan@example.com | Git: https://github.com/ivanov'
student_string = 'Иванов Иван Иванович | ID: 3 | Phone: +79876543210 | Telegram: @ivan_user | Email: ivan@example.com | Git: https://github.com/ivanov | Birth Date: 2001-01-01'
student = Student.from_string(student_string)
puts "Parsed Student: #{student.to_s}"
@ -51,6 +49,34 @@ def test_parsing
puts "Parsed StudentShort: #{student_short.to_s}"
end
def test_binary_search_tree
bst = BinarySearchTree.new
student1 = Student.new(
id: '1',
git: 'https://github.com/student1',
contact: Contact.new(phone: '+123456789', telegram: '@student1', email: 'student1@example.com'),
surname: 'Смирнов',
name: 'Алексей',
patronymic: 'Иванович',
birth_date: Date.new(1999, 2, 15)
)
student2 = Student.new(
id: '2',
git: 'https://github.com/student2',
contact: Contact.new(phone: '+987654321', telegram: '@student2', email: 'student2@example.com'),
surname: 'Иванов',
name: 'Иван',
patronymic: 'Сергеевич',
birth_date: Date.new(2001, 5, 10)
)
bst.add(student1)
bst.add(student2)
puts "Students in BST (sorted by birth_date):"
bst.each { |student| puts student.to_s }
end
if __FILE__ == $0
puts "=== Testing Classes ==="
@ -58,4 +84,7 @@ if __FILE__ == $0
puts "\n=== Testing Parsing ==="
test_parsing
end
puts "\n=== Testing Binary Search Tree ==="
test_binary_search_tree
end

@ -2,22 +2,23 @@ require_relative 'person'
require_relative 'contact'
class Student < Person
attr_accessor :surname, :name, :patronymic
attr_accessor :surname, :name, :patronymic, :birth_date
NAME_REGEX = /\A[А-Яа-яЁёA-Za-z\-]+\z/
def initialize(id:, git:, contact:, surname:, name:, patronymic:)
def initialize(id:, git:, contact:, surname:, name:, patronymic:, birth_date:)
super(id: id, git: git, contact: contact)
@surname = surname
@name = name
@patronymic = patronymic
@birth_date = birth_date
validate_student
end
def self.from_string(student_string)
parts = student_string.split('|').map(&:strip)
raise ArgumentError, 'Invalid student string format' if parts.size < 6
raise ArgumentError, 'Invalid student string format' if parts.size < 7
name_parts = parts[0].split(' ')
raise ArgumentError, 'Invalid name format' if name_parts.size != 3
@ -28,6 +29,7 @@ class Student < Person
telegram = parts[3].split(': ').last
email = parts[4].split(': ').last
git = parts[5].split(': ').last
birth_date = Date.parse(parts[6].split(': ').last)
contact = Contact.new(phone: phone, telegram: telegram, email: email)
@ -37,7 +39,8 @@ class Student < Person
contact: contact,
surname: surname,
name: name,
patronymic: patronymic
patronymic: patronymic,
birth_date: birth_date
)
end
@ -48,11 +51,11 @@ class Student < Person
def to_s
"#{@surname} #{@name} #{@patronymic} | ID: #{@id} | " \
"Phone: #{@contact.phone || 'N/A'} | Telegram: #{@contact.telegram || 'N/A'} | " \
"Email: #{@contact.email || 'N/A'} | Git: #{@git}"
"Email: #{@contact.email || 'N/A'} | Git: #{@git} | Birth Date: #{@birth_date}"
end
def get_info
"#{surname_and_initials}, Git: #{@git}, Contact: #{contact_info}"
"#{surname_and_initials}, Git: #{@git}, Contact: #{contact_info}, Birth Date: #{@birth_date}"
end
private
@ -61,6 +64,7 @@ class Student < Person
raise ArgumentError, 'Surname is required' if @surname.nil? || @surname.strip.empty?
raise ArgumentError, 'Name is required' if @name.nil? || @name.strip.empty?
raise ArgumentError, 'Patronymic is required' if @patronymic.nil? || @patronymic.strip.empty?
raise ArgumentError, 'Birth date is required' if @birth_date.nil?
raise ArgumentError, "Invalid surname format: #{@surname}" unless valid_name?(@surname)
raise ArgumentError, "Invalid name format: #{@name}" unless valid_name?(@name)

Loading…
Cancel
Save