Найти - Пользователи
Полная версия: написание калькулятора
Начало » Python для новичков » написание калькулятора
1
Lorenzo
помогите пожалуйста с кодом, мне нужно избавиться от второго поля ввода и сделать так, чтобы все ответы отображались только в одном, а также увеличить само поле ввода
from tkinter import *
from tkinter import messagebox
from tkinter import ttk
import math

#окно калькулятора
root = Tk()
root.title (“Калькулятор”)
root.configure(background='lightgrey',bd=5)
root.resizable(False, False)

#логика калькулятора
def calc (key):
global memory
if key == “=”:
#исключаем написание букв
strl = “+-0123456789*/xⁿ+/-cos sin tan”
if calc_entry.get() not in strl:
calc_entry.delete(0, END)
calc_entry.insert(END, “Вы ввели не число”)
messagebox.showerror(“Ошибка!”, “проверьте данные”)

#счет
try:
result = eval(calc_entry.get())
calc_entry.delete(0, END)
calc_entry.insert(END, str(result))
except:
calc_entry.insert(END, “Ошибка!”)
messagebox.showerror(“Ошибка!”, “данные не верны”)
elif key == “C”:
calc_entry.delete(0, END)
elif key == “+/-”:
if “=” in calc_entry.get():
calc_entry.delete(0, END)
try:
if calc_entry.get() == “-”:
calc_entry.delete(0)
else:
calc_entry.insert(0, “-”)
except IndexError:
pass
elif key == ‘sin’:
calc_entry2.insert(0, 0)
calc_entry2.delete(0, END)
calc_entry2.insert(0, str(format(math.sin(math.radians(float(
calc_entry.get()))), ‘.5f’)))
elif key == “cos”:
calc_entry2.insert(0, 0)
calc_entry2.delete(0, END)
calc_entry2.insert(0, str(format(math.cos(math.radians(float(
calc_entry.get()))), ‘.5f’)))
elif key == ‘tan’:
calc_entry2.insert(0, 0)
calc_entry2.delete(0, END)
calc_entry2.insert(0, str(format(math.tan(math.radians(float(
calc_entry.get()))), ‘.5f’)))
elif key == “xⁿ”:
calc_entry.insert(END, “**”)
elif key == “√2”:
calc_entry2.insert(0, 0)
calc_entry2.delete(0, END)
calc_entry2.insert(END, str(format (math.sqrt(float(
calc_entry.get())), ‘.5f’)))
elif key == ‘Cm’:
calc_entry2.delete(0, END)
else:
if “=” in calc_entry.get():
calc_entry.delete(0, END)
calc_entry.insert(END, key)

#создание ячеек кнопок
bttn_list = [
“√2”, “xⁿ”, “Cm”, “C”,
“sin”, “cos”, “tan”, “/”,
“7”, “8”, “9”, “*”,
“4”, “5”, “6”, “-”,
“1”, “2”, “3”, “+”,
“+/-”, “0”, “.”, “=”,
]

r = 2
c = 0

for i in bttn_list:
cmd = lambda x=i: calc (x)
ttk.Button (root, text=i, command=cmd, width=7).grid(row=r, column=c)
Button(root, text=i, command=cmd, width=6 , height=1, font='Arial 15', bg='white').grid(
row=r, column=c)
c += 1
if c > 3:
c = 0
r += 1

#создание поля ввода
calc_entry = Entry(root, width=49)
calc_entry.grid(row=0, column=0, columnspan=4)
calc_entry2 = Entry(root, width=11,)
calc_entry2.grid(row=1, column=3, columnspan=4)

root.mainloop ()
PEHDOM
ну чтоб так сразу там много правок нужно делать, убираете вот это,

calc_entry2 = Entry(root, width=11,)
calc_entry2.grid(row=1, column=3, columnspan=4)
в остальном коде меняете везде calc_entry2 на calc_entry, и чутка переписываетет логику всех этих key == ‘sin’ , “cos” и тд по примерно такому принципу:
 	elif key == "√2":
		res =  str(format (math.sqrt(float(calc_entry.get())), '.5f'))
		calc_entry.insert(0, 0)
		calc_entry.delete(0, END)
		calc_entry.insert(END, res)
