diff --git a/lab1/README.md b/lab1/README.md new file mode 100644 index 0000000..21c405d --- /dev/null +++ b/lab1/README.md @@ -0,0 +1,67 @@ +# 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 new file mode 100644 index 0000000..44080ff --- /dev/null +++ b/lab1/spec/spec_02.rb @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..434b534 --- /dev/null +++ b/lab1/spec/spec_03.rb @@ -0,0 +1,34 @@ +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 new file mode 100644 index 0000000..717d507 --- /dev/null +++ b/lab1/src/01_hello_world.rb @@ -0,0 +1,2 @@ +puts "Hello, world!" + diff --git a/lab1/src/02_user_interface.rb b/lab1/src/02_user_interface.rb new file mode 100644 index 0000000..f68737b --- /dev/null +++ b/lab1/src/02_user_interface.rb @@ -0,0 +1,30 @@ +#!/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 new file mode 100644 index 0000000..3d05635 --- /dev/null +++ b/lab1/src/03_fork_02_with_exec_pasted_command.rb @@ -0,0 +1,39 @@ +#!/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 new file mode 100644 index 0000000..588e2ec --- /dev/null +++ b/lab1/src/04_number_funcs.rb @@ -0,0 +1,67 @@ +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/README.md b/lab2/README.md deleted file mode 100644 index 5ad6678..0000000 --- a/lab2/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Lab 2 - -> "И тут я обнаружил что случайно сделал 3-5 задачи в 1-2" - diff --git a/lab2/main.rb b/lab2/main.rb deleted file mode 100644 index e714667..0000000 --- a/lab2/main.rb +++ /dev/null @@ -1,59 +0,0 @@ -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' - ) - - 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: 'Норакет', - name: 'Норакет', - patronymic: 'Фамилия' - ) - - student2.set_contacts( - phone: '+70000000000' - ) - - puts student1 - puts '-' * 40 - 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 "Ошибка: #{e.message}" -end diff --git a/lab2/person.rb b/lab2/person.rb deleted file mode 100644 index 1dc8f9e..0000000 --- a/lab2/person.rb +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100644 index 57d26a7..0000000 --- a/lab2/student.rb +++ /dev/null @@ -1,92 +0,0 @@ -require_relative 'person' - -class Student < Person - attr_accessor :surname, :name, :patronymic - - def initialize(args = {}) - 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 - - 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 - - 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 - "#{@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 diff --git a/lab2/student_short.rb b/lab2/student_short.rb deleted file mode 100644 index 1bff260..0000000 --- a/lab2/student_short.rb +++ /dev/null @@ -1,31 +0,0 @@ -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