Efim Kozhemiakin#11
Conversation
|
Finished development, however, if there are defects, I am ready to fix it. |
final_task/calc/main.py
Outdated
|
|
||
| def main(): | ||
| try: | ||
|
|
|
|
||
|
|
||
| def reduction_expression(s): | ||
|
|
final_task/calc/main_functions.py
Outdated
| from calc.math_functions import decide_func | ||
|
|
||
|
|
||
| def reduction_expression(s): |
There was a problem hiding this comment.
лучше избегать названий переменных, которые состоят из одного символа. Такие названия не несут никакой информации.
final_task/calc/main_functions.py
Outdated
| @@ -0,0 +1,114 @@ | |||
| import calc.other_functions as o_f | |||
There was a problem hiding this comment.
Человеку, который видит этот код впервые, сложно понять, что значит o_f. Я думаю, в данном случае лучше оставить other_functions
final_task/calc/main_functions.py
Outdated
| return lis | ||
|
|
||
|
|
||
| def compare(lis): |
There was a problem hiding this comment.
Из названия функции и названия аргументов нельзя получить информацию, что эта функция делает и что в эту функцию нужно отправить в качестве аргумента. Отсутствие документации усложняет ситуацию. Я бы дал более осмысленное название функции и ее аргументам.
final_task/calc/main_functions.py
Outdated
|
|
||
| def compare(lis): | ||
| i = 0 | ||
| while i < len(lis)-1: |
There was a problem hiding this comment.
С-style итерирование по коллекции через индексы крайне редко используется в Python. В Python есть замечательный цикл for, который позволяет удобным образом итерироваться по данным в коллекции без использования индексов.
for item in lis:
# do smt
passThere was a problem hiding this comment.
А если мне не нужно последний элемент проверять, то брать срез?
for item in lis[:-1]:
...
Или чтоб получать индексы использовать range:
for item in range(len(lis)-1):
...
There was a problem hiding this comment.
В случае, если нужно взять колекцию без последнего элемента, то можно взять срез.
а если нужно в этом случае еще использовать индексы, то можно использовать функцию enumerate
for index, element in enumerate(lis[:-1]):
pass
final_task/calc/main_functions.py
Outdated
| return st_nums[0] | ||
|
|
||
|
|
||
| def verify(s, i, st_nums, st_ops): |
There was a problem hiding this comment.
Очень сложно читать код, где названия переменных не несут в себе смысла. Как минимум я бы переименовал переменные s и i
| i += 1 | ||
|
|
||
| if len(st_nums) > 1 or len(st_ops): | ||
| print('ERROR: not necessary operation') |
There was a problem hiding this comment.
Я думаю, в данном случае будет уместо использовать исключения.
There was a problem hiding this comment.
Можете дать подсказку как это должно выглядеть, потому что я не совсем понял суть использования исключений.
There was a problem hiding this comment.
В данном случае вместо print и выхода из программы можно "бросить" исключение, например:
class InvalidExpressionError(Exception):
pass
if len(st_nums) > 1 or len(st_ops):
raise InvalidExpressionErrorА на самом верхнем уровне, где вызывается функция main, можно эти исключения обрабатывать и корректно завершать программу:
try:
main()
except Excpetion as e:
print(f"ERROR: {e})В таком случае у нас будет только одна точка, где мы завершаем исполнение этой программы, вместо большого количества функций exit.
PS: код приведен для примера, написан "на коленке" и без проверки того, что он работает.
final_task/calc/math_functions.py
Outdated
| print('ERROR: so many arguments') | ||
| exit() | ||
|
|
||
| elif func == 'abs': |
There was a problem hiding this comment.
Огромное количество одинакого кода. Почему бы в данной ситуации не использовать словарь с маппингом функций, где ключ -- это название функции, а значение -- это сама функция?
functions_mapping = {
"sin": math.sin,
...
}There was a problem hiding this comment.
Очень хорошая вещь этот маппинг, жалко раньше не знал.
final_task/calc/math_functions.py
Outdated
|
|
||
| def decide_func(func, ready_args): | ||
| if len(ready_args) == 0: | ||
| print('ERROR: no necessary arguments ') |
There was a problem hiding this comment.
В данном случае будет уместно использовать исключения.
final_task/calc/math_functions.py
Outdated
| exit() | ||
|
|
||
| elif len(ready_args) > 2: | ||
| print('ERROR: so many arguments') |
There was a problem hiding this comment.
В данном случае будет уместно использовать исключения.
final_task/calc/math_functions.py
Outdated
| return log(ready_args[0], ready_args[1]) | ||
|
|
||
| elif len(ready_args) < 2: | ||
| print('ERROR: no necessary arguments or our function "' + s[i] + '"') |
There was a problem hiding this comment.
В данном случае будет уместно использовать исключения.
final_task/calc/math_functions.py
Outdated
| return ldexp(ready_args[0], ready_args[1]) | ||
|
|
||
| else: | ||
| print('ERROR: not find function "' + func + '"') |
There was a problem hiding this comment.
В данном случае будет уместно использовать исключения.
final_task/calc/other_functions.py
Outdated
| i = 0 | ||
| while i < len(s): | ||
|
|
||
| if 96 < ord(s[i]) < 122: |
There was a problem hiding this comment.
Магические константы. Что обозначают 96 и 122?
Как минимум можно занести эти значения в переменные с читаемым именем.
final_task/calc/other_functions.py
Outdated
| unit_fun = '' | ||
| s += ' ' | ||
| i = 0 | ||
| while i < len(s): |
There was a problem hiding this comment.
Итерирование как в языке С. В даннос случае лучше использовать цикл for
There was a problem hiding this comment.
Почему for лучше? Или его просто принято использовать?
There was a problem hiding this comment.
Python высокоуровневый язык программирования. В нем есть много концепций, которые облегчают жизнь программистам. В том числе и цикл for
Цикл for позволяет абстрагироваться от индексов и поиска элемента в коллекции по этому индексу, а просто работать с итератором, который возвращает следующие значение.
В большинстве случаев, индексы программисту не нужны, так как часто используется обычный последовательный проход по данным.
Идея в простоте. Индексы прото не нужны.
final_task/calc/other_functions.py
Outdated
| unit_fun += s[i] | ||
| unit_fun = verify_pi_e(unit_fun, lis) | ||
|
|
||
| elif (47 < ord(s[i]) < 58) or s[i] == '.': |
final_task/calc/other_functions.py
Outdated
|
|
||
| def verify_pi_e(unit_func, lis): | ||
| if unit_func == 'e': | ||
| lis.append(2.718281828459045) |
There was a problem hiding this comment.
В стандартной бибилиотеке math есть эти значения. Не нужно их набирать самостоятельно.
There was a problem hiding this comment.
Понял, но хотел как лучше: быстрее и меньше памяти.
| exit() | ||
|
|
||
|
|
||
| def verify_pi_e(unit_func, lis): |
There was a problem hiding this comment.
В библиотеке math существует переменная tau. Учитывается ли она в этом решении?
There was a problem hiding this comment.
tau = 2*pi, решил её не включать, так как ей никто не пользуется и её не сложно через пи выразить.
Если без неё никак, то добавить можно)
There was a problem hiding this comment.
Есть конкретные требования в задании:
All functions and constants from standard python module
math(trigonometry, logarithms, etc.).
final_task/calc/other_functions.py
Outdated
| return lis | ||
|
|
||
|
|
||
| def prior(op): |
There was a problem hiding this comment.
Название функции должно быть глаголом.
There was a problem hiding this comment.
Можно поинтересоваться почему, специально в PEP8 заглянул, там такого не написано.
There was a problem hiding this comment.
Функция -- это действие, а действие описывает глагол, вот и все :)
Поясню свой комментарий.
Имя функции не должно состоять из одного глагола. Название функции должно описывать какое-то действие.
в данном случае вместо prior можно дать название get_priority
final_task/calc/other_functions.py
Outdated
| return 5 | ||
|
|
||
|
|
||
| def bin_operate(a, b, op): |
There was a problem hiding this comment.
Название функции должно быть глаголом.
|
|
||
| def additions(lis): | ||
| i = 0 | ||
| while i < len(lis)-1: |
There was a problem hiding this comment.
Лучше использовать цикл for для генерации новой коллекции, чем видоизменять колекцию, которая передана как аргумент функции, прямо в момент итерации по этой коллекции
There was a problem hiding this comment.
Привычка после С++, буду пробовать исправляться.
final_task/calc/unit_tests.py
Outdated
| formated_expression = get_args(['(', '(', 2, ')', ',', 4, ',', '(', ')', ')']) | ||
| self.assertEqual(formated_expression, [['(', 2, ')'], [4], ['(', ')']]) | ||
|
|
||
| def test14_ga3(self): |
There was a problem hiding this comment.
Не нужно использовать нумерацию тест кейсов. Достаточно будет дать им читаемое имя.
| st_ops = [] | ||
| i = 0 | ||
|
|
||
| while i < len(s): |
final_task/calc/math_functions.py
Outdated
| @@ -0,0 +1,137 @@ | |||
| from math import * | |||
There was a problem hiding this comment.
Импортирование через звездочку может привести к конфликту имен или просто запутать программиста.
Я думаю, будет лучше просто сделать импорт библиотеки math
import math|
Многие циклы поменять на for не смог, так как у меня не фиксированное число проверок, их количество нужно менять внутри цикла. |
|
Можно конечно менять на for, но для этого нужно менять уже и логику, а времени уже нету. |
Second version, soon will be tests and may be comments