Вычисления в Линуксе — 2

В предыдущей статье «Вычисления в Линуксе» мы с вами затронули тему создания программ для калькулятора командной строки bc. Мы написали пару простых программ, убедились, что оно работает и успокоились.

Однако, я хотел бы чуть-чуть продвинуться дальше в этой теме — показать, как можно совершенно не напрягаясь значительно улучшить потребительские свойства этих программ.

Далеко продвигаться в изучение bc, я думаю, не стоит, но пройти мимо того, что я опишу ниже, — тоже будет не разумно, поскольку это касается работы в Unix/Linux вообще, а не только в частном случае с bc.

В предыдущей статье мы написали вот такую прогу:

# Решаем квадратное уравнение

scale = 6

# Получить коэфициенты
print "Введите а ... "
a = read()
print "Введите b ... "
b = read()
print "Введите c ... "
c = read()

print "\n"

# Посчитать дискриминант
d = b * b - 4 * a * c

# Определим, сколько корней в уравнении
if (d < 0) {
  print "Корней нет\n"
} else if (d == 0) {
  x = -b / (2 * a);
  print "Корень один\n"
  print "  x = ", x, "\n"
} else {
  print "Два корня:\n"
  d1 = sqrt(d)
  x1 = (-b - d1) / (2 * a)
  x2 = (-b + d1) / (2 * a)
  print "  x1 = ", x1, "\n"
  print "  x2 = ", x2, "\n"
}

quit
[/source]

Вопросов к проге нет, она вполне рабочая и даже кому-то будет полезна. Проблема в том, что это не совсем тот путь Unix/Linux. Не совсем правильный путь.

В мире существует много разных типов программ, и Linux не исключение. Программы бывают GUI-шные (Graphical User Interface) и программы бывают CLI-шные (Command-Line Interface). CLI-проги мы еще называем консольными.

Консольные проги тоже бывают нескольких типов. Сила Линукса состоит в том, что его консольные проги могут объединяться в цепочки посредством каналов (пайпов, pipe). И это правильное решение в духе Unix/Linux.

Дело в том, что как только прога становится интерактивной и начинает задавать уточняющие вопросы пользователю (типа "введите значение Х ..."), так сразу же такую прогу становится сложно вставлять в cкрипты. Прога по возможности, должна работать автономно. Только в таком случае возможна полная автоматизация работ. Сисадмины понимают, о чем речь, а остальным ... ну пока принимайте информацию как есть. Этот дзэн Линукса сложно объяснить словами, к нему вы должны сами дойти своим умом.

Так вот, с нашей прогй -- расчета корней квадратного уравнения -- получается небольшой парадокс. С одной стороны прога не должна беспокоить юзера, а с другой -- как ей еще как-то по другому брать входные данные?

Первое, что приходит на ум -- это вписывать исходные данные в сам текст проги. Например, так:


# Решаем квадратное уравнение

scale = 6

# Получить коэфициенты
a = 10
b = 20
c = -3

# Посчитать дискриминант
d = b * b - 4 * a * c

# Определим, сколько корней в уравнении
...
[/source]

Так тоже можно. Работать будет. Но вся автоматизация накроется медным тазом. Чтобы посчитать корни для других a, b и c, нужно откопать в директориях файл этой проги, открыть его в редакторе, осторожно изменить коэффициенты ничего другого попутно не нарушив, сохранить и заново запустить прогу. Если вы думаете, что это не кошерно, то вы ничуть не ошибаетесь!

Мы с вами работаем в Линуксе. Поэтому давайте будем поступать по-Линуксовому. Вы знаете, что команда <strong>cat</strong> осуществляет вывод содержимого файла на стандартный выход.


$ cat myfile

Однако вспомните, первоначальное назначение проги — конкатенация двух и более файлов. Это значит, что если мы укажем два и более файла, то cat выведет их содержимое как одного целого файла. И если стандартный выход cat будет перенаправлен на вход bc, то bc даже не догадается, что это были два или несколько файлов.

Улавливаете, куда я клоню?

Что нам надо сделать? Нам нужно разбить наш файл на два. В первом файле мы будем задавать значения коэффициентов a, b и c, а второй — будет выполнять свою работу как обычно.

Первый файл — abc.bc

# Задайте коэффициенты квадратного уравнения
a = 10
b = 20
c = -3

Второй файл — axx+bx+c=0.bc:

# Расчет корней квадратного уравнения

# Задайте значения коэффициентов a, b и c

# Посчитать дискриминант
d = b * b - 4 * a * c

# Определим, сколько корней в уравнении
if (d &lt; 0) {
  print "Корней нет\n"
} else if (d == 0) {
  x = -b / (2 * a);
  print "Корень один\n"
  print "  x = ", x, "\n"
} else {
  print "Два корня:\n"
  d1 = sqrt(d)
  x1 = (-b - d1) / (2 * a)
  x2 = (-b + d1) / (2 * a)
  print "  x1 = ", x1, "\n"
  print "  x2 = ", x2, "\n"
}

quit

Теперь можно вызвать программу следующим образом:

$ cat abc.bc axx+bx+c=0.bc | bc

Чтобы обсчитывать разные уравнения нам достаточно изменять имя первого файла. Вы уловили идею?

Конечно, реализация подхода к проблеме многократных расчетов с разными коэффициентами все еще далека от совершенства. Более того, желательно коэффициенты уравнения передавать непосредственно сразу в командной строке, а не создавать еще один файл. Но мне это не удалось понять как это можно сделать. Да и не воспринимайте слишком критично эту публикацию, мне хотелось только поделиться с вами еще одним секретом духа Линукса, показать его гибкость и разнообразие решений проблемы.

К тому же с bc надо завязывать. Он простой инструмент, и если вам действительно нужны расчеты, то их лучше выполнять не c помощью bc, а в Python.


.


.


.


.

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s