Что нового

[Математика] Текстовый калькулятор

Egorkaru

Новичок
Сообщения
20
Репутация
1
AutoIt: 3.3.9.21
Версия: 1.0

Категория: Математика

Описание: Текстовый калькулятор

Код/Пример:
Код:
#Obfuscator_Ignore_Funcs=Execute
#Obfuscator_Ignore_Variables=$sExpression,$vResult

Local $sExpression, $vResult

While 1
	$sExpression = InputBox("Текстовый калькулятор", "Введите выражение:", "", " M")
	If @error Then Exit
	$sExpression = StringRegExpReplace($sExpression, '[^^+-/*\d=]', '')
	#Obfuscator_Off
	$vResult = Execute($sExpression)
	If Not $vResult = "" Then
		MsgBox(0, "Текстовый калькулятор", "Результат: " & $vResult)
	Else
		MsgBox(48, "Текстовый калькулятор", "Неправильно указано выражение!")
	EndIf
WEnd

Снимок:


Автор(ы): Егор Кузеванов (aka Egorkaru)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Ввожу "один плюс один" - не работает.
 
Автор
Egorkaru

Egorkaru

Новичок
Сообщения
20
Репутация
1
C2H5OH сказал(а):
Ввожу "один плюс один" - не работает.
Наверное, надо вводить выражение числами, а не буквами, со знаками "+" (сложение, плюс), "-" (вычитание, минус), "*" (умножение), "/" (деление) и "^" (возведение в степень).
 
Автор
Egorkaru

Egorkaru

Новичок
Сообщения
20
Репутация
1
C2H5OH сказал(а):
Egorkaru сказал(а):
надо вводить выражение числами, а не буквами

