Skip to content

Conversation

@Efi-fi
Copy link

@Efi-fi Efi-fi commented Dec 3, 2018

Second version, soon will be tests and may be comments

@Efi-fi Efi-fi changed the title [WIP] Efim Alekseevich Efim Kozhemiakin Dec 4, 2018
@Efi-fi
Copy link
Author

Efi-fi commented Dec 4, 2018

Finished development, however, if there are defects, I am ready to fix it.


def main():
try:

Choose a reason for hiding this comment

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

Лишняя пустая строка



def reduction_expression(s):

Choose a reason for hiding this comment

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

лишняя пустая строка

from calc.math_functions import decide_func


def reduction_expression(s):

Choose a reason for hiding this comment

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

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

@@ -0,0 +1,114 @@
import calc.other_functions as o_f

Choose a reason for hiding this comment

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

Человеку, который видит этот код впервые, сложно понять, что значит o_f. Я думаю, в данном случае лучше оставить other_functions

return lis


def compare(lis):

Choose a reason for hiding this comment

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

Из названия функции и названия аргументов нельзя получить информацию, что эта функция делает и что в эту функцию нужно отправить в качестве аргумента. Отсутствие документации усложняет ситуацию. Я бы дал более осмысленное название функции и ее аргументам.


def compare(lis):
i = 0
while i < len(lis)-1:

Choose a reason for hiding this comment

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

С-style итерирование по коллекции через индексы крайне редко используется в Python. В Python есть замечательный цикл for, который позволяет удобным образом итерироваться по данным в коллекции без использования индексов.

for item in lis:
    # do smt
    pass

Copy link
Author

@Efi-fi Efi-fi Dec 6, 2018

Choose a reason for hiding this comment

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

А если мне не нужно последний элемент проверять, то брать срез?
for item in lis[:-1]:
...

Или чтоб получать индексы использовать range:
for item in range(len(lis)-1):
...

Choose a reason for hiding this comment

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

В случае, если нужно взять колекцию без последнего элемента, то можно взять срез.
а если нужно в этом случае еще использовать индексы, то можно использовать функцию enumerate

for index, element in enumerate(lis[:-1]):
    pass

return st_nums[0]


def verify(s, i, st_nums, st_ops):

Choose a reason for hiding this comment

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

Очень сложно читать код, где названия переменных не несут в себе смысла. Как минимум я бы переименовал переменные s и i

i += 1

if len(st_nums) > 1 or len(st_ops):
print('ERROR: not necessary operation')

Choose a reason for hiding this comment

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

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

Copy link
Author

Choose a reason for hiding this comment

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

Можете дать подсказку как это должно выглядеть, потому что я не совсем понял суть использования исключений.

Choose a reason for hiding this comment

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

В данном случае вместо 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: код приведен для примера, написан "на коленке" и без проверки того, что он работает.

print('ERROR: so many arguments')
exit()

elif func == 'abs':

Choose a reason for hiding this comment

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

Огромное количество одинакого кода. Почему бы в данной ситуации не использовать словарь с маппингом функций, где ключ -- это название функции, а значение -- это сама функция?

functions_mapping = {
    "sin": math.sin,
    ...
}

Copy link
Author

Choose a reason for hiding this comment

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

Очень хорошая вещь этот маппинг, жалко раньше не знал.


def decide_func(func, ready_args):
if len(ready_args) == 0:
print('ERROR: no necessary arguments ')

Choose a reason for hiding this comment

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

В данном случае будет уместно использовать исключения.

exit()

elif len(ready_args) > 2:
print('ERROR: so many arguments')

Choose a reason for hiding this comment

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

В данном случае будет уместно использовать исключения.

return log(ready_args[0], ready_args[1])

elif len(ready_args) < 2:
print('ERROR: no necessary arguments or our function "' + s[i] + '"')

Choose a reason for hiding this comment

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

В данном случае будет уместно использовать исключения.

return ldexp(ready_args[0], ready_args[1])

else:
print('ERROR: not find function "' + func + '"')

Choose a reason for hiding this comment

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

В данном случае будет уместно использовать исключения.

i = 0
while i < len(s):

if 96 < ord(s[i]) < 122:

Choose a reason for hiding this comment

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

Магические константы. Что обозначают 96 и 122?
Как минимум можно занести эти значения в переменные с читаемым именем.

unit_fun = ''
s += ' '
i = 0
while i < len(s):

Choose a reason for hiding this comment

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

Итерирование как в языке С. В даннос случае лучше использовать цикл for

Copy link
Author

Choose a reason for hiding this comment

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

Почему for лучше? Или его просто принято использовать?

Choose a reason for hiding this comment

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

Python высокоуровневый язык программирования. В нем есть много концепций, которые облегчают жизнь программистам. В том числе и цикл for
Цикл for позволяет абстрагироваться от индексов и поиска элемента в коллекции по этому индексу, а просто работать с итератором, который возвращает следующие значение.
В большинстве случаев, индексы программисту не нужны, так как часто используется обычный последовательный проход по данным.
Идея в простоте. Индексы прото не нужны.

unit_fun += s[i]
unit_fun = verify_pi_e(unit_fun, lis)

elif (47 < ord(s[i]) < 58) or s[i] == '.':

Choose a reason for hiding this comment

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

Магические константы.


def verify_pi_e(unit_func, lis):
if unit_func == 'e':
lis.append(2.718281828459045)

Choose a reason for hiding this comment

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

В стандартной бибилиотеке math есть эти значения. Не нужно их набирать самостоятельно.

Copy link
Author

Choose a reason for hiding this comment

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

Понял, но хотел как лучше: быстрее и меньше памяти.

exit()


def verify_pi_e(unit_func, lis):

Choose a reason for hiding this comment

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

В библиотеке math существует переменная tau. Учитывается ли она в этом решении?

Copy link
Author

Choose a reason for hiding this comment

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

tau = 2*pi, решил её не включать, так как ей никто не пользуется и её не сложно через пи выразить.
Если без неё никак, то добавить можно)

Choose a reason for hiding this comment

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

Есть конкретные требования в задании:

All functions and constants from standard python module math (trigonometry, logarithms, etc.).

Copy link
Author

Choose a reason for hiding this comment

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

Так, точно)

return lis


def prior(op):

Choose a reason for hiding this comment

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

Название функции должно быть глаголом.

Copy link
Author

Choose a reason for hiding this comment

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

Можно поинтересоваться почему, специально в PEP8 заглянул, там такого не написано.

Choose a reason for hiding this comment

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

Функция -- это действие, а действие описывает глагол, вот и все :)
Поясню свой комментарий.
Имя функции не должно состоять из одного глагола. Название функции должно описывать какое-то действие.
в данном случае вместо prior можно дать название get_priority

Copy link
Author

Choose a reason for hiding this comment

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

Благодарю за уточнение.

return 5


def bin_operate(a, b, op):

Choose a reason for hiding this comment

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

Название функции должно быть глаголом.


def additions(lis):
i = 0
while i < len(lis)-1:

Choose a reason for hiding this comment

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

Лучше использовать цикл for для генерации новой коллекции, чем видоизменять колекцию, которая передана как аргумент функции, прямо в момент итерации по этой коллекции

Copy link
Author

Choose a reason for hiding this comment

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

Привычка после С++, буду пробовать исправляться.

formated_expression = get_args(['(', '(', 2, ')', ',', 4, ',', '(', ')', ')'])
self.assertEqual(formated_expression, [['(', 2, ')'], [4], ['(', ')']])

def test14_ga3(self):

Choose a reason for hiding this comment

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

Не нужно использовать нумерацию тест кейсов. Достаточно будет дать им читаемое имя.

st_ops = []
i = 0

while i < len(s):

Choose a reason for hiding this comment

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

Цикл for

@@ -0,0 +1,137 @@
from math import *

Choose a reason for hiding this comment

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

Импортирование через звездочку может привести к конфликту имен или просто запутать программиста.
Я думаю, будет лучше просто сделать импорт библиотеки math

import math

@Efi-fi
Copy link
Author

Efi-fi commented Dec 19, 2018

Многие циклы поменять на for не смог, так как у меня не фиксированное число проверок, их количество нужно менять внутри цикла.

@Efi-fi
Copy link
Author

Efi-fi commented Dec 19, 2018

Можно конечно менять на for, но для этого нужно менять уже и логику, а времени уже нету.

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