Skip to content

Conversation

@Shalynishka
Copy link

No description provided.

func = {'round': (round, 4), 'abs': (abs, 4)}

users_mod = {}
bin_op = {'+': (operator.add, 1), '-': (operator.sub, 1), '*': (operator.mul, 2),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Возможно тут будет удобно использовать namedtuple для хранения данных вроде (operator.add, 1)

eval_not(self) - evaluates RPE using eval_list as source
check_num(self, temp_num) - converts str to int or float and store num in eval_list
"""
const = {'pi': math.pi, 'e': math.e, 'q': math.pi * math.e}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно достать все числа из модуля красивым способом

import math
import numbers

numbers = {attr: getattr(math, attr) for attr in dir(math) if isinstance(getattr(math, attr), numbers.Number)}
print(numbers)
{'e': 2.718281828459045,
 'inf': inf,
 'nan': nan,
 'pi': 3.141592653589793,
 'tau': 6.283185307179586}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Заменил, но немножко иначе.

unary = True
implicit_mul = False # флаг на случай неявного умножения "(2+3)4"

# лимит на длину буквенного выражения. Если его превысить -> raise ValueError

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В данном случае это не критично, но лучше писать комментарии в коде на английском языке, потому что английский поймут все, а русский не факт (мой комментарий тоже должен был быть на английском :) )

def calculate():
re = {' + ': '+', ' * ': '*', ', ': ',', ' - ': '-', '\'': '', '"': ''}
try:
parser = argparse.ArgumentParser(description='Pure-python command-line calculator.')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Функция calculate содержит логику по настройке интерфейса консольной утилиты. Это не ее ответственность, возможно нужно вынести логику по созданию парсера в отдельную функцию.

parser.add_argument('EXPRESSION', help='Expression string to evaluate')
parser.add_argument('-m', '--use-modules', action='store', nargs='*',
dest='user', help='Using your own module', default=None)
pr = parser.parse_args().__dict__

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В данном случае использовать магическую переменную __dict__ не нужно. Можно просто получать достп к атрибутам через точку

args = parser.parse_args()
args.EXPRESSION

raise ValueError('incorrect symbols!')
else:
s = s.replace('//', '$')
s = s.replace('epi', 'q')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Насколько я понимаю, это частное решение для реализации неявного умножения. Если использовать неявное умножение с какой-либо другой константой, то оно работать не будет, например tau и pi.
Реализовывать эту часть функционала по-другому необязательно, просто нужно понимать, что это dirty hack

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Конкретная замена символов "//" на "$" - именно читы, чтобы не читать два деления. А вот со вторым уже нет никакой разницы, т.к. найдя константу в подстроке, подключится возможность неявного умножения. Это был костыль в самом начале, когда об обработке неявного умножения речи не шло, но убрать надо. :)


class Calc:
"""
Pretty class for cmd evaluating

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эта строчка документация не несет никакой полезной информации. Нет понимания того, для чего предназначен класс Calc


cmp_op = []

def __init__(self, users: list):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В моем понимании users -- это набор объектов, которые представляют людей, которые пользуются этим программным решением :)

Возможно нужно придумать другое название переменной, которое будет четко описывать ее предназначение.

else:
self.users_mod[foo] = dir(foo)

def my_eval(self, st: str):
Copy link

@AlexeiBuzuma AlexeiBuzuma Dec 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Такая же ситуация. Не совсем понятно, что значит название функции my_eval и для чего она предназначена. Особенно сложно понять, что значит аргумент st.

Возможно было бы хорошо добавить документацию к функции

foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
except:
continue

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я думаю, что ошибки такого рода не должны замалчиваться.
Если программа не смогла найти модуль, который пользователь передал в утилиту, то мы должны явно сказать пользователю, что тут возникла ошибка. Модуль не найден и программа не может выполнять вычисления используя несуществующий модуль.

self.make_note(string) # сборка ОПЗ
res.insert(0, self.eval_note()) # вычисление ОПЗ
self.eval_list = []
for op in self.cmp_op:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я думаю, в таком случае лучше не скупиться на символы и написать хотя бы вот так

for cmp_operator in self.cpm_operators:
    ...

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

self.implicit_mul = False
egg = '' # содержит операцию
temp_num = '' # содержит операнд
for c in st:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Желательно не использовать в коде переменные, название которых состоит из одного символа. Это всегда плохо читается.

def make_note(self, st: str, impl=False):
self.unary = True
self.implicit_mul = False
egg = '' # содержит операцию

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему переменная, которая должна содержать операцию, называется яйцо и инициализируется пустой строкой?)

egg += c # формируем строку с буквами - sin/pi/epi и тд. Из этого потом сформируем функции или const

# попытка вытащить текущий egg из пользовательского модуля
for u, d in self.users_mod.items():

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Та же ситуация. Переменные из одного символа очень сложно читаются.



def calculate():
re = {' + ': '+', ' * ': '*', ', ': ',', ' - ': '-', '\'': '', '"': ''}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Первое, что приходит в голову, при виде переменной re -- это что-то связанное с регулярными выражениями (есть такой модуль re). Но в данном случае это что-то другое. Нужно другое название для переменной.

Copy link

@AlexeiBuzuma AlexeiBuzuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть очень много проблем с именованием переменных.

Defenition of similar function(log vs log10)
@Shalynishka Shalynishka changed the title [WIP] Nikita Kaleko Nikita Kaleko Dec 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants