Форум сайта python.su
0
#!/usr/bin/python
# -*- coding: latin-1 *-
import calc;
if __name__ == "__main__":
print '============================================================================================================================';
print 'Вас приветствует приложение-калькулятор ЦЕЛЫХ чисел, которое переводит выражение в обратную польскую запись и вычисляет его'
print '============================================================================================================================';
print 'Обратная польская запись - форма записи математических выражений, в которой операнды расположены перед знаками операций.';
print 'Пример:\n обычная запись: (2+3)*4+5 \n обратная польская запись: 2 3 + 4 * 5 +';
print 'Программа работает ТОЛЬКО С ЦЕЛЫМИ ЧИСЛАМИ! При вводе отрицательного числа вводите знак минус ТОЛЬКО СЛИТНО с числом!\nПри вводе выражения соблюдайте условие, что количество операторов должно быть меньше количества операндов на 1'
print 'Допустимы следующие операции:';
print calc.operations();
print 'Введите выражение:';
while 1:
expression = (raw_input('>>'));
while not calc.check_symbols(expression):
print 'Вы ввели недопустимые символы! Повторите ввод';
expression = (raw_input('>>'));
if calc.check_brackets(expression):
print str(calc.calculate(calc.return_Polish_record(expression)));
else:
print 'Ошибка. Проверьте правильность ввода скобок'
Офлайн
0
#!/usr/bin/python
# -*- coding: latin-1 -*-
from sets import Set
import math;
AllowedOperators = { #словарь(ассоциативный массив) операторов
'-':float.__sub__, #определяем ключи к операторам,и действия которые они выполняют
'+':float.__add__,
'*':float.__mul__,
'/':float.__div__,
#'c':__cos__,
#'s':__sin__,
#'t':__tan__,
#'C':__ctg__,
# '^':float.__pow__,
}
Priority = {#словарь приоритетов операторов
's':4,
'c':4,
't':4,
'C':4,
'^':4,
'*':3,
'/':3,
'+':2,
'-':2,
'(':1,
}
def check_symbols(expression): #функция проверяет введенное выражение на корректность
allowed_symbols=Set('0123456789-+*/ ().sctC^'); #разрешимые символы для ввода
if Set(expression).issubset(allowed_symbols): #если в expression нет никаких других символов кроме разрешенных
return True; #возвращаем,что все нормально
print math.cos(5+2*2)
def allowed_nums(): #возвращает разрешимые ЦИФРЫ
return '0123456789.'
def check_brackets(expression):#проверка на баланс скобок
bracketsAmount=0 #счетчик скобок
for symbol in expression: #цикл по строке
# if bracketsAmount==-1: #если счетчик скобок равен -1,значит закрывающая скобка стоит раньше открывающей
# return False #а это неправильно,возвращаем фолс
if symbol=='(': #если символ равен открывающей скобке, прибавляем к счетчику 1
bracketsAmount+=1
elif symbol==')': #если символ равен закрывающей скобке, вычитаем единицу из счетчика
bracketsAmount-=1
if bracketsAmount!=0: #после того как все выражение пройдено, смотрим если счетчик скобок не равен нулю,значит у нас дисбаланс скобок
return False #возвращаем фолс
return True #если все нормально возвращаем тру
def operations(): #возвращает допустимые операции
return '"+" - сложение\n"-" - вычитание\n"*" - умножение\n"/" - деление\n"c" - cos\n"s" - sin\n"t" - tan\n"C" - ctg'
def calculate(expression): #функция вычисления выражения,передаваемого в обратной польской записи
stack = []; #стэк(список) для хранения чисел
number=''; #строка в которую будем записывать число, затем преобразовывать его в int , и очищать эту строку, и так с каждым числом
iter=0
if expression=='': #если ниче не ввели то возвращаем что все плохо
return 'Ошибка при вычислении.Проверьте корректность данного выражения'
for symbol in expression: #идем по строке в которой выражение
if symbol=='-': #если символ равен "-"
try: #пробуем посмотреть следующий символ
if expression[iter+1]in allowed_nums(): #смотрим ,если следующий символ после минуса число
number+=symbol #то записываем минус в строку , которая будет числом (строка ,потому что число может быть отрицательным и двузначным)
iter+=1
continue #переходим к следующему шагу цикла
except IndexError: #если не получается посмотреть,значит этот минус последний символ в строке,а следовательно он не может принадлежать числу,значит он оператор
pass #пропускаем и идем дальше
if symbol in allowed_nums(): #если символ - число
number+=symbol #то записываем его в строку, в которой будет формироваться число
iter+=1
continue #переходим к следующему шагу цикла
if number!='': #если в строке,формирующей число что-то есть
num=float(number) #то преобразуем это число в float
stack.append(num) #и записываем его в стэк
number='' #строку очищаем
if not symbol in AllowedOperators.keys(): #если символ не оператор
iter+=1
continue
try:
number2=stack.pop()
number1=stack.pop()
except IndexError:
return 'Количество операторов должно быть меньше количества операндов на 1. Возможно вы ввели минус слитно с числом';
try:
result=AllowedOperators[symbol](number1,number2)
#print str(number1)+' '+symbol+' '+str(number2);
except ZeroDivisionError:
return 'Ошибка: деление на 0'
iter+=1
stack.append(result);
if len(stack)!=1:
return 'Количество операторов должно быть меньше количества операндов на 1. Возможно вы ввели минус слитно с числом';
res=str(stack.pop())
return 'Преобразованное в ОПЗ выражение: '+expression+'\nОтвет: '+str(res);
def return_Polish_record(expression):
isSearch=False
stack = []
outstring=''
iter=0
for symbol in expression:
if symbol=='-':
try:
if expression[iter+1] in allowed_nums():
outstring+=symbol
iter+=1
continue
except IndexError:
pass
if symbol==')':
i=0
for elem in stack:
if elem=='(':
pos=i
i+=1
if pos<len(stack):
stack.pop(pos)
k=len(stack)
while k>pos:
outstring+=stack.pop()
k-=1
outstring+=') '
if symbol in allowed_nums():
try:
if expression[iter+1] in allowed_nums():
outstring+=symbol
else:
outstring+=symbol+' '
except IndexError:
outstring+=symbol+' '
if symbol=='(':
stack.append(symbol)
outstring+=' ('
if symbol in AllowedOperators.keys():
if not stack:
stack.append(symbol)
else:
if Priority[symbol]>Priority[stack[-1]]:
stack.append(symbol)
else:
cnt=0
for elem in stack:
if elem=='(':
while cnt<len(stack):
if Priority[stack[cnt]]>=Priority[symbol]:
outstring+=stack.pop(cnt)+' '
cnt+=1
stack.append(symbol)
isSearch=True
break
cnt+=1
if not isSearch:
for elem in stack:
if Priority[elem]>=Priority[symbol]:
i=0
while stack[i]!=elem:
i+=1
outstring+=stack.pop(i)+' '
stack.append(symbol)
#print outstring
#print stack
iter+=1
for elem in reversed(stack):
outstring+=elem+' '
return outstring
Офлайн
0
Всем привет. помогите пожалуйста. реализовал калькулятор, но у меня почему-то если действие вычитание, то ответ получется с минусом. Например 5 - 3 = -8, как исправить?
подскажите, как реализовать, чтобы с плавающей запятой числа тоже получались? и ещё, отчего-то иногда ответ совсем не тот, который нужен, где ошибки? помогите
import math from tkinter import * current = 0 temp = '' last ='None' def knopka1(): global temp temp += '1' #это нужно для того, чтобы к одной цифре добавлялась другая vvod.configure(text=temp) def knopka2(): global temp temp += '2' vvod.configure(text=temp) def knopka3(): global temp temp += '3' vvod.configure(text=temp) def knopka4(): global temp temp += '4' vvod.configure(text=temp) def knopka5(): global temp temp += '5' vvod.configure(text=temp) def knopka6(): global temp temp += '6' vvod.configure(text=temp) def knopka7(): global temp temp += '7' vvod.configure(text=temp) def knopka8(): global temp temp += '8' vvod.configure(text=temp) def knopka9(): global temp temp += '9' vvod.configure(text=temp) def knopka0(): global temp temp += '0' vvod.configure(text=temp) #Функции для кнопок действий def knopkaplus(): global temp global current global last current=current+int(temp) temp='' vvod.configure(text='') last='Plus' def knopkaminus(): global temp global current global last current=current-int(temp) temp='' vvod.configure(text='') last='Minus' def knopkaumnozhit(): global temp global current global last current=current*int(temp) temp='' vvod.configure(text='') last='Umnozh' def knopkadelit(): global temp global current global last current=current/int(temp) temp='' vvod.configure(text='') last='Delenie' def knopkaravno(): global last global current global temp if last == 'Plus': current=current+int(temp) elif last == 'Minus': current=current-int(temp) elif last == 'Umnozh': current=current*int(temp) elif last == 'Delenie': current=current/int(temp) vvod.configure(text=str(current)) def knopkaclear(): global temp global current temp='' current=0 vvod.configure(text='') ############## root=Tk() okno=Frame(root) okno.pack() root.title("Калькулятор") num=StringVar() main=Frame(root) main.pack() vvod=Label(okno,text='') vvod.pack() knopki=Frame() kn1=Button(knopki, text='1', padx=15, pady=15, command=knopka1) kn1.grid(row=0,column=0) kn2=Button(knopki, text='2', padx=15, pady=15, command=knopka2) kn2.grid(row=0,column=1) kn3=Button(knopki, text='3', padx=15, pady=15, command=knopka3) kn3.grid(row=0,column=2) kn4=Button(knopki, text='4', padx=15, pady=15, command=knopka4) kn4.grid(row=1,column=0) kn5=Button(knopki, text='5', padx=15, pady=15, command=knopka5) kn5.grid(row=1,column=1) kn6=Button(knopki, text='6', padx=15, pady=15, command=knopka6) kn6.grid(row=1,column=2) kn7=Button(knopki, text='7', padx=15, pady=15, command=knopka7) kn7.grid(row=2,column=0) kn8=Button(knopki, text='8', padx=15, pady=15, command=knopka8) kn8.grid(row=2,column=1) kn9=Button(knopki, text='9', padx=15, pady=15, command=knopka9) kn9.grid(row=2,column=2) kn0=Button(knopki, text='0', padx=15, pady=15, command=knopka0) kn0.grid(row=3,column=1) knopki.pack() #Создание кнопок-функций +,-,*,/ plus=Button(knopki, text='+',command=knopkaplus) plus.grid(row=0,column=4) minus=Button(knopki, text='-',command=knopkaminus) minus.grid(row=1,column=4) umnozh=Button(knopki, text='*',command=knopkaumnozhit) umnozh.grid(row=2,column=4) delenie=Button(knopki, text='/',command=knopkadelit) delenie.grid(row=3,column=4) ravno=Button(knopki, text='=',command=knopkaravno) ravno.grid(row=4,column=3) clr=Button(knopki, text='C',command=knopkaclear) clr.grid(row=4,column=2) root.mainloop()
Прикреплённый файлы:
calculator_done_full.py (4,3 KБ)
Офлайн
568
sayyes
Неправильно вообще всё. То есть вообще.
Офлайн
0
даже нечего исправлять? потраченное зря время Ж)
Офлайн
568
sayyesИсправлять есть что. Всё.
даже нечего исправлять?
Офлайн
0
делал копию по видео. пробую сам теперь
спасиб
Офлайн
568
sayyesа дайте ссылку на видео?
делал копию по видео
Офлайн
0
Офлайн
568
Во жесть то! Это надо было еще умудриться найти это видео с 30-ю просмотрами. Автор аццкий говнокодер.
sayyes
не смотри больше “обучающее видео”. Лучше книжки читай. Марк Лутц 4-е издание, например.
Офлайн