Skip to content
Open
17 changes: 17 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file added final_task/pycalc/__init__.py
Empty file.
28 changes: 28 additions & 0 deletions final_task/pycalc/arithmetic.py
Original file line number Diff line number Diff line change
@@ -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)
76 changes: 76 additions & 0 deletions final_task/pycalc/calculate_expression.py
Original file line number Diff line number Diff line change
@@ -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
82 changes: 82 additions & 0 deletions final_task/pycalc/calculate_math_parameters.py
Original file line number Diff line number Diff line change
@@ -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
43 changes: 43 additions & 0 deletions final_task/pycalc/parse_brackets.py
Original file line number Diff line number Diff line change
@@ -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
90 changes: 90 additions & 0 deletions final_task/pycalc/pycalc.py
Original file line number Diff line number Diff line change
@@ -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)
19 changes: 19 additions & 0 deletions final_task/pycalc/pycalc_common.py
Original file line number Diff line number Diff line change
@@ -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)
24 changes: 24 additions & 0 deletions final_task/setup.py
Original file line number Diff line number Diff line change
@@ -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",
],
)