Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Реализовать MergeBU #46

Open
be9 opened this issue Jun 8, 2017 · 7 comments
Open

Реализовать MergeBU #46

be9 opened this issue Jun 8, 2017 · 7 comments
Assignees

Comments

@be9
Copy link
Collaborator

be9 commented Jun 8, 2017

Cтр. 278.

Сделать одну версию с необязательным блоком (аналогично shell_sort2!). Можно реализовать их в одном модуле с #45 и использовать наследование или include для классов тестов, чтобы избежать дублирования.

@be9 be9 added this to the Раздел 2.2 milestone Jun 8, 2017
@be9 be9 assigned v26 Jun 8, 2017
@v26
Copy link
Owner

v26 commented Jan 31, 2018

@be9 Здесь не совсем понял как реализовать. В одном файле merge_sort.rb будет и обычный merge_sort и BU, и два тестовых файла (один от другого наследуется, напр.). Тогда надо тестируемый метод как аргумент передавать в тест? (соответственно, тест под это дело подогнать)

@be9
Copy link
Collaborator Author

be9 commented Feb 7, 2018

В тест можно передавать блок, который будет вызывать нужную функцию (просто функцию в Ruby передать нельзя, т.е. можно, но так не делают)

Другой вариант: делается два TestCase, наследующиеся от одного класса, и у каждого создается метод sort, который в одном случае будет вызывать одну функцию, а в другом — другую.

Второй вариант даже проще.

@v26
Copy link
Owner

v26 commented Mar 17, 2018

@be9 Возникла проблема. Хочу реализовать второй вариант (просто чтобы знать хотя бы, как делается, для себя; первый тоже потом реализую).
Вот как сделал:

merge_sort_test.rb

require_relative 'sort_test'
require_relative '../../lib/2_2_merge_sort/merge_sort'

class MergeSortTest < SortTest
  def sort!(a, &block)
    merge_sort!(a, &block)
  end
end

sort_test.rb

require 'minitest/autorun'

class SortTest < Minitest::Test
  def setup
    @unsorted_ary = [5,3,2,1,4,9,6,8,7]
    @sorted_ary = [1,2,3,4,5,6,7,8,9].freeze
    @unsorted_hash = [['Vasya', 1], ['Petya', 3], ['Kolya', 2]]
    @sorted_hash = [['Petya', 3], ['Kolya', 2], ['Vasya', 1]].freeze
  end                                                       
  # Testing #sorted?
  def test_sorted
    assert sorted?(@sorted_ary), "Should be sorted"
  end

  def test_not_sorted
    assert !sorted?(@unsorted_ary), "Shouldn't be sorted"
  end

  # Testing #sort!
  def sort!
    raise NotImplementedError, "To be implemented in child class"
  end

  def test_sort_like_without_block                                
    assert_equal @sorted_ary, sort!(@unsorted_ary) { |x| x }, "Array hasn't been sorted"
  end                                                       

  def test_sort_like_without_block_with_rand_ary
    rand_ary_1 = (0...100).to_a.shuffle                         
    rand_ary_2 = rand_ary_1.dup                                 
    assert_equal rand_ary_1.sort, sort!(rand_ary_2) { |x| x }, "Array hasn't been sorted properly"
  end
  
  def test_sort_with_block
    sort!(@unsorted_hash) { |item| -item[1] }
    assert_equal @sorted_hash, @unsorted_hash, "Array hasn't been sorted"
  end

  def test_sort_with_block_with_rand_ary                        
    permutation = (0...100).to_a.shuffle                       
    pairs = (0...permutation.size).map { |i| [i, permutation[i]] }
    pairs_copy = pairs.dup
    pairs.sort_by! { |item| -item[1] }                         
    sort!(pairs_copy) { |item| -item[1] }
    assert_equal pairs, pairs_copy, "Array hasn't been sorted properly"
  end
end

При запуске файла merge_sort_test.rb выдает ошибку ArgumentError в sort!, given 1, expected 0.
То есть, используется метод sort! из класса родителя.
Я прочел, что в ruby нет, как таковых, интерфейсов. Но прежде чем пробовать вариант с примесями, хотел бы реализовать, все-таки, и через наследование.

Что я делаю не так?

П.С. знаю, что определять sort! в классе родителе необязательно - он выдаст просто NoMethodError, но сути дела это не меняет, как я понял.

П.П.С. Копировать с мобильного ssh клиента трудно. Возможны мелкие синтаксические ошибки.

@v26
Copy link
Owner

v26 commented Mar 18, 2018

@be9 Update: с отсутствием абстракных классов погорячился...

  • с помощью include сделал, но все же хочу разобраться с вариантом с наследованием.

@be9
Copy link
Collaborator Author

be9 commented Mar 24, 2018

Проблема тут в том, что в базовом классе ты объявил метод без аргументов, а в классе-наследнике аргументы добавил. В базовом классе стоило бы написать так:

def sort!(ary)
  raise NotImplementedError, "To be implemented in child class"
end

или даже

def sort!(*)
  raise NotImplementedError, "To be implemented in child class"
end

Последняя версия позволяет принимать любое количество аргументов.

@v26
Copy link
Owner

v26 commented Mar 24, 2018

@be9 Так тоже не работает. Вы уверены, что так можно сделать? (Где-то прочел, что minitest запускает файлы только унаследованные непосредственно от Minitest::Test). Может, в этом дело?

@be9
Copy link
Collaborator Author

be9 commented Mar 24, 2018

Проблема в том, что твой SortTest тоже запускается на проверку, ибо содержит методы test_*. Т.е. идея с «абстрактным» базовым классом, увы, не прокатит. Это уже я погорячился со своим предложением.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants