Разложение функции в композицию индуктивных – творческая задача и применяется только в простейших случаях, где оно более или менее очевидно.
sum, count = 0.0, 0
begin
while true
sum += readline f
o
t
count += 1
end
rescue EOFError
puts count == 0 ?
0 :
sum/count
end
В данной задаче минимальным индуктивным расширением является объединение двух индуктивных функций – количества элементов последовательности и их суммы.
Как правило, решение таких задач сводится к тому, что программист должен понять, какой информации (переменных) ему не хватает, и ввести ее в программу Более подробно об этом можно причитать в пособии Е.А. Роганова «Основы информатики и программирования» (стр. 132—138).
3.3 Тестирование последовательностей. Для тестирования программ, работающих с последовательностью, возможно применение следующего приёма. Продемонстрируем его на тестировании программы, находящей среднее арифметическое элементов последовательности.
require ’test/unit’
class TestAverage < Test::Unit::TestCase
def setup # запуск программы с последовательностью @seq = IO.popen("ruby average.rb", "r+") end
def teardown # выключение программы (закрытие потока) @seq.close end
# метод направляющий поток данных в тестируемую
# программу и возвращающий результат в виде строки def sequence(*items)
items.each { |i| @seq.puts(i) }
@seq.close_write @seq.read.chomp end
def test_average
assert_equal("2.5",sequence(1,2,3,4))
end
def test_empty
assert_equal("0", sequence()) end end
Отметим что функция sequence() возвращает результат выполнения программы average.rb в виде строки (выводимой коммандой puts). Таким образом, если бы оператор печати выглядет так:
puts "average = #{count == 0 ? 0 : sum/count}"
то тестовый случай должен принять вид
assert_equal(sequence(1,2,3,4),"average = 2.5")
Задача 1. Найдите максимальный элемент последовательности чисел.
Задача 2. Найдите второй по величине элемент последовательности.
Тестирование последовательностей
Задача 3. Напишите программу, определяющую, является ли последовательность чисел возрастающей?
Задача 4. Найдите наибольший общий делитель последовательности целых чисел.
Задача 5. Найдите сумму всех попарных произведений элементов последовательности чисел.
4. Стековый калькулятор и языки
Прежде, чем начать рассматривать сам компилятор формул, необходимо ознакомиться с такими понятиями как стек, стековый калькулятор, языки, грамматики, а также компилятор.
Итак, введем определение стека. Стеком называется любая структура, в которой могут накапливаться какие-то элементы и для которой выполнено следующее основное условие: элементы из стека можно доставать только в порядке, обратном порядку добавления их в стек. Это условие часто называют принципом «последним пришел – первым ушел» или LIFO (Last In – First Out).
Элемент стека, который в данный момент можно взять или посмотреть называется вершиной стека, максимальное число элементов в стеке – глубина стека. Стек, в котором нет ни одного элемента называется пустым.
Уже из названия видно, что стековый калькулятор использует стек. При выполнении любых арифметический операций (сложить, умножить, вычесть, разделить) стековый калькулятор достает из стека последовательно сначала правый, а затем левый аргументы операции, выполняет операцию и полученный результат помещает в стек.
При выполнении любой арифметической операции число элементов в стеке уменьшается на 1. Попытки выполнить операцию, когда в стеке меньше двух элементов, или показать результат, когда стек пуст, приводят к отказу.
Рассмотрим пример для стекового калькулятора. Пусть требуется получить значение формулы 5 - (7+8) +25. Тогда последовательность для стекового калькулятора будет такой: 5,7,8, +, •, 25, +.
Из предыдущего примера видно, что обычная формула преобразуется в некую последовательность для стекового калькулятора. Причем эта последовательность преобразуем мы сами. Наша же задача написать программу, которая делает это для любой формулы автоматически. Такая программа называется компилятором с языка арифметических формул на язык понятный стековому калькулятору.