Comments 8
У меня есть сильное-пресильное ощущение, что вы смешали бизнес-логику и представление воедино, поэтому уже сейчас, в программе, далекой от завершения, у вас царит лапшекошмар.
Почему бы всякие утилиты вида "отцентровать строку" не вынести в функцию? Почему бы не повыносить в функции кучу других утилит? Почему не оформить Chart или Plot как класс с методами для рисования?
Да даже с точки зрения UX, зачем спрашивать pace, когда его можно высчитать, исходя из ширины окна терминала?
Как быть с тем, что если вы захотите перейти на другой бэкенд, например, на ncurses, то вам потребуется переписать абсолютно все с нуля, потому что этот код не переносим?
Если бы вас посетила светлая идея использовать символы псевдографики для увеличения разрешения графика, то ведь тоже придется все выбросить. Зачем?
Вы парсите '%10.6g', просто беря символы с 1 по 3 невключительно. Это так не работает! Я хочу поле шириной 100 знаков, и что теперь? Или 9 знаков? Зачем в принципе использовать устаревшие %s
, когда есть {}
?
У меня слишком много вопросов к тому, что в этой статье написано абсолютно не так, как следовало бы.
Может я что-то не правильно понял, поправьте тогда, но почему не использовать метод формат, с довольно гибкой спецификацией для настроек.
Например там же есть выравнивание при помощи символа заполнителя.
Тут, например, описана спецификация.
Стоило бы еще изучить основы форматирования исходников Python и PEP-8. Например, строки переносятся без уродливого \
, и внутри любых скобок его тоже можно не использовать (у вас, кстати, половина строк с бэкслешем, половина — без него).
Теперь нам нужно печатать сами значения. Для этого понадобиться цикл. Так как введенные данные могут быть дробными, использовать range не получится, поэтому я буду использовать обычный цикл.
import operator
...
def myrange(from_, to, step):
op = operator.le if step > 0 else operator.ge
while op(from_, to):
yield from_
from_ += step
Дарю
Лучше так
if pace_x == 0 or (to_x - from_x) * pace_x < 0 or to_x == from_x:
print("Incorrect input")
exit(1)
// какой-то код
dial_precision = "{:10.6f}" # точность числа
...
aux_x = dials_precision % x_copy
aux = len(aux_x) != int(dials_precision[1:3]) + 2
aux_2 = len(aux_x) == int(dials_precision[1:3]) + 1
vs
LENGTH = 10
DIAL_PRECISION = "{:{}.6f}" # точность числа
...
aux_x = DIAL_PRECISION.format(x_copy, LENGTH)
aux = len(aux_x) != LENGTH + 2
aux_2 = len(aux_x) == LENGTH + 1
Можно немного сократить код, даже без разделения кода и его вывода как замечели выше
import operator
from math import sqrt
INPUT_TEXT = 'Enter the first and the last x-coordinates and a pace dividing them by a space:'
LENGTH = 10
COL_LENGTH = LENGTH + 2
DIAL_PRECISION = "{v:{d}>{l}.3g}" # точность числа
DELIMITER = ' '
BAD_ROW = '{v:{d}^{l}}'.format(v='не сущ', l=LENGTH, d=DELIMITER)
HEADER_FORMAT = "|{d}{x:{d}^{l}}{d}|{d}{y1:{d}^{l}}{d}|{d}{y2:{d}^{l}}{d}|{d}{y3:{d}^{l}}{d}|"
ROW_FORMAT = HEADER_FORMAT.replace('^', '>')
def y1(x):
return x ** 3 - 2 * x ** 2 + 4 * x - 8
def y2(x):
return 1 - 1 / x ** 2
def y3(x):
return sqrt(abs(y1(x) * y2(x)))
def myrange(from_, to, step=1):
if step == 0:
raise ValueError('Step must be != 0')
op = operator.le if step > 0 else operator.ge
while op(from_, to):
yield from_
from_ += step
def get_out(value):
aux_value = DIAL_PRECISION.format(v=value, d=DELIMITER, l=LENGTH)
return aux_value
def go():
# from_x, to_x, pace_x = map(float, input(INPUT_TEXT).split())
from_x, to_x, pace_x = -2, 2, 2
if pace_x == 0 or (to_x - from_x) * pace_x < 0 or not abs(to_x - from_x):
print("Incorrect input")
exit(1)
length_of_table_lower_bound = COL_LENGTH * 4 + 5
min_y1_value, max_y1_value, x_copy = y1(from_x), y1(from_x), from_x
negative_value_exists = False
print('-' * length_of_table_lower_bound)
print(HEADER_FORMAT.format(
x='x', y1='y1', y2='y2', y3='y3', l=LENGTH, d=DELIMITER)
)
print('-' * length_of_table_lower_bound)
for x_copy in myrange(from_x, to_x, pace_x):
y1_cur_value = y1(x_copy)
min_y1_value = ((min_y1_value > y1_cur_value) * y1_cur_value +
(min_y1_value <= y1_cur_value) * min_y1_value)
max_y1_value = ((max_y1_value < y1_cur_value) * y1_cur_value +
(max_y1_value >= y1_cur_value) * max_y1_value)
negative_value_exists += y1_cur_value < 0
out_x = get_out(x_copy)
out_y1 = get_out(y1_cur_value)
out_y2 = get_out(y2(x_copy)) if x_copy else BAD_ROW
out_y3 = get_out(y3(x_copy)) if x_copy else BAD_ROW
print(ROW_FORMAT.format(x=out_x, y1=out_y1, y2=out_y2, y3=out_y3, d=DELIMITER, l=LENGTH))
print('-' * length_of_table_lower_bound)
if __name__ == '__main__':
go()
А почему не писать ljust rjust?
Построение функций в консоли. Часть 1