Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/140: Рейтинг темы: голосов - 140, средняя оценка - 4.54
84 / 1 / 0
Регистрация: 14.11.2019
Сообщений: 14

Калькулятор для строковых выражений

14.11.2019, 12:19. Показов 27132. Ответов 18

Студворк — интернет-сервис помощи студентам
Мне нужно написать калькулятор для строковых выражений. <число> <операция> <число> числа не отрицательные до 100.
То есть пользователь вводит например "тридцать три плюс десять" и получает ответ "сорок три".
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.11.2019, 12:19
Ответы с готовыми решениями:

Калькулятор выражений в обратной польской записи
Напишите калькулятор выражений в обратной польской записи. В выражении должны поддерживаться числа, знаки бинарных операций ‘+’, ‘-’, ‘*’,...

Калькулятор логических выражений
Доброго дня граждане питонисты, у меня появилась задача написать калькулятор логических выражений на Python, при этом он должен выдавать в...

Калькулятор логических выражений
Доброго дня граждане питонисты, у меня появилась задача написать калькулятор логических выражений на Python, при этом он должен выдавать в...

18
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
14.11.2019, 12:24
Попробуйте регулярными выражениями разобрать строку на части.
Code
1
2
3
<сотни1><десятки1><единицы1(до19)> 
<операция> 
<сотни2><десятки2><единицы2(до19)>
Затем выполнить вычисления
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
14.11.2019, 16:25
Python
1
2
3
4
>>> '1+2'.partition('+')
('1', '+', '2')
>>> '115+2'.partition('+')
('115', '+', '2')
Добавлено через 22 секунды
Или человек вводит русские буквы?
0
5042 / 1069 / 149
Регистрация: 29.01.2013
Сообщений: 6,248
14.11.2019, 16:25
Рыжий Лис, суть проблемы в том, что входные данные:
Цитата Сообщение от spectr1231 Посмотреть сообщение
"тридцать три плюс десять"
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
14.11.2019, 16:41
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
s = 'один плюс ноль'
 
ls = s.split(' ')
 
d1 = {
    'ноль': 0,
    'один': 1,
    #…
    'двенадцать': 12,
    #…
    'девятьнадцать': 19,
}
d_op = {
    'плюс': lambda x, y: x + y,
    #…
}
 
i = 0
try:
    e1 = d1[ls[i]]
except KeyError:
    raise NotImplementedError
i += 1
 
try:
    func = d_op[ls[i]]
except KeyError:
    raise ValueError('ожидался оператор, найдена ересь: "%s"' % ls[i])
i += 1
 
try:
    e2 = d1[ls[i]]
except KeyError:
    raise NotImplementedError
i += 1
 
if i != len(ls):
    raise ValueError('найдена ересь: "%s"' % ls[i:])
 
r = func(e1, e2)
print(r)
Хотя, наверное, правильнее разбивать строку по словам "плюс"/"минус" итд.

Добавлено через 4 минуты
Тогда предлагаю ТСу начать писать функции по парсингу строк вида "двадцать один" в числа и обратно.
1
84 / 1 / 0
Регистрация: 14.11.2019
Сообщений: 14
14.11.2019, 19:33  [ТС]
Проблема не в самом составлении кода для строкового калькулятора, я не понимаю как мне грамотно перевести числа написанные буквами в цифры.
Я учусь только на первом курсе поэтому не сильно понимаю. Я думал создать словарь и с помощью get переводить числа, но у меня не получилось.
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
14.11.2019, 19:42
Для начала разбей строку по разделителю "плюс"/"минус" итд. Получится две строки.

Допустим
Python
1
2
3
el1 = "двадцать один"
op = "плюс"
el3 = "один"
А дальше передаём строку в функцию. Да, там можно и словарём обойтись. Только сделать проверку, что слово одно. Если два, то чуть сложнее будет. Попробуй пока написать код для чисел от 0 до 19.
1
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
15.11.2019, 07:13
Цитата Сообщение от spectr1231 Посмотреть сообщение
Я думал создать словарь и с помощью get переводить числа, но у меня не получилось.
А что не получилось? Напишите, как Вы попробовали решить.
Для чисел из одного слова получаете значение из словаря. Для чисел из нескольких слов просто суммируете значения однословных чисел.
Code
1
value['сорок'] + val['семь']
Для чисел меньше 2000 должно сработать.
0
84 / 1 / 0
Регистрация: 14.11.2019
Сообщений: 14
20.11.2019, 20:30  [ТС]
привет, извини что так долго не отвечал, писал рефераты
вот что у меня получилось


Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
digit={"один":1,"два":2,"три":3,"четыре":4,"пять":5,"шесть":6,"семь":7,"восемь":8,"девять":9,\
    "одиннадцать":11,"двенадцать":12,"тринадцать":13,"четырнадцать":14,"пятнадцать":15,"шестнадцать":16,"семнадцать":17,"восемнадцать":18,"девятнадцать":19,\
    "десять":10,"двадцать":20,"тридцать":30,"сорок":40,"пятьдесят":50,"шестьдесят":60,"семьдесят":70,"восемьдесят":80,"девяносто":90,\
    'плюс':'+','минус':'-','умножить':'*', 'делить':'/', 'степени':'**'}
 
 
 
 
 
