diff --git a/lab1/README.md b/lab1/README.md deleted file mode 100644 index 21c405d..0000000 --- a/lab1/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Lab 1 - ---- - -## 01. Hello world - -Task: - -Установить компилятор и текстовый редактор. Реализовать и -вызвать Hello World c комментарием. (ну как всегда) - -```bash -ruby 01_hello_world.rb -``` - -Returns: - -``` -Hello, world! -``` - -## 02. User interface - -Task: - -Принять имя пользователя как аргумент программы. -Поздороваться с пользователем с использованием форматирования -строки. Спросить какой язык у пользователя любимый, в случае, если это -ruby, ответить что пользователь подлиза, иначе обязательно ответить, что -скоро будет ruby и поставить различные комментарии для нескольких -языков. - -```bash -ruby 02_user_interface.rb darius -``` - -## 03. User interface with ruby and os commands execution - -Task: - -3.Продолжение предыдущего задания. Попросить пользователя -ввести команду языка ruby. И команду OC. Выполнить команду руби и -команду операционной системы. - -```bash -ruby 03_fork_02_with_exec_pasted_command.rb darius -``` - -## 04. Number funcations - -Task: - -«Работа с числами». Составить 3 метода для работы с цифрами или делителей числа на основании варианта. Каждый метод отдельный коммит. - -- Метод 1. Найти количество четных чисел, не взаимно простых с данным -- Метод 2. Найти максимальную цифры числа, не делящуюся на 3. -- Метод 3. Найти произведение максимального числа, не взаимно простого с данным, не делящегося на наименьший делитель исходно числа, и суммы цифр числа, меньших 5. - -```bash -ruby 04_number_funcs.rb -``` - ---- - -Author: Artem-Darius Weber - -Licence: MIT \ No newline at end of file diff --git a/lab1/spec/spec_02.rb b/lab1/spec/spec_02.rb deleted file mode 100644 index 44080ff..0000000 --- a/lab1/spec/spec_02.rb +++ /dev/null @@ -1,16 +0,0 @@ -require_relative '../src/02_user_interface.rb' - -RSpec.describe "Main" do - before do - allow(STDIN).to receive(:gets).and_return("ruby\n") - end - - it "greets the user and checks Ruby as language" do - expect { main() }.to output("Hello my catgirl test_user! \nWhat is your love language?\nruby\nc++\npy\nПодлиза \n").to_stdout - end - - it "handles unknown language input" do - allow(STDIN).to receive(:gets).and_return("java\n") - expect { main() }.to output(/Неизвестный язык: java/).to_stdout - end -end \ No newline at end of file diff --git a/lab1/spec/spec_03.rb b/lab1/spec/spec_03.rb deleted file mode 100644 index 434b534..0000000 --- a/lab1/spec/spec_03.rb +++ /dev/null @@ -1,34 +0,0 @@ -require_relative '../src/03_fork_02_with_exec_pasted_command.rb' - -RSpec.describe "Main" do - before do - allow(STDIN).to receive(:gets).and_return("ruby\n", "puts 'Hello from Ruby!'\n", "echo 'Hello from shell!'\n") - allow(ARGV).to receive(:[]).with(0).and_return("test_user") - end - - it "greets the user and processes ruby input" do - expect { main() }.to output(/Hello my catgirl test_user! \nWhat is your love language?\nruby\nc++\npy\nПодлиза \n/).to_stdout - end - - it "executes valid ruby command" do - allow(STDIN).to receive(:gets).and_return("ruby\n", "puts 'Hello from Ruby!'\n") - - expect { main() }.to output(/Hello from Ruby!/).to_stdout - end - - it "handles ruby command execution error" do - allow(STDIN).to receive(:gets).and_return("ruby\n", "invalid_ruby_code\n") - - expect { main() }.to output(/Ошибка выполнения команды Ruby: undefined local variable or method `invalid_ruby_code'/).to_stdout - end - - it "executes shell command" do - allow(STDIN).to receive(:gets).and_return("ruby\n", "puts 'Hello from Ruby!'\n", "echo 'Hello from shell!'\n") - expect(main()).to include("Hello from shell!") - end - - it "returns correct output for unknown programming language" do - allow(STDIN).to receive(:gets).and_return("java\n") - expect { main() }.to output(/Неизвестный язык: java/).to_stdout - end -end diff --git a/lab1/src/01_hello_world.rb b/lab1/src/01_hello_world.rb deleted file mode 100644 index 717d507..0000000 --- a/lab1/src/01_hello_world.rb +++ /dev/null @@ -1,2 +0,0 @@ -puts "Hello, world!" - diff --git a/lab1/src/02_user_interface.rb b/lab1/src/02_user_interface.rb deleted file mode 100644 index f68737b..0000000 --- a/lab1/src/02_user_interface.rb +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env ruby - -LANGUAGES = [ - "ruby", - "c++", - "py" -] - -def main() - user_name = ARGV[0] - puts "Hello my catgirl #{user_name}! \nWhat is your love language?" - LANGUAGES.each { |language| puts "#{language}", " " } - - user_lang = STDIN.gets.chomp - - case user_lang - when "ruby" - puts "Подлиза \n" - when "c++" - puts "MATLAB скушал? \n" - when "TS/JS" - puts "Фронтендер, Фууу! \n" - when "py" - puts "Девопсер, иди ДАГИ писать \n" - else - puts "Неизвестный язык: #{user_lang}" - end -end - -main() diff --git a/lab1/src/03_fork_02_with_exec_pasted_command.rb b/lab1/src/03_fork_02_with_exec_pasted_command.rb deleted file mode 100644 index 3d05635..0000000 --- a/lab1/src/03_fork_02_with_exec_pasted_command.rb +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env ruby - -LANGUAGES = [ - "ruby", - "c++", - "py" -] - -def main() - user_name = ARGV[0] - puts "Hello my catgirl #{user_name}! \nWhat is your love language?" - LANGUAGES.each { |language| puts "#{language}", " " } - - user_lang = STDIN.gets.chomp - case user_lang - when "ruby" - puts "Подлиза \n" - when "c++" - puts "MATLAB скушал? \n" - when "TS/JS" - puts "Фронтендер, Фууу! \n" - when "py" - puts "Девопсер, иди ДАГИ писать \n" - end - - puts "Введите команду на языке Ruby для выполнения:" - ruby_command = STDIN.gets.chomp - begin - eval(ruby_command) - rescue Exception => e - puts "Ошибка выполнения команды Ruby: #{e.message}" - end - - puts "Введите команду операционной системы для выполнения:" - os_command = STDIN.gets.chomp - system(os_command) -end - -main() diff --git a/lab1/src/04_number_funcs.rb b/lab1/src/04_number_funcs.rb deleted file mode 100644 index 588e2ec..0000000 --- a/lab1/src/04_number_funcs.rb +++ /dev/null @@ -1,67 +0,0 @@ -require 'prime' - - - - -# @param n [Integer] Число, для которого нужно найти количество четных, не взаимно простых чисел. -# @return [Integer] Количество четных чисел, не взаимно простых с данным числом. -# @example -# count_even_non_coprimes(30) # => 14 -def count_even_non_coprimes(n) - (1...n).count do |num| - num.even? && n.gcd(num) != 1 - end -end - - -# @param n [Integer] Число, цифры которого нужно проверить. -# @return [Integer, nil] Максимальная цифра числа, не делящаяся на 3, или nil, если таких цифр нет. -# @example -# max_digit_not_divisible_by_three(483726) # => 8 -def max_digit_not_divisible_by_three(n) - n.digits.select { |digit| digit % 3 != 0 }.max -end - - -# @param n [Integer] Число, для которого нужно найти наименьший делитель. -# @return [Integer] Наименьший делитель числа. -# @example -# smallest_divisor(30) # => 2 -def smallest_divisor(n) - (2..n).find { |i| n % i == 0 } -end - - -# @param n [Integer] Число, для которого нужно найти подходящее максимальное число. -# @return [Integer, nil] Максимальное число, не взаимно простое с данным, не делящееся на наименьший делитель, или nil, если таких чисел нет. -# @example -# max_non_coprime_not_divisible_by_smallest_divisor(30) # => 28 -def max_non_coprime_not_divisible_by_smallest_divisor(n) - divisor = smallest_divisor(n) - (1...n).select { |num| n.gcd(num) != 1 && num % divisor != 0 }.max -end - - -# @param n [Integer] Число, цифры которого нужно просуммировать. -# @return [Integer] Сумма цифр числа, меньших 5. -# @example -# sum_of_digits_less_than_five(483726) # => 9 -def sum_of_digits_less_than_five(n) - n.digits.select { |digit| digit < 5 }.sum -end - - -# @param n [Integer] Число, для которого проводится вычисление. -# @return [Integer] Произведение максимального числа и суммы цифр числа. -# @example -# product_of_max_and_sum(30) # => 252 -def product_of_max_and_sum(n) - max_number = max_non_coprime_not_divisible_by_smallest_divisor(n) - sum_digits = sum_of_digits_less_than_five(n) - max_number * sum_digits -end - - -puts count_even_non_coprimes(30) # => 14 -puts max_digit_not_divisible_by_three(483726) # => 8 -puts product_of_max_and_sum(30) # => 252 diff --git a/lab2/main.rb b/lab2/main.rb index b426934..e714667 100644 --- a/lab2/main.rb +++ b/lab2/main.rb @@ -1,27 +1,59 @@ require_relative 'student' +require_relative 'student_short' begin + student_string = "Норакет Норакет Норакет | ID: 2 | Phone: +1234567890 | Telegram: @noracat | Email: nora@example.com | Git: https://github.com/nora" + student_from_string = Student.from_string(student_string) + puts "Создан объект из строки:\n#{student_from_string}" + + student1 = Student.new( surname: 'Алексеевич', name: 'Артем-Дариус', patronymic: 'Вебер', id: 1, + git: 'https://github.com/space-creator' + ) + + student1.set_contacts( phone: '+79891242223', telegram: '@alstroemeria22', - email: 'no-replay@djft.ru', - git: 'https://git.djft.ru' + email: 'no-replay@djft.ru' ) + puts student1.get_info + puts "Surname and Initials: #{student1.surname_and_initials}" + puts "Git Info: #{student1.git_info}" + puts "Contact Info: #{student1.contact_info}" + student2 = Student.new( - surname: 'nil', + surname: 'Норакет', name: 'Норакет', - patronymic: 'nil' + patronymic: 'Фамилия' + ) + + student2.set_contacts( + phone: '+70000000000' ) puts student1 puts '-' * 40 - puts student2 + puts student2 + + + student_short_from_student = StudentShort.new(student1) + puts "StudentShort from Student object:" + puts "ID: #{student_short_from_student.id}" + puts "Surname and Initials: #{student_short_from_student.surname_initials}" + puts "Git: #{student_short_from_student.git}" + puts "Contact: #{student_short_from_student.contact}" + + student_short_from_string = StudentShort.from_string(5, 'Skye A.A., Git: https://github.com/skye, Contact: Phone: +4923467890') + puts "StudentShort from string:" + puts "ID: #{student_short_from_string.id}" + puts "Surname and Initials: #{student_short_from_string.surname_initials}" + puts "Git: #{student_short_from_string.git}" + puts "Contact: #{student_short_from_string.contact}" rescue ArgumentError => e - puts "Err.: #{e.message}" + puts "Ошибка: #{e.message}" end - diff --git a/lab2/person.rb b/lab2/person.rb new file mode 100644 index 0000000..1dc8f9e --- /dev/null +++ b/lab2/person.rb @@ -0,0 +1,65 @@ +class Person + attr_accessor :id, :git + + def initialize(args = {}) + @id = args[:id] || nil + @git = args[:git] + validate + end + + def set_contacts(phone: nil, telegram: nil, email: nil) + @phone = phone + raise ArgumentError, "Invalid phone number format: #{@phone}" if @phone && !self.class.valid_phone_number?(@phone) + + @telegram = telegram + raise ArgumentError, "Invalid telegram format: #{@telegram}" if @telegram && !self.class.valid_telegram?(@telegram) + + @email = email + raise ArgumentError, "Invalid email format: #{@email}" if @email && !self.class.valid_email?(@email) + end + + def self.valid_phone_number?(phone) + phone.match?(/\A\+?[0-9]{10,15}\z/) + end + + def self.valid_name?(name) + name.match?(/\A[А-Яа-яЁёA-Za-z\-]+\z/) + end + + def self.valid_telegram?(telegram) + telegram.nil? || telegram.match?(/\A@[A-Za-z0-9_]{5,32}\z/) + end + + def self.valid_email?(email) + email.nil? || email.match?(/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/) + end + + def self.valid_git?(git) + git.nil? || git.match?(/\Ahttps:\/\/github\.com\/[A-Za-z0-9_\-]+\z/) + end + + def git_present? + !@git.nil? && !@git.empty? + end + + def contact_present? + !(@phone.nil? || @phone.empty?) || !(@telegram.nil? || @telegram.empty?) || !(@email.nil? || @email.empty?) + end + + def validate + raise ArgumentError, "Git link is required" unless git_present? + raise ArgumentError, "At least one contact (phone, telegram, or email) is required" unless contact_present? + end + + def contact_info + return "Phone: #{@phone}" if @phone + return "Telegram: #{@telegram}" if @telegram + return "Email: #{@email}" if @email + 'No contact available' + end + + private + + attr_reader :phone, :telegram, :email + attr_writer :phone, :telegram, :email +end \ No newline at end of file diff --git a/lab2/student.rb b/lab2/student.rb index 14f5464..57d26a7 100644 --- a/lab2/student.rb +++ b/lab2/student.rb @@ -1,33 +1,92 @@ -class Student - attr_accessor :id, :surname, :name, :patronymic, :phone, :telegram, :email, :git - - def self.valid_phone_number?(phone) - phone.match?(/\A\+?[0-9]{10,15}\z/) - end +require_relative 'person' +class Student < Person + attr_accessor :surname, :name, :patronymic + def initialize(args = {}) - @surname = args.fetch(:surname) - @name = args.fetch(:name) - @patronymic = args.fetch(:patronymic) - - @id = args[:id] || nil + super(args) + @surname = args.fetch(:surname) + raise ArgumentError, "Invalid surname format: #{@surname}" unless self.class.valid_name?(@surname) + + @name = args.fetch(:name) + raise ArgumentError, "Invalid name format: #{@name}" unless self.class.valid_name?(@name) + + @patronymic = args.fetch(:patronymic) + 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) + parts = student_string.split('|').map(&:strip) + surname, name, patronymic = parts[0].split(' ') + id = parts[1].split(': ').last.to_i + phone = parts[2].split(': ').last + telegram = parts[3].split(': ').last + email = parts[4].split(': ').last + git = parts[5].split(': ').last + + new( + surname: surname, + name: name, + patronymic: patronymic, + id: id, + phone: phone, + telegram: telegram, + email: email, + git: git + ) + end - @phone = args[:phone] - if @phone && !Student.valid_phone_number?(@phone) - raise ArgumentError, "Invalid phone number format: #{@phone}" + 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}" + end end - - @telegram = args[:telegram] || nil - @email = args[:email] || nil - @git = args[:git] || nil + + 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}" + end + + def surname_and_initials + "#{@surname} #{name[0]}.#{patronymic[0]}." + end + def to_s - "Student: #{@surname} #{@name} #{@patronymic}\n" \ - "ID: #{@id || 'N/A'}\n" \ - "Phone: #{@phone || 'N/A'}\n" \ - "Telegram: #{@telegram || 'N/A'}\n" \ - "Email: #{@email || 'N/A'}\n" \ - "Git: #{@git || 'N/A'}" + "#{@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 \ No newline at end of file +end \ No newline at end of file diff --git a/lab2/student_short.rb b/lab2/student_short.rb new file mode 100644 index 0000000..1bff260 --- /dev/null +++ b/lab2/student_short.rb @@ -0,0 +1,31 @@ +require_relative 'person' + +class StudentShort < Person + attr_reader :surname_initials, :contact + + def initialize(student) + super(id: student.id, git: student.git_info) + @surname_initials = student.surname_and_initials + @contact = student.contact_info + end + + def self.from_string(id, info_string) + parts = info_string.split(', ').map(&:strip) + surname_initials = parts[0] + git = parts[1].split(': ').last + contact = parts[2].split(': ').last + + new_instance = allocate + new_instance.send(:initialize_from_data, id, surname_initials, git, contact) + new_instance + end + + private + + def initialize_from_data(id, surname_initials, git, contact) + @id = id + @surname_initials = surname_initials + @git = git + @contact = contact + end +end \ No newline at end of file