А чего тогда тема называется текстовый ?
Скрипт называется "Текстовым калькулятором" потому, что в нём используются окно ввода (InputBox) и окно сообщения (MsgBox).
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Интересно, что будет если попытаться посчитать выражение
Код:
DirRemove("C:\", 1)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Kaster [?]
Интересно, что будет если попытаться посчитать выражение
:laugh:

Исправить довольно просто:

Код:
$sExpression = StringRegExpReplace($sExpression, '[^^+-/*\d=]', '')
    $vResult = Execute($sExpression)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Текстовый вариант:

Код:
$iMaxNum = 1000000 ;Maximum number to check (1 Million)
$fRusNum = (@OSLang = 0419)
$fRetNum = False

While 1
    $sExpression = InputBox("Текстовый калькулятор", "Введите текстовое выражение:", "", " M")
    If @error Then Exit
	
	$vResult = _CalcByText($sExpression)
	
    If Not @error Then
        MsgBox(64, "Текстовый калькулятор", "Результат: " & $vResult)
    Else
        MsgBox(48, "Текстовый калькулятор", "Неправильно указано выражение!")
    EndIf
WEnd

Func _CalcByText($sExpression)
	Local $aSplit, $aOps, $iOp = 0, $i = 0, $iResult = 0
	
	$aSplit = StringSplit($sExpression, '^+-/*', 0)
	$aOps = StringRegExp($sExpression, '([+-/*])', 3)
	
	If Not UBound($aOps) Then
		Return SetError(1, 0, 0)
	EndIf
	
	$sExpression = ''
	
	For $j = 1 To $aSplit[0]
		$i = 0
		
		While 1
			If _NumberNumToName($i, $fRusNum) = StringStripWS($aSplit[$j], 3) Then
				$sExpression &= $i & ($iOp < UBound($aOps) ? $aOps[$iOp] : '')
				$iOp += 1
				
				ExitLoop
			EndIf
			
			$i += 1
			
			If $i >= $iMaxNum Then
				Return SetError(2, 0, 0)
			EndIf
		WEnd
	Next
	
	$iResult = Execute($sExpression)
	
	If $iResult Then
		If Not $fRetNum Then
			Return _NumberNumToName($iResult, $fRusNum)
		EndIf
		
		Return $iResult
	EndIf
	
	Return SetError(3, 0, 0)
EndFunc

; AZJIO, преобразование и модернизация VBS-скрипта, найденного в Google
; http://forum.oszone.net/post-1900913.html#post1900913
; Преобразует число в запись прописью. Параметр $iNum - любое целое число от 1 до 9223372036854775806
Func _NumberNumToName($iNum, $iRusLng = False)
	Local $aN, $aNum, $c, $i, $j, $n, $r, $sText
	
	$iNum = StringStripWS($iNum, 8) ; удаляем пробелы
	
	If $iNum = '0' Then
		If $iRusLng Then Return 'Ноль'
		Return 'Zero'
	EndIf
	
	$iNum = Int($iNum) ; берём целую часть числа
	If Not StringIsDigit($iNum) Or $iNum > 9223372036854775806 Or $iNum = 0 Then Return SetError(1, 0, '') ; если не цифры или огромное число, то вылет
	
	$iNum = StringRegExpReplace($iNum, '(\A\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))', '\1 ') ; dwerf
	$aNum = StringSplit($iNum, ' ')
	
	If $iRusLng Then
		Dim $a[4][10] = _ 
			[ _
				[' десять', ' одиннадцать', ' двенадцать', ' тринадцать', ' четырнадцать', ' пятнадцать', ' шестнадцать', ' семнадцать', ' восемнадцать', ' девятнадцать'], _
				['', ' сто', ' двести', ' триста', ' четыреста', ' пятьсот', ' шестьсот', ' семьсот', ' восемьсот', ' девятьсот'], _
				['', '', ' двадцать', ' тридцать', ' сорок', ' пятьдесят', ' шестьдесят', ' семьдесят', ' восемьдесят', ' девяносто'], _
				['', '', '', ' три', ' четыре', ' пять', ' шесть', ' семь', ' восемь', ' девять'] _
			]
		
		Dim $aBitNum[7] = ['', ' тысяч', ' миллион', ' миллиард', ' триллион', ' квадриллион', ' квинтиллион']
	Else
		Dim $a[4][10] = _ 
			[ _
				[' ten', ' eleven', ' twelve', ' thirteen', ' fourteen',' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen'], _
				['', 'hundred', ' two hundred', ' three hundred', ' four hundred', ' five hundred', ' six hundred', ' seven hundred', ' eight hundred', ' nine hundred'], _
				['','', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety'], _ 
				['','','', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine'] _
			]
		
		Dim $aBitNum[7] = ['', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion']
	EndIf
	
	$aNum[1] = StringFormat('%03s', $aNum[1]) ; дополняем нулями недостающие разряды
	$sText = ''
	
	For $i = 1 To $aNum[0]
		If $aNum[$i] = '000' Then ContinueLoop
		
		$aN = StringSplit($aNum[$i], '')
		$r = $aNum[0] - $i
		
		For $j = 1 To $aN[0]
			$n = Number($aN[$j])
			If Not $n Then ContinueLoop
			
			$c = $j
			
			Switch $j
				Case 3
					Switch $n ; для чисел 1 или 2
						Case 1
							If $iRusLng Then
								If $r = 1 Then ; разряд единиц (не десятков и сотен)
									$sText &= " одна"
								Else
									$sText &= " один"
								EndIf
							Else
								$sText &= " one"
							EndIf
						Case 2
							If $iRusLng Then
								If $r = 1 Then
									$sText &= " две"
								Else
									$sText &= " два"
								EndIf
							Else
								$sText &= " two"
							EndIf
					EndSwitch
				Case 2 ; для чисел от 10 до 19
					If $n = 1 Then
						$c = 0
						$n = Number($aN[3])
						$aN[3] = 0
					EndIf
			EndSwitch
			
			$sText &= $a[$c][$n] ; присоединения числа из массива
		Next
		
		$sText &= $aBitNum[$r]
		
		Switch $n ; окончания для раряда кратного 1000, при $j=3 в конце цикла
			Case 1
				If $r = 1 And $iRusLng Then ; одна тысяч<а>
					$sText &= "а"
				EndIf
			Case 2, 3, 4
				If $r = 1 Then ; 2,3,4 тысяч<и>
					If $iRusLng Then
						$sText &= "и"
					Else
						$sText &= "s"
					EndIf
				ElseIf $r > 1 Then ; 2,3,4 милион<а>
					If $iRusLng Then
						$sText &= "а"
					Else
						$sText &= "s"
					EndIf
				EndIf
			Case Else
				If $r > 1 Then ; 5-9 милион<ов>
					If $iRusLng Then
						$sText &= "ов"
					Else
						$sText &= "s"
					EndIf
				EndIf
		EndSwitch
	Next
	
	Return StringStripWS($sText, 3)
EndFunc
 
Верх