我有一个可以使用eval进行正常操作的计算器(python 3.4.2)。
def calculator(user_input):
if any(c not in config.valid_cal_chars for c in user_input):
print("- Invalid Equation | Bad characters")
return
elif not any(c in user_input for c in "0123456789"):
print("- Invalid Equation | No numbers found")
return
sys.stdout.write("calculating " + "-".join(gfx.load_sequence))
time.sleep(0.1)
print (" | 100%")
try:
current_ans = eval(user_input)
except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
print ("- Invalid Equation | Error")
return
config.ans = current_ans
print (current_ans)
这是config.ans,config.valid_cal_char引用的config.py:
ans = ("0.0")
valid_cal_chars = ("0123456789-+/*ansqrt() \n")
如果你想知道
是什么user_choice
变量是指,它指的是我在此函数之前的输入函数。那部分有效,所以不用担心。
但是,我想知道是否可以做这样的事情:
input equation here: 4*4 #this would be saved as the user_input variable
> 16 #the output of the equation
input equation here: sqrt(ans) #this would use the previous answer saved in config.ans (ans) and the sqrt() to find the square root of the previous printed value, so:
> 4
因此输入ans会导致:
input equation here: 1+1
> 2
input equation here: ans
> 2
使用sqrt()会导致:
input equation here: 2+2
> 4
input equation here: sqrt(4)
> 2
因此,如果您还没有得到它,sqrt()会找到输入值的平方根。 ans使用之前返回的值。所以结合两个" sqrt(ans)"将给出前一个返回值的平方根。
在背景信息不受影响的情况下,我想要做的是允许用户在计算时使用这些信息。虽然" eval"可能不起作用,我很乐意使用" exec" (知道危险)。但是,这是一个multitool.py(主文件),它导入这个文件(functions.py)以使用我在那里的所有函数,包括这个函数。
import os, sys, glob, math, random, login, gfx, config, functions, time
path = "******" #creates path to folder (can be changed by commenting this line out and creating new one)
dirs = os.listdir( path ) #not used currently
functions.load_sequence_complete()
functions.username_login()
time.sleep(0.05)
functions.password_login()
print ("\n[credentials have been verified! proceeding to main program " + "-".join(gfx.load_sequence) + "]\n")
time.sleep(0.1)
program = True
while (program == True):
user_choice = functions.choice_selecter()
functions.validate_choice(user_choice)
如果您还需要其他信息,请将其放在下面的评论或答案中,以便我可以对此进行编辑以帮助您:)
答案 0 :(得分:2)
您可以在第一种方法中执行此操作,您可以在函数的开头将ans
定义为全局,然后在eval(user_input)
的结果中定义ans
,并使用current_ans
代替def calculator(user_input):
global ans
if any(c not in config.valid_cal_chars for c in user_input):
print("- Invalid Equation | Bad characters")
return
sys.stdout.write("calculating " + "-".join(gfx.load_sequence))
time.sleep(0.1)
print (" | 100%")
try:
ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{})
except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
print ("- Invalid Equation | Error")
return
config.ans = ans
print (ans)
无处不在。
假设一切正常,你的功能会是什么样子 -
elif
请注意我摆脱了函数中的ans
部分,否则它不会让像>>> def calculator(user_input):
... global ans
... if any(c not in "0123456789-+/*ansqrt() \n" for c in user_input):
... print("- Invalid Equation | Bad characters")
... return
... time.sleep(0.1)
... print (" | 100%")
... try:
... ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{})
... except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
... print ("- Invalid Equation | Error")
... return
... print (ans)
...
>>>
>>> calculator('1+2')
| 100%
3
>>> calculator('ans')
| 100%
3
>>> from math import sqrt
>>> calculator('sqrt(ans)')
| 100%
1.7320508075688772
这样的输入通过 - 你可能会重新思考如何重写它。
示例/演示 -
ans = eval(user_input, {'ans':ans,'sqrt':sqrt},{})
虽然您也可以使用eval
作为 -
ans
这会将eval限制为仅将sqrt
和eval()
作为名称。
但是仍然应该重新考虑使用ECHO Access to this system is restricted to authorized personnel for authorized business purpose only!!
CHOICE /M "Do you want to continue"
If Errorlevel 2 GoTo N
:Y
ECHO.
ECHO You choose: YES
set /p id=Enter Name/ID:
ECHO Hello %id%
timeout /t 5
GoTo ErrorFunc
:N
Echo.
Echo You choose: NO and you are required to exit from cmd !
Echo.
ECHO EXITING IN 5 SECOND
timeout /t 5
exit
test.bat > C:\test.log
,因为即使限制了全局变量和局部变量,用户仍然会造成伤害。为什么? Check here.
答案 1 :(得分:0)
由于多种原因,Eval在这里是一个坏主意。虽然您可以通过致电:
轻松完成您所描述的内容eval(user_input, {'ans': config.ans})
您应该调查正确的表达式解析。类似pyparsing
模块的东西应该可以帮到你。您可以在此处找到该项目的示例计算器:https://github.com/pyparsing/pyparsing/blob/master/examples/fourFn.py