увеличить размер поля ввода:
 #создание поля ввода
calc_entry = Entry(root, width=26, font=('Verdana', 14))
calc_entry.grid(row=0, column=0, columnspan=4, padx=2, pady=16)
Lorenzo
спасибо большое, подскажите еще пожалуйста, как сделать кнопку, которая будет стирать по одному числу, я пытался, но получилось, что у меня стиралось самое первое число, а не последнее. Еще есть небольшой баг с двойной ошибкой, когда вводишь букву, вместо числа, то выдается ошибка (как и должно быть), но когда ее закрываешь, то выдается еще одна ошибка, которая уже относится к неправильности введенных данных и уже после ее закрытия все уходит. И теперь появилась небольшая проблемка с корнем, когда число целое, например корень из 4 = 2, то в калькуляторе отображается как 2.00000 (5 цифр после запятой), соответственно также с tan, cos и sin, как это исправить (кроме как обрезать цифры после запятой)? Простите за такую наглость, но вы мне очень поможете, если подскажите что делать.
AD0DE412
Lorenzo
PEHDOM
Lorenzo
как сделать кнопку, которая будет стирать по одному числу, я пытался, но получилось, что у меня стиралось самое первое число, а не последнее.
поскольку у вас в поле строка, то берете срез
 [:-1]
с значения в поле и заменяете
Lorenzo
И теперь появилась небольшая проблемка с корнем, когда число целое, например корень из 4 = 2, то в калькуляторе отображается как 2.00000 (5 цифр после запятой)
дело в том что функция sqrt, sin,cos и тд возвращают float
Вы можете отказаться от принудительного форматирования вида ‘.5f’ и тогда оно будет показывать просто 2.0
или же вам придеться написать анализатор который будет смотреть, что еcли после запятой одни нули то прводить число к int

Lorenzo
Еще есть небольшой баг с двойной ошибкой, когда вводишь букву, вместо числа, то выдается ошибка (как и должно быть), но когда ее закрываешь, то выдается еще одна ошибка, которая уже относится к неправильности введенных данных и уже после ее закрытия все уходит.
это не баг, это так вы(или не вы) запрограмировали вот этот кусок
 def calc (key):
	global memory
	if key == "=":
#исключаем написание букв
		strl = "+-0123456789*/xⁿ+/-cos sin tan"
		if calc_entry.get() [0] not in strl:
			calc_entry.delete(0, END)
			calc_entry.insert(END, "Вы ввели не число")
			messagebox.showerror("Ошибка!", "проверьте данные")
#счет
		try:
			result = eval(calc_entry.get())
			calc_entry.delete(0, END)
			calc_entry.insert(END, str(result))
		except:
			calc_entry.insert(END, "Ошибка!")
			messagebox.showerror("Ошибка!", "данные не верны")
сначала оно проверяет первый элемент(почему только первый а не все?) , если он не в числе разрешенных символов то выводит messagebox.showerror(“Ошибка!”, “проверьте данные”)
а птом оно еще делает try: и в случае ексепшина еще раз messagebox.showerror(“Ошибка!”, “проверьте данные”)
кстати это серьезная дыра в безопасности, я допустим могу ввести 2+2 and messagebox.showerror(“Hello!”, “Hello world!”) и ваш “кулькулятор” мне таки выведет “Hello world!”. А ведь я могу вместо “Hello world!” написать вообще все что угодно, хоть os.system('rm -rf /')
нелья вот так бездумно скармливать евалу чтонипопадя.
Lorenzo
Простите, но я не понял, как сделать кнопку для стирания
PEHDOM
Lorenzo
Простите, но я не понял, как сделать кнопку для стирания
АП вам и не надо, у вас есть две кнопки “Cm” и “С”, поскольку одна уже не нужно можно использовать ее, переделать, например, этот кусок elif key == ‘Cm’….
берете текст из ентри calc_entry.get() , очищаете ентри и вставляете срез (:-1)текста что взяли ранее из ентри
Lorenzo
вот весь мой код, я временно вместо Cm поставил число П и теперь хочу вместо него поставить кнопку стирания, напишите пожалуйста прямо код, который мне нужно будет просто вставить заместо кода числа П.
 # импортирование нужных библиотек
