diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..c825f3de
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/final_task/pycalc/__init__.py b/final_task/pycalc/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/final_task/pycalc/arithmetic.py b/final_task/pycalc/arithmetic.py
new file mode 100644
index 00000000..894f8ac6
--- /dev/null
+++ b/final_task/pycalc/arithmetic.py
@@ -0,0 +1,28 @@
+def subtraction(first_parameter, second_parameter):
+ return float(first_parameter) - float(second_parameter)
+
+
+def add(first_parameter, second_parameter):
+ return float(first_parameter) + float(second_parameter)
+
+
+def multiply(first_parameter, second_parameter):
+ return float(first_parameter) * float(second_parameter)
+
+
+def division(first_parameter, second_parameter):
+ if float(second_parameter) == 0:
+ return "Error: division by zero"
+ return float(first_parameter) / float(second_parameter)
+
+
+def power(first_parameter, second_parameter):
+ return float(first_parameter) ** float(second_parameter)
+
+
+def integer_division(first_parameter, second_parameter):
+ return float(first_parameter) // float(second_parameter)
+
+
+def modulo_division(first_parameter, second_parameter):
+ return float(first_parameter) % float(second_parameter)
diff --git a/final_task/pycalc/calculate_expression.py b/final_task/pycalc/calculate_expression.py
new file mode 100644
index 00000000..51b10bab
--- /dev/null
+++ b/final_task/pycalc/calculate_expression.py
@@ -0,0 +1,76 @@
+from pycalc import arithmetic
+import re
+
+
+def calculate(value):
+ """ It is a calculator. It can be use Math operation"""
+
+ if type(value) is not str:
+ print('It expected str got ' + type(value).__name__)
+
+ access_operators = ['+', '-', '*', '/', '//', '%', '**']
+ operators = re.findall(r'(\D*[^-.?\d?])', value)
+ digits = re.findall(r'(-*\.*\d+\.*\d*)', value)
+ if len(operators) == len(digits):
+ return "Error: you miss digits"
+ # check accessible operators
+ for operator in operators:
+ format_operator = operator.replace(' ', '')
+ if format_operator not in access_operators:
+ return "Error: not accessible operator '" + operator + "'"
+
+ counter = 0
+ result = 0
+ rest_operator = []
+ rest_digits = []
+ check = False
+ # look for priority operators
+ for operator in operators:
+ format_operator = operator.replace(' ', '')
+
+ if format_operator == '/' or format_operator == '*' or format_operator == '//' or format_operator == '%' \
+ or format_operator == '**':
+ first_parameter = digits[counter]
+ if check:
+ first_parameter = rest_digits[-1]
+ if format_operator == '*':
+ result = arithmetic.multiply(first_parameter, digits[counter + 1])
+ elif format_operator == '/':
+ result = arithmetic.division(first_parameter, digits[counter + 1])
+ if type(result) is str:
+ return result
+ elif format_operator == '//':
+ result = arithmetic.integer_division(first_parameter, digits[counter + 1])
+ elif format_operator == '%':
+ result = arithmetic.modulo_division(first_parameter, digits[counter + 1])
+ elif format_operator == '**':
+ result = arithmetic.power(first_parameter, digits[counter + 1])
+ if counter != 0:
+ rest_digits[-1] = result
+ else:
+ rest_digits.append(result)
+ check = True
+ else:
+ rest_operator.append(format_operator)
+ if counter == 0:
+ rest_digits.append(digits[counter])
+ rest_digits.append(digits[counter + 1])
+ check = False
+ counter += 1
+ if len(rest_operator) == 0:
+ # return value
+ if len(rest_digits) > 0:
+ return rest_digits[0]
+ else:
+ return value
+ else:
+ result = rest_digits[0]
+ counter2 = 0
+ for operator in rest_operator:
+ format_operator = operator.replace(' ', '')
+ if format_operator == '+':
+ result = arithmetic.add(result, rest_digits[counter2 + 1])
+ elif format_operator == '-':
+ result = arithmetic.subtraction(result, rest_digits[counter2 + 1])
+ counter2 += 1
+ return result
diff --git a/final_task/pycalc/calculate_math_parameters.py b/final_task/pycalc/calculate_math_parameters.py
new file mode 100644
index 00000000..608ac695
--- /dev/null
+++ b/final_task/pycalc/calculate_math_parameters.py
@@ -0,0 +1,82 @@
+import math
+import re
+import builtins
+from pycalc import calculate_expression, parse_brackets
+
+math_param = dir(math)
+additional_param = ['abs', 'round']
+all_parameters = math_param + additional_param
+
+
+def calc_math(name, value):
+ if value.find(',') == -1:
+ result = getattr(math, name)(
+ float(calculate_expression.calculate("".join(parse_brackets.parse_brackets(value)))))
+ else:
+ new_value = value.split(',')
+ result = getattr(math, name)(
+ float(calculate_expression.calculate("".join(parse_brackets.parse_brackets(new_value[0])))),
+ float(calculate_expression.calculate("".join(parse_brackets.parse_brackets(new_value[1])))))
+ return result
+
+
+def cal_additional_parameters(name, value):
+ return getattr(builtins, name)(float(eval(value)))
+
+
+# input: value - string expression
+# output: string with calculated parameters
+def calculate_math_parameters(value):
+ value = value.replace('pi', str(math.pi)).replace('e', str(math.e))
+
+ math_parameters_from_expression = re.findall(r'(\w+)\s*\((.+)\)', value)
+ value = value.replace(' (', '(')
+
+ for items in math_parameters_from_expression:
+ new_item_name = items[0]
+ new_item_value = items[1]
+ if new_item_name not in all_parameters:
+ return 'Error: parameter "' + new_item_name + '" not found'
+ if items[0] in additional_param:
+ value = value.replace(items[0] + '(' + items[1] + ')',
+ str(cal_additional_parameters(new_item_name, new_item_value)))
+ else:
+ value = value.replace(items[0] + '(' + items[1] + ')', str(calc_math(new_item_name, new_item_value)))
+
+ return value
+
+
+def calc_math_parameter(value):
+
+ result = []
+ temp = ""
+ previous_element = ""
+ for item in value:
+ if re.match(r'[a-z]', item) and not re.match(r'[a-z]', previous_element):
+ if len(temp) > 0:
+ result.append(temp)
+ temp = ""
+ temp += item
+ if item == ')':
+ if len(temp) > 0:
+ if temp.find('(') != -1 and temp.find(')') != -1:
+ count_left_bracket = re.findall(r'\(', temp)
+ count_right_bracket = re.findall(r'\)', temp)
+ if len(count_left_bracket) == len(count_right_bracket):
+ if len(result) > 0:
+ if result[-1].find('(') != -1:
+ temp = result[-1] + str(calculate_math_parameters(temp))
+ del result[-1]
+ else:
+ temp = str(calculate_math_parameters(temp))
+ result.append(temp)
+ temp = ""
+ else:
+ temp = str(calculate_math_parameters(temp))
+ result.append(temp)
+ temp = ""
+ else:
+ result.append(temp)
+ temp = ""
+ previous_element = item
+ return result
diff --git a/final_task/pycalc/parse_brackets.py b/final_task/pycalc/parse_brackets.py
new file mode 100644
index 00000000..2ad0a1d0
--- /dev/null
+++ b/final_task/pycalc/parse_brackets.py
@@ -0,0 +1,43 @@
+from pycalc import calculate_expression
+
+
+def parse_brackets(value):
+ result = []
+ temp = ""
+ is_calculate_expression = False
+ counter_value = 1
+ for item in value:
+ if item == '(' or item == ')':
+ if item == ')':
+ temp += item
+ if len(temp) > 0:
+ if temp.find('(') != -1 and temp.find(')') != -1:
+ temp = temp.replace('(', '').replace(')', '')
+ if len(result) > 0:
+ if result[-1].find('(') != -1:
+ temp = result[-1] + str(calculate_expression.calculate(temp))
+ del result[-1]
+ else:
+ temp = str(calculate_expression.calculate(temp))
+ result.append(temp)
+ temp = ""
+ is_calculate_expression = True
+ else:
+ temp = str(calculate_expression.calculate(temp))
+ result.append(temp)
+ else:
+ result.append(temp)
+ temp = ""
+ else:
+ if len(value) == counter_value:
+ temp += item
+ result.append(temp)
+ temp += item
+ if item == ')' and not is_calculate_expression:
+ temp = ""
+ elif is_calculate_expression:
+ temp = temp[:-1]
+ is_calculate_expression = False
+ counter_value += 1
+ result = ''.join(result)
+ return result
diff --git a/final_task/pycalc/pycalc.py b/final_task/pycalc/pycalc.py
new file mode 100644
index 00000000..3e03fe3e
--- /dev/null
+++ b/final_task/pycalc/pycalc.py
@@ -0,0 +1,90 @@
+import argparse
+# import re
+from pycalc.pycalc_common import pcalc
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("EXPRESSION", type=str, help="expression is the string you use here")
+ parser.add_argument("-m", "--use-modules", help="additional modules to use", action="store_true")
+ args = parser.parse_args()
+ if args.EXPRESSION:
+ print(pcalc(args.EXPRESSION))
+
+# print(pcalc('round(123.4567890)'))
+# print(type(pycalc_common.pcalc('-13')))
+# print(pycalc_common.pcalc('sin(e**log(e**e**sin(23.0),45.0) + cos(3.0+log10(e**-e)))'))
+# def pcalc(value):
+# left_bracket = re.findall(r'\(', value)
+# right_bracket = re.findall(r'\)', value)
+# if len(left_bracket) != len(right_bracket):
+# return 'error: missing bracket'
+#
+# result_calculate = calculate_math_parameters.calculate_math_parameters(value)
+#
+# print('result_calculate', result_calculate)
+# if len(left_bracket) or len(right_bracket):
+# result = parse_brackets.parse_brackets(result_calculate)
+# else:
+# result = eval(value)
+# # print('eval_result:', eval(value))
+# print('my_result:', result)
+# return result
+
+
+# print(pcalc('sin(e**log(e**e**sin(23.0),45.0) + cos(3.0+log10(e**-e)))'))
+# print(sin(e**log(e**e**sin(23.0),45.0) + cos(3.0+log10(e**-e))))
+# print(calculate_expression.calculate('2.718281828459045**2.718281828459045**-0.8462204041751706'))
+# print(2.718281828459045**2.718281828459045**-0.8462204041751706)
+# print(2.718281828459045**-0.8462204041751706)
+# print(2.718281828459045**0.4290334443756452)
+# print(calculate_expression.calculate('5**2'))
+# print(calc_math('sin(-cos(-sin(3.0)-cos(-sin(-3.0*5.0)-sin(cos(log10(43.0))))+cos(sin(sin(34.0-2.0**2.0))))--cos(1.0)--cos(0.0)**3.0)'))
+# print(sin(-cos(-sin(3.0)-cos(-sin(-3.0*5.0)-sin(cos(log10(43.0))))+cos(sin(sin(34.0-2.0**2.0))))--cos(1.0)--cos(0.0)**3.0))
+# print(parse_brackets.parse_brackets('sin(e**log(e**e**sin(23.0),45.0) + cos(3.0+log10(e**-e)))'))
+# print(calculate_math_parameters.calculate_math_parameters('e + .3 + e '))
+# print(pcalc('7+((4+e) + log(8)*8)/cos((log(8) - 4)*2)'))
+#
+# def calculate(value):
+# parameters_level_one = ['**']
+# parameters_level_two = ['/', '*', '//', '%']
+# parameters_level_three = ['+', '-']
+# all_parameters = parameters_level_one + parameters_level_two + parameters_level_three
+# # get_numbers = []
+# # get_operators = []
+# # temp = ""
+# # prev_item = ""
+# # value = value.replace(' ', '')
+# # for item in value:
+# # if re.match(r'\d', item):
+# # get_number.append('item')
+# # if not re.match(r'\d]', item):
+# operators = re.findall(r'(\D*[^.?\d?])', value)
+# digits = re.findall(r'(\.*\d+\.*\d*)', value)
+# counter = 0
+# get_first_number = 0
+# get_second_number = 0
+# for item in operators:
+# item = item.replace(' ', '')
+# if len(digits) > counter:
+# get_first_number = digits[counter]
+# if len(digits) > counter + 1:
+# get_second_number = digits[counter + 1]
+# if item not in all_parameters:
+# minus = re.findall('-', item)
+#
+# elements = re.findall(r'[^-+\s]', item)
+# print(len(minus) % 2)
+# if len(minus) % 2 == 0:
+# get_second_number = '-' + get_second_number
+# print('elements:', elements)
+# if len(minus) == 0:
+# return "Error: not accessible operator '" + item + "'"
+# get_parameter = re.findall(r'(\D*[^-+.?\d?])', value)
+# counter += 1
+# print(get_first_number)
+# print(get_second_number)
+# print('result:', float(get_first_number) * float(get_second_number))
+#
+# print(operators)
+# print(digits)
diff --git a/final_task/pycalc/pycalc_common.py b/final_task/pycalc/pycalc_common.py
new file mode 100644
index 00000000..6e62a9f7
--- /dev/null
+++ b/final_task/pycalc/pycalc_common.py
@@ -0,0 +1,19 @@
+import re
+from pycalc import calculate_math_parameters, calculate_expression, parse_brackets
+import math
+
+
+def pcalc(value):
+ value = value.replace('pi', str(math.pi)).replace('e', str(math.e))
+ left_bracket = re.findall(r'\(', value)
+ right_bracket = re.findall(r'\)', value)
+ if len(left_bracket) != len(right_bracket):
+ return 'error: missing bracket'
+
+ math_parameters_from_expression = re.findall(r'(\w+)\s*\((.+)\)', value)
+ result = value
+ if len(math_parameters_from_expression):
+ result = "".join(calculate_math_parameters.calc_math_parameter(value))
+ result = parse_brackets.parse_brackets(result)
+ result = calculate_expression.calculate(result)
+ return float(result)
diff --git a/final_task/setup.py b/final_task/setup.py
index e69de29b..7f9954c2 100644
--- a/final_task/setup.py
+++ b/final_task/setup.py
@@ -0,0 +1,24 @@
+import setuptools
+
+with open("README.md", "r") as fh:
+ long_description = fh.read()
+
+setuptools.setup(
+ name='pycalc',
+ version='1.31',
+
+ author="Maxim Tsyba",
+ author_email="maksimtsuba@gmail.com",
+ description="Calculator for EPAM",
+ long_description=long_description,
+ long_description_content_type="text/markdown",
+ url="https://github.com/javatechy/dokr",
+ packages=setuptools.find_packages(include=['pycalc']),
+ entry_points={'console_scripts': ['pycalc = pycalc.pycalc:main']},
+ py_modules=["pycalc"],
+ classifiers=[
+ "Programming Language :: Python :: 3.6",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ ],
+)