def calc(mat_example=str(input('input expamle: ')).split(' ')):
    
    ls=list(mat_example)
 
    del1=''.join(ls)
    
    
    try:
        delete=del1.find('на')
        if delete!=0:
            ls.remove('на')
    except:
        pass
 
    try:
        delete1=del1.find('в')
        if delete1!=0:
            ls.remove('в')
    except:
        pass
    
    count=len(ls)
    
 
    for i in range (0,count):
        ls[i]=digit.get(ls[i])
 
    
    
    if count==3:
        if ls[1]=='+':
            answer=ls[0]+ls[2]
        elif ls[1]=='-':
            answer=ls[0]-ls[2]
        elif ls[1]=='*':
            answer=ls[0]*ls[2]
        elif ls[1]=='/':
            answer=ls[0]/ls[2]
        elif ls[1]=='**':
            answer=ls[0]**ls[2]
            
    
    elif count==5:
        y1=ls[0]+ls[1]
        y2=ls[3]+ls[4]
        if ls[2]=='+':
            answer=y1+y2
        elif ls[2]=='-':
            answer=y1-y2
        elif ls[2]=='*':
            answer=y1*y2
        elif ls[2]=='/':
          answer=y1/y2
        elif ls[2]=='**':
            answer=y1**y2
          
    elif count==4:
        if ls[1]=='+' or ls[1]=='-' or ls[1]=='*':
            y2=ls[2]+ls[3]
            if ls[1]=='+':
                answer=ls[0]+y2
            elif ls[1]=='-':
                answer=ls[0]-y2
            elif ls[1]=='*':
                answer=ls[0]*y2
            elif ls[2]=='/':
                answer=ls[0]/y2
            elif ls[2]=='**':
                answer= ls[0]**y2
        elif ls[2]=='+' or ls[2]=='-' or ls[2]=='*':
            y1=ls[0]+ls[1]
            if ls[1]=='+':
                answer=y1+ls[3]
            elif ls[1]=='-':
                answer=y1-ls[3]
            elif ls[1]=='*':
                answer=ls[3]*y1
            elif ls[1]=='/':
                answer=y1/ls[3]
            elif ls[1]=='**':
                answer==y1**ls[3]
    
    
    
    
    return round(answer,3)
 
print(calc())
1
84 / 1 / 0
Регистрация: 14.11.2019
Сообщений: 14
21.11.2019, 18:02  [ТС]
мне теперь надо сделать так чтобы ответ выводился в буквенной форме, и мне кажется, что сам код написан не грамотно
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
21.11.2019, 18:17
Цитата Сообщение от spectr1231 Посмотреть сообщение
и мне кажется, что сам код написан не грамотно
Согласен. Ну пусть пока будет таким.

Вторую часть сделать легко. Пусть будет функция (почему бы и нет?)
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
dig1 = {
    0: 'ноль',
    1: 'один',
    #…
    19: 'девятнадцать',
}
dig2 = {
    2: 'двадцать',
    3: 'тридцать',
    #…
}
 
def int2str(i):
    if i < 0:
        return '<0'
    if i < 20:
        return dig1[i]
    if i >= 100:
        return '>100'
    # двузначное число
    d2 = i // 10
    d1 = i % 10
    if d1 == 0:
        return dig2[d2]
    return dig2[d2] + ' ' + dig1[d1]
 
print(int2str(21))
2
84 / 1 / 0
Регистрация: 14.11.2019
Сообщений: 14
21.11.2019, 20:13  [ТС]
а есть функция обратная get, а то второй словарь создавать не супер?
0
Просто Лис
Эксперт Python
 Аватар для Рыжий Лис
5973 / 3735 / 1099
Регистрация: 17.05.2012
Сообщений: 10,791
Записей в блоге: 9
22.11.2019, 05:04
Нет, но можно перевернуть словарь

Python
1
2
3
4
5
6
>>> d = {0:'ноль', 1:'один'}
>>> d
{0: 'ноль', 1: 'один'}
>>> d2 = {v:k for k, v in d.items()}
>>> d2
{'один': 1, 'ноль': 0}
Python
1
2
3
4
5
6
>>> d2 = {}
>>> for k, v in d.items():
...    d2[v] = k
... 
>>> d2
{'один': 1, 'ноль': 0}
2
0 / 0 / 0
Регистрация: 05.11.2022
Сообщений: 11
05.11.2022, 22:12
Удалось ли доделать калькулятор? сейчас получил то же задание и единственное место, где я нашел что-то по теме это данный форум.
0
06.11.2022, 09:25

Не по теме:

Ramdy, не беспокойтесь, у нас всё получилось и работает.