from tkinter import *
from tkinter import messagebox
from tkinter import ttk 
import math
#окно калькулятора
root = Tk()
root.title ("Калькулятор")
root.configure(background='lightgrey',bd=5)
root.resizable(False, False)
#логика калькулятора
def calc (key):
    global memory
    if key == "=":
    #исключаем написание букв
        strl = "+-0123456789*/xⁿ+/-cos sin tan п"
        if calc_entry.get() [0] not in strl:
            calc_entry.delete(0, END)
            calc_entry.insert(END, "Вы ввели не число")
            messagebox.showerror("Ошибка!", "проверьте данные")
    #счет
        try:
            result = eval(calc_entry.get())
            calc_entry.delete(0, END)
            calc_entry.insert(END, str(result))
        except:
            calc_entry.insert(END, "Ошибка!")
            messagebox.showerror("Ошибка!", "данные не верны")
    elif key == "C":
        calc_entry.delete(0, END)
    elif key == "+/-":
        if "=" in calc_entry.get():
            calc_entry.delete(0, END)
        try:
            if calc_entry.get() [0] == "-":
                calc_entry.delete(0)
            else:
                calc_entry.insert(0, "-")
        except IndexError:
            pass
    elif key == 'sin':
        res = str(format(math.sin(math.radians(float(calc_entry.get())))))
        calc_entry.insert(0, 0)
        calc_entry.delete(0, END)
        calc_entry.insert(0, res)
    elif key == "cos":
        res = str(format(math.cos(math.radians(float(calc_entry.get())))))
        calc_entry.insert(0, 0)
        calc_entry.delete(0, END)
        calc_entry.insert(0, res)
    elif key == 'tan':
        res = str(format(math.tan(math.radians(float(calc_entry.get())))))
        calc_entry.insert(0, 0)
        calc_entry.delete(0, END)
        calc_entry.insert(0, res)
    elif key == "xⁿ":
        calc_entry.insert(END, "**")
    elif key == "√2":
        res =  str(format (math.sqrt(float(calc_entry.get()))))
        calc_entry.insert(0, 0)
        calc_entry.delete(0, END)
        calc_entry.insert(END, res)
    elif key == "п":
        calc_entry.insert(0, 0)
        calc_entry.delete(0, END)
        calc_entry.insert(END, math.pi)
    else:
        if "=" in calc_entry.get():
            calc_entry.delete(0, END)
        calc_entry.insert(END, key)
#создание ячеек кнопок
bttn_list = [
    "√2", "xⁿ", "п", "C",
    "sin", "cos", "tan", "/",
    "7", "8", "9", "*",  
    "4", "5", "6", "-", 
    "1", "2", "3", "+", 
    "+/-", "0", ".", "=",
]
#функционал и вид кнопок
r = 2
c = 0
for i in bttn_list: 
    cmd = lambda x=i: calc (x)
    ttk.Button (root, text=i, command=cmd, width=7).grid(row=r, column=c)
    Button(root, text=i, command=cmd, width=6, height=2, font=('Verdana', 13), bg='white').grid(
        row=r, column=c)
    c += 1
    if c > 3:
        c = 0
        r += 1
#создание поля ввода
calc_entry = Entry(root, width=22, font=('Verdana', 16))
calc_entry.grid(row=0, column=0, columnspan=4, padx=6, pady=13)
root.mainloop ()
PEHDOM
  elif key == "п":
        res =calc_entry.get()
        calc_entry.insert(0, 0)
        calc_entry.delete(0, END)
        calc_entry.insert(END, res[:-1])
буковки уже сами поменяете
Lorenzo
теперь наконец-то все, спасибо вам огромное)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB