Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding two new functions(% and log) in Calculadora.py #46

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions app/calculador.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,53 @@ def calculation(self, calc):

"""
return self.__calculation_validation(calc=calc)

def __calculation_validation(self, calc):
"""Responsável por verificar se o calculo informado é possível ser feito"""

# divide o cálculo de entrada em componentes individuais com base em espaços em branco
components = calc.split()

modified_components = []

for component in components:
if component.startswith("log("):
# Se o componente for uma operação logarítmica, calcule-o separadamente
arg = component[4:-1]

try:
result = self.__calculate_log(float(arg))
# Formate o resultado e adicione-o à lista de componentes modificados
modified_components.append(str(result))

except (ValueError, ZeroDivisionError):
return "Error"
else:
# Se o componente não for uma operação logarítmica, adicione-o inalterado
modified_components.append(component)

# Join the modified components to form the modified expression
modified_expression = " ".join(modified_components)

try:
result = eval(calc)
result = eval(modified_expression)

return self.__format_result(result=result)
except (NameError, ZeroDivisionError, SyntaxError, ValueError):
return 'Erro'
return "Error"


def __calculate_log(self, value):
"""Implementação personalizada do logaritmo natural (base-e)"""

result = 0
# Defina uma tolerância de erro
epsilon = 0.00001
x = 1
while abs(x - value) > epsilon:
result += 1 / x
x *= value
return result

def __format_result(self, result):
"""Formata o resultado em notação cientifica caso seja muito grande
Expand Down
67 changes: 54 additions & 13 deletions app/calculadora.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import sys
import os
import platform
import math

import tkinter as tk
from tkinter import Menu, FALSE
Expand All @@ -32,7 +33,7 @@ class Calculadora(object):
4 | 5 | 6 | -
1 | 2 | 3 | +
. | 0 | = | /
| | ^ | √
log| % | ^ | √

OBS: É necessário importar o modulo style contido na pacote view,
e selecionar uma de suas classes de estilo.
Expand Down Expand Up @@ -157,6 +158,8 @@ def _create_buttons(self, master):
self._BTN_MULT = tk.Button(master, text='*', cnf=self.theme['BTN_OPERADOR'])
self._BTN_EXP = tk.Button(master, text='^', cnf=self.theme['BTN_OPERADOR'])
self._BTN_RAIZ = tk.Button(master, text='√', cnf=self.theme['BTN_OPERADOR'])
self._BTN_LOG = tk.Button(master, text='log', cnf=self.theme['BTN_OPERADOR'])
self._BTN_PERCENT = tk.Button(master, text='%', cnf=self.theme['BTN_OPERADOR'])

# Seta configurações globais (width, height font etc) no botão especificado.
self.theme['BTN_DEFAULT'].update(self.settings['global'])
Expand All @@ -168,11 +171,7 @@ def _create_buttons(self, master):
self._BTN_CLEAR = tk.Button(master, text='C', cnf=self.theme['BTN_DEFAULT'])
self._BTN_DEL = tk.Button(master, text='<', cnf=self.theme['BTN_CLEAR'])
self._BTN_RESULT = tk.Button(master, text='=', cnf=self.theme['BTN_OPERADOR'])
self._BTN_DOT = tk.Button(master, text='.', cnf=self.theme['BTN_DEFAULT'])

# Instânciação dos botões vazios, para futura implementação
self._BTN_VAZIO1 = tk.Button(master, text='', cnf=self.theme['BTN_OPERADOR'])
self._BTN_VAZIO2 = tk.Button(master, text='', cnf=self.theme['BTN_OPERADOR'])
self._BTN_DOT = tk.Button(master, text='.', cnf=self.theme['BTN_DEFAULT'])

# Distribuição dos botões em um gerenciador de layout grid
# Linha 0
Expand Down Expand Up @@ -206,8 +205,8 @@ def _create_buttons(self, master):
self._BTN_DIV.grid(row=4, column=3, padx=1, pady=1)

# Linha 5
self._BTN_VAZIO1.grid(row=5, column=0, padx=1, pady=1)
self._BTN_VAZIO2.grid(row=5, column=1, padx=1, pady=1)
self._BTN_LOG.grid(row=5, column=0, padx=1, pady=1)
self._BTN_PERCENT.grid(row=5, column=1, padx=1, pady=1)
self._BTN_EXP.grid(row=5, column=2, padx=1, pady=1)
self._BTN_RAIZ.grid(row=5, column=3, padx=1, pady=1)

Expand All @@ -230,7 +229,8 @@ def _create_buttons(self, master):
self._BTN_DIV['command'] = partial(self._set_operator_in_input, '/')
self._BTN_EXP['command'] = partial(self._set_operator_in_input, '**')
self._BTN_RAIZ['command'] = partial(self._set_operator_in_input, '**(1/2)')

self._BTN_LOG['command'] = partial(self._set_operator_in_input, 'log(')
self._BTN_PERCENT['command'] = partial(self._set_operator_in_input, '%')

# Eventos dos botões de funcionalidades da calculadora
self._BTN_DOT['command'] = partial(self._set_dot_in_input, '.')
Expand Down Expand Up @@ -300,22 +300,63 @@ def _set_operator_in_input(self, operator):
"""Metódo responsável por captar o operador matemático clicado e setar no input"""
if self._entrada.get() == 'Erro':
return

if operator == 'log(':
# substitua a entrada padrão '0' por 'log('
if self._entrada.get() == '0':
self._entrada.delete(0, tk.END)
self._entrada.insert(0, 'log(')
else:
last_char = self._entrada.get()[-1] if self._entrada.get() else ''
if last_char in '+-/*)':
self._entrada.insert(len(self._entrada.get()), operator)
return

if self._entrada.get() == '':
# print('\33[91mOperação inválida.\33[m')
return
# Evita casos de operadores repetidos sequêncialmente, para evitar erros
if self._entrada.get()[-1] not in '+-*/' and self._lenght_max(self._entrada.get()):
self._entrada.insert(len(self._entrada.get()) ,operator)

def _get_data_in_input(self):
"""Pega os dados com todas as operações contidos dentro do input
para realizar o calculo"""
if self._entrada.get() == 'Erro':
return

result = self.calc.calculation(self._entrada.get())
self._set_result_in_input(result=result)

expressao = self._entrada.get()

if "log(" in expressao:
# Encontre o índice da primeira ocorrência de "log("
log_index = expressao.find("log(")
closing_index = expressao.find(")", log_index)
if closing_index != -1:
# Extraia o argumento da função logaritmo
value_str = expressao[log_index + 4 : closing_index]
try:
# Avalie o argumento do logaritmo e calcule o resultado
value = float(value_str)
log_result = math.log10(value)
# Substitua a expressão logarítmica pelo seu resultado na expressão
expressao = (
expressao[:log_index] +
str(log_result) +
expressao[closing_index + 1:]
)
except (ValueError, ZeroDivisionError):
# Lidar com argumentos de logaritmo inválidos
self._set_result_in_input("Error")

self._process_expression(expressao)

def _process_expression(self, expression):
"""Processe a expressão contendo operações diferentes do logaritmo"""
try:
result = eval(expression)
self._set_result_in_input(result=result)
except (NameError, ZeroDivisionError, SyntaxError, ValueError):
self._set_result_in_input("Error")

def _set_result_in_input(self, result=0):
"""Seta o resultado de toda a operação dentro do input"""
Expand Down
4 changes: 2 additions & 2 deletions app/settings/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"current_theme": "Dark",
"current_theme": "Ocean",
"global": {
"borderwidth": 0,
"highlightthickness": 0,
Expand Down Expand Up @@ -313,4 +313,4 @@
}
}
]
}
}