0
0 / 0 / 0
Регистрация: 05.11.2022
Сообщений: 11
06.11.2022, 13:17
Рыжий Лис, в предложенном решении у меня не работают операции с числами, которые состоят из двух слов (по типу двадцать пять, тридцать семь и тд). Думал возможно осталось полное решение.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
07.11.2022, 07:27
Ramdy, достаточно просто разбить такие числа на слова, перевести каждое в число и сложить результаты.
0
2 / 2 / 0
Регистрация: 09.06.2021
Сообщений: 3
09.11.2022, 00:30
Кстати, в условии нигде не сказано, что результат положительный и меньше 100. Условие говорит, что операнды меньше 100 и больше 0, а 99*99 это на минуточку 9801, а 98-99=-1
1
2 / 2 / 0
Регистрация: 09.06.2021
Сообщений: 3
10.11.2022, 12:23
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def calculate(expression):
    plus = lambda x,y: x+y
    minus = lambda x,y: x-y
    multiply = lambda x,y: x*y
    dictOfStrings = {'девяносто': 90,'восемьдесят': 80,'семьдесят': 70, 'шестьдесят': 60, 'пятьдесят': 50,
                     'сорок': 40,'тридцать': 30, 'двадцать': 20, 'девятнадцать': 19, 'восемнадцать': 18,
                     'семнадцать': 17, 'шестнадцать': 16, 'пятнадцать': 15, 'четырнадцать': 14,'тринадцать': 13,
                     'двенадцать': 12, 'одиннадцать': 11, 'десять': 10, 'девять': 9, 'восемь': 8, 'семь': 7,
                     'шесть': 6, 'пять': 5, 'четыре': 4, 'три': 3, 'два': 2, 'один': 1, 'ноль': 0,
                     'плюс': plus, 'минус': minus, 'умножить': multiply}
    
    dictOfNums = {9000: 'девять тысяч', 8000: 'восемь тысяч', 7000: 'семь тысяч', 6000: 'шесть тысяч',
                  5000: 'пять тысяч', 4000: 'четыре тысячи', 3000: 'три тысячи', 2000: 'две тысячи',
                  1000: 'одна тысяча', 900:'девятьсот', 800:'восемьсот', 700:'семьсот', 600:'шестьсот',
                  9500:'пятьсот', 400:'четыреста', 300:'триста', 200:'двести', 100:'сто',
                  90:'девяноста', 80:'восемьдесят', 70:'семдесят', 60:'шестьдесят', 50:'пятьдесят',
                  40:'сорок', 30:'тридцать', 20:'двадцать', 19:'девятнадцать', 18:'восемнадцать',
                 17:'семнадцать', 16:'шестнадцать', 15:'пятнадцать', 14:'четырнадцать', 13:'тринадцать',
                 12:'двенадцать', 11:'одиннадцать', 10:'десять', 9:'девять', 8:'восемь', 7:'семь',
                 6:'шесть', 5:'пять', 4:'четыре', 3:'три', 2:'два', 1:'один', 0:''}
    expressionList = []
    operatorPosition = 0
    for i,item in enumerate(expression.split()):
        try:
            expressionList.append(dictOfStrings[item])
            if isinstance(dictOfStrings[item], type(lambda: None)):
                operatorPosition = i 
        except:
            return 'Ошибка ввода выражения'
    
    try:
        resultNum = expressionList[operatorPosition](sum(expressionList[:operatorPosition]),
                                           sum(expressionList[operatorPosition+1:]))
        resultList = []
        
        if resultNum < 0:
            resultList.append('минус')
            resultNum = abs(resultNum)
        elif resultNum == 0:
            return 'ноль'      
                
        for i in reversed(range(1,4)):
            j = resultNum//10**i*10**i
            if j == 0:
                continue
            elif (j < 20) & (i==1):
                resultList.append(dictOfNums[resultNum])
                break
            else:
                resultList.append(dictOfNums[j])
            resultNum -= j
        else:
            resultList.append(dictOfNums[resultNum])
        return ' '.join(resultList)
 
        
    except:
        return 'Ошибка ввода выражения'
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.11.2022, 12:23
Помогаю со студенческими работами здесь

Калькулятор для больших арифметических выражений
Здравствуйте, хочу сделать калькулятор в Visual Basic 2010, который считает большие арифметические выражения, к примеру (2*2+2^2)/2*5 =20. ...

Калькулятор для расчета сложных выражений
в общем вот что у меня есть Добавлено через 3 минуты #include &lt;iostream&gt; #define PI 3.14159265 using namespace std; void...

Обработка строковых выражений
Здравствуйте , мне дали задание по информатике написать программу для проверки баланса левых и правых скобок в заданом тексте , в...

Создать калькулятор для вычисления математических выражений
Добрый день. Стоит задача сделать калькулятор который будет при вводе выражения. Например 2+2(2+3) выводить ответ. тобешь чему...

Калькулятор для выражений с префиксной формой записи
Было задание написать такой калькулятор, написал. Вроде бы считает, даже пример из википедии правильно посчитал. Кто разбирается в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru