- Коректно
- 8 успешни тест(а)
- 0 неуспешни тест(а)
........ Finished in 0.0099 seconds 8 examples, 0 failures
Срокът за предаване на решения е отминал
Изберете си число между 1 и 10. Умножете това число по 2. Умножете полученото по 5. Разделете новия резултат на числото, което бяхте избрали първоначално. Извадете 7 от новия резултат.
Абракадабра!
Получихте 3, нали?
Всички сме чували/представяли такива трикове, дори сме бивали дълбоко впечатлявани от тях, когато сме били невръстни. Разбира се, тестването на достоверността на тези трикове би било по-лесно, ако се напише малко код. Един изключително полезен съвет от книгата "The Pragmatic Programmer: From Journeyman to Master" e:
Да опитаме.
Искаме да създадем мини-език, a.k.a. DSL в който „операторите“ са манипулациите с числа, близки до естествения език, с който бихме описали трика. Например, трикът, който представихме в началото, може да бъде записан и проверен по следния начин:
Charlatan.trick do
pick_from 1..10
multiply_by 2
multiply_by 5
divide_by :your_number
subtract 7
you_should_get 3
end
За целите на това предизвикателство, ще приемем, че горният код е по-четим заради близостта си до "проблемната област" (domain), от този:
(1..10).all? do |number|
((number * 2 * 5) / number) - 7 == 3
end
Затова, създайте модул Charlatan, в който има метод Charlatan.trick, приемащ
блок, който дефинира „проверяваща програма“ от следния вид:
pick_from <range> – задава интервал от цели числа, за които ще тестваме
дали трикът работи. Приема само области от числа.add <number> – добавя число към текущия резултат.subtract <number> – изважда число от текущия резултат.multiply_by <number> – умножава текущия резултат по число.divide_by <number> – Разделя (целочислено) текущия резултат на число.you_should_get <number> – последният ред на програмата указва числото,
което трябва да бъде „разпознато“ от шарлатана в края на трика.Вместо число, на всички операции без pick_from, може да се подаде символът
:your_number, който трябва да представлява стойността на първоначално
избраното число.
Изпълнението на Charlatan.trick трябва да връща true, или false, в
зависимост от това дали манипулациите върху всяко число от областта са довели
до числото, подадено като аргумент на you_should_get.
Примери:
Charlatan.trick do
pick_from 1..1
add 1
you_should_get 2
end # => true
Charlatan.trick do
pick_from 1..2
add 2
subtract 2
you_should_get :your_number
end # => true
Charlatan.trick do
pick_from 10..100
multiply_by 3
you_should_get 1000
end # => false
Забележка: Подадените на Charlatan.trick програми ще бъдат коректни,
всички ще започват с pick_from и ще завършват с you_should_get. Също така,
няма да се подават некоректни данни, както сме казвали много пъти досега.
Ако изпитвате затруднения да измислите как да реализирате този DSL, питайте във форума или ни пишете.
........ Finished in 0.0099 seconds 8 examples, 0 failures
........ Finished in 0.00994 seconds 8 examples, 0 failures
........ Finished in 0.01418 seconds 8 examples, 0 failures
........ Finished in 0.01136 seconds 8 examples, 0 failures
true .true .true .true .true .true .true .true false . Finished in 0.01011 seconds 8 examples, 0 failures
........ Finished in 0.01128 seconds 8 examples, 0 failures
........ Finished in 0.0101 seconds 8 examples, 0 failures
........ Finished in 0.0097 seconds 8 examples, 0 failures
........ Finished in 0.00983 seconds 8 examples, 0 failures
........ Finished in 0.01819 seconds 8 examples, 0 failures
true
.true
.true
.true
.true
.Ftrue
.F
Failures:
1) Charlatan allows :your_number as an argument to arithmetic methods
Failure/Error: you_should_get 0
TypeError:
:your_number can't be coerced into Fixnum
# /tmp/d20140105-32545-2su3w4/solution.rb:46:in `-'
# /tmp/d20140105-32545-2su3w4/solution.rb:46:in `execute_action'
# /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block (2 levels) in you_should_get'
# /tmp/d20140105-32545-2su3w4/solution.rb:56:in `each'
# /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block in you_should_get'
# /tmp/d20140105-32545-2su3w4/solution.rb:54:in `each'
# /tmp/d20140105-32545-2su3w4/solution.rb:54:in `you_should_get'
# /tmp/d20140105-32545-2su3w4/spec.rb:45:in `block (3 levels) in <top (required)>'
# /tmp/d20140105-32545-2su3w4/solution.rb:4:in `instance_eval'
# /tmp/d20140105-32545-2su3w4/solution.rb:4:in `trick'
# /tmp/d20140105-32545-2su3w4/spec.rb:42:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
2) Charlatan actually performs calculations
Failure/Error: you_should_get 3
TypeError:
:your_number can't be coerced into Fixnum
# /tmp/d20140105-32545-2su3w4/solution.rb:50:in `/'
# /tmp/d20140105-32545-2su3w4/solution.rb:50:in `execute_action'
# /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block (2 levels) in you_should_get'
# /tmp/d20140105-32545-2su3w4/solution.rb:56:in `each'
# /tmp/d20140105-32545-2su3w4/solution.rb:56:in `block in you_should_get'
# /tmp/d20140105-32545-2su3w4/solution.rb:54:in `each'
# /tmp/d20140105-32545-2su3w4/solution.rb:54:in `you_should_get'
# /tmp/d20140105-32545-2su3w4/spec.rb:63:in `block (3 levels) in <top (required)>'
# /tmp/d20140105-32545-2su3w4/solution.rb:4:in `instance_eval'
# /tmp/d20140105-32545-2su3w4/solution.rb:4:in `trick'
# /tmp/d20140105-32545-2su3w4/spec.rb:57:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.01031 seconds
8 examples, 2 failures
Failed examples:
rspec /tmp/d20140105-32545-2su3w4/spec.rb:41 # Charlatan allows :your_number as an argument to arithmetic methods
rspec /tmp/d20140105-32545-2su3w4/spec.rb:56 # Charlatan actually performs calculations
........ Finished in 0.0096 seconds 8 examples, 0 failures
........ Finished in 0.01239 seconds 8 examples, 0 failures
........ Finished in 0.01115 seconds 8 examples, 0 failures
........ Finished in 0.00961 seconds 8 examples, 0 failures
........ Finished in 0.00983 seconds 8 examples, 0 failures
........ Finished in 0.01043 seconds 8 examples, 0 failures
........ Finished in 0.01014 seconds 8 examples, 0 failures
........ Finished in 0.00972 seconds 8 examples, 0 failures
....F..F
Failures:
1) Charlatan performs division
Failure/Error: divide_by 2
NoMethodError:
undefined method `divide_by' for Charlatan:Module
# /tmp/d20140105-32545-qao338/spec.rb:36:in `block (3 levels) in <top (required)>'
# /tmp/d20140105-32545-qao338/solution.rb:5:in `instance_eval'
# /tmp/d20140105-32545-qao338/solution.rb:5:in `trick'
# /tmp/d20140105-32545-qao338/spec.rb:34:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
2) Charlatan actually performs calculations
Failure/Error: divide_by :your_number
NoMethodError:
undefined method `divide_by' for Charlatan:Module
# /tmp/d20140105-32545-qao338/spec.rb:61:in `block (3 levels) in <top (required)>'
# /tmp/d20140105-32545-qao338/solution.rb:5:in `instance_eval'
# /tmp/d20140105-32545-qao338/solution.rb:5:in `trick'
# /tmp/d20140105-32545-qao338/spec.rb:57:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00986 seconds
8 examples, 2 failures
Failed examples:
rspec /tmp/d20140105-32545-qao338/spec.rb:33 # Charlatan performs division
rspec /tmp/d20140105-32545-qao338/spec.rb:56 # Charlatan actually performs calculations
........ Finished in 0.00973 seconds 8 examples, 0 failures
........ Finished in 0.00969 seconds 8 examples, 0 failures
........ Finished in 0.01017 seconds 8 examples, 0 failures
........ Finished in 0.0105 seconds 8 examples, 0 failures
F.....F.
Failures:
1) Charlatan works without operations
Failure/Error: you_should_get 1
NoMethodError:
undefined method `all?' for nil:NilClass
# /tmp/d20140105-32545-1j4yxtb/solution.rb:37:in `you_should_get'
# /tmp/d20140105-32545-1j4yxtb/spec.rb:5:in `block (3 levels) in <top (required)>'
# /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `instance_eval'
# /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `execute'
# /tmp/d20140105-32545-1j4yxtb/solution.rb:55:in `trick'
# /tmp/d20140105-32545-1j4yxtb/spec.rb:3:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
2) Charlatan accepts :your_number as an argument to you_should_get
Failure/Error: you_should_get :your_number
NoMethodError:
undefined method `first' for nil:NilClass
# /tmp/d20140105-32545-1j4yxtb/solution.rb:35:in `you_should_get'
# /tmp/d20140105-32545-1j4yxtb/spec.rb:52:in `block (3 levels) in <top (required)>'
# /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `instance_eval'
# /tmp/d20140105-32545-1j4yxtb/solution.rb:9:in `execute'
# /tmp/d20140105-32545-1j4yxtb/solution.rb:55:in `trick'
# /tmp/d20140105-32545-1j4yxtb/spec.rb:50:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00997 seconds
8 examples, 2 failures
Failed examples:
rspec /tmp/d20140105-32545-1j4yxtb/spec.rb:2 # Charlatan works without operations
rspec /tmp/d20140105-32545-1j4yxtb/spec.rb:49 # Charlatan accepts :your_number as an argument to you_should_get
........ Finished in 0.00962 seconds 8 examples, 0 failures
FFFFF...
Failures:
1) Charlatan works without operations
Failure/Error: Charlatan.trick do
expected: true value
got: false
# /tmp/d20140105-32545-158er48/spec.rb:3:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
2) Charlatan performs addition
Failure/Error: Charlatan.trick do
expected: true value
got: false
# /tmp/d20140105-32545-158er48/spec.rb:10:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
3) Charlatan performs substraction
Failure/Error: Charlatan.trick do
expected: true value
got: false
# /tmp/d20140105-32545-158er48/spec.rb:18:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
4) Charlatan performs multiplication
Failure/Error: Charlatan.trick do
expected: true value
got: false
# /tmp/d20140105-32545-158er48/spec.rb:26:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
5) Charlatan performs division
Failure/Error: Charlatan.trick do
expected: true value
got: false
# /tmp/d20140105-32545-158er48/spec.rb:34:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.01026 seconds
8 examples, 5 failures
Failed examples:
rspec /tmp/d20140105-32545-158er48/spec.rb:2 # Charlatan works without operations
rspec /tmp/d20140105-32545-158er48/spec.rb:9 # Charlatan performs addition
rspec /tmp/d20140105-32545-158er48/spec.rb:17 # Charlatan performs substraction
rspec /tmp/d20140105-32545-158er48/spec.rb:25 # Charlatan performs multiplication
rspec /tmp/d20140105-32545-158er48/spec.rb:33 # Charlatan performs division
........ Finished in 0.01245 seconds 8 examples, 0 failures
........ Finished in 0.00964 seconds 8 examples, 0 failures
.......F
Failures:
1) Charlatan actually performs calculations
Failure/Error: Charlatan.trick do
expected: true value
got: false
# /tmp/d20140105-32545-1y39hg6/spec.rb:57:in `block (2 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
# ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00985 seconds
8 examples, 1 failure
Failed examples:
rspec /tmp/d20140105-32545-1y39hg6/spec.rb:56 # Charlatan actually performs calculations