473,605 Members | 2,703 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How do I convert arithemtic string (like "2+2") to a number?

Hello, I need to convert a string to a number, but the string can
contain +,-,* and / as well as parenthesis. For example, if I have the
string "30/(6+9)" I would like a function that returned the number 2.

I actually wrote a java function that did this a couple of years ago, in
school, as an excersise in "binary trees". I lost it, and most of my
programming knowledge, but I figured perhaps there is a way to do this
easily in python? It seems to me like it could be a common problem.

/Arvid Andersson
Jul 18 '05 #1
8 2330
Use the eval function:
eval("30/(6+9)")

2

Michael

Jul 18 '05 #2
On Sat, Feb 05, 2005 at 02:11:07PM -0800, Michael Hartl wrote:
Use the eval function:
eval("30/(6+9)")

2


Thanks, just what I was looking for!

Jul 18 '05 #3
On Sat, 2005-02-05 at 17:11, Michael Hartl wrote:
Use the eval function:
eval("30/(6+9)")

2

Michael


Sure, if you trust the source of the string you are evaluating. If this
is a form submission on your web site, be wary of the nefarious user who
might submit to you:

commands.getout put( "rm -rf %(HOME)s"%os.en viron )

as the "expression " to evaluate.
Adam DePrince
Jul 18 '05 #4
Adam brings up a good point: eval is a very general function which
evaluates an arbitrary Python expression. As a result, it (and its
close cousin exec) should be used with caution if security is an issue.

Michael

Jul 18 '05 #5
Michael Hartl wrote:
Adam brings up a good point: eval is a very general function which
evaluates an arbitrary Python expression. As a result, it (and its
close cousin exec) should be used with caution if security is an issue.


To get a secure eval for simple mathematical expressions, it should
suffice to check the string in the following way:

It does not contain characters other than operators, numbers, dots and
parentheses (perhaps you want to allow 'e' for floats, but you should
make sure that the 'e' is surrounded by numbers or optionally followed
by a +/- sign).

If you want to go a step further, you could parse the string to eval
with the parser/tokenize/... modules and verify the parse tree that it
contains nothing except operators and numbers.

Reinhold
Jul 18 '05 #6
Well, a bit more secure would be

eval(expression , {'__builtins__' : {}}, {})

or alike.

Jul 18 '05 #7
"Adomas" <ad************ ******@gmail.co m> writes:
Well, a bit more secure would be

eval(expression , {'__builtins__' : {}}, {})

or alike.


Don't believe this without (or even with ;-) very careful thought,
anyone. Google for rexec.
John
Jul 18 '05 #8
John J. Lee wrote:
"Adomas" <ad************ ******@gmail.co m> writes:

Well, a bit more secure would be

eval(expressi on, {'__builtins__' : {}}, {})

or alike.

Don't believe this without (or even with ;-) very careful thought,
anyone. Google for rexec.
John

This module provides a more systematic way to set up restricted evaluation:
"""Restrict ed evaluation

Main entry point: r_eval()
For usage see class tests or run them using testall()"""
import types
import compiler
import operator

import sys, os # used only for testing

ast = compiler.ast

class Eval_Error(Exce ption):
def __init__(self,e rror,descr = None,node = None):
self.error = error
self.descr = descr

def __repr__(self):
return "%s: %s" % (self.error, self.descr)
__str__ = __repr__
class AbstractVisitor (object):
"""Standard depth-first AST walker - dispatches to methods
based on Node class name"""
def __init__(self):
self._cache = {} # dispatch table

def visit(self, node,**kw):
if node is None: return None
cls = node.__class__
meth = self._cache.set default(cls,
getattr(self,'v isit'+cls.__nam e__,self.defaul t))
return meth(node, **kw)

def default(self, node, **kw):
for child in node.getChildNo des():
return self.visit(chil d, **kw)
visitExpression = default

class Eval(AbstractVi sitor):
"""An AST walker that implements a replacement to built-in eval.

See r_eval for entry point/usage.

Provides hooks for managing name resolution, proxying objects,
and controlling attribute access

Does not implement:
List Comprehensions, Generator Expressions, Lambda
Ellipsis (can this be used without numpy?)
"""
def __init__(self, context = globals()):
super(Eval,self ).__init__()
self.context = context

# Namespace interface. Safe implementations should override these methods
# to implement restricted evaluation. This implementation simply
# evals the name in self.context and provides no proxying or
# attribute lookup restrictions

def lookup(self, objname):
"""Called only by visitName. Raise an exception here
to prevent any direct name resolution, but note that
objects may be returned by callables or attribute lookups"""
return eval(objname, self.context)

def getObject(self, obj):
"""Called by all name resolvers and by CallFunc. Provides
a hook for proxying unsafe objects"""
return obj

def getAttribute(se lf,obj,attrname ):
"""Called by visitGetattr"""
return getattr(obj,att rname)

# End Namespace interface
# Syntax nodes follow by topic group. Delete methods to disallow
# certain syntax.

# Object constructor nodes
def visitConst(self , node, **kw):
return node.value
def visitDict(self, node,**kw):
return dict([(self.visit(k), self.visit(v)) for k,v in node.items])
def visitTuple(self ,node, **kw):
return tuple(self.visi t(i) for i in node.nodes)
def visitList(self, node, **kw):
return [self.visit(i) for i in node.nodes]
def visitSliceobj(s elf,node,**kw):
return slice(*[self.visit(i) for i in node.nodes])
def visitEllipsis(s elf,node,**kw):
raise NotImplementedE rror, "Ellipsis"

# Binary Ops
def visitAdd(self,n ode,**kw):
return self.visit(node .left) + self.visit(node .right)
def visitDiv(self,n ode,**kw):
return self.visit(node .left) / self.visit(node .right)
def visitFloorDiv(s elf,node,**kw):
return self.visit(node .left) // self.visit(node .right)
def visitLeftShift( self,node,**kw) :
return self.visit(node .left) << self.visit(node .right)
def visitMod(self,n ode,**kw):
return self.visit(node .left) % self.visit(node .right)
def visitMul(self,n ode,**kw):
return self.visit(node .left) * self.visit(node .right)
def visitPower(self ,node,**kw):
return self.visit(node .left) ** self.visit(node .right)
def visitRightShift (self,node,**kw ):
return self.visit(node .left) >> self.visit(node .right)
def visitSub(self,n ode,**kw):
return self.visit(node .left) - self.visit(node .right)

# Unary ops
def visitNot(self,n ode,*kw):
return not self.visit(node .expr)
def visitUnarySub(s elf,node,*kw):
return -self.visit(node .expr)
def visitInvert(sel f,node,*kw):
return ~self.visit(nod e.expr)
def visitUnaryAdd(s elf,node,*kw):
return +self.visit(nod e.expr)

# Logical Ops
def visitAnd(self,n ode,**kw):
return reduce(lambda a,b: a and b,[self.visit(arg) for arg in node.nodes])
def visitBitand(sel f,node,**kw):
return reduce(lambda a,b: a & b,[self.visit(arg) for arg in node.nodes])
def visitBitor(self ,node,**kw):
return reduce(lambda a,b: a | b,[self.visit(arg) for arg in node.nodes])
def visitBitxor(sel f,node,**kw):
return reduce(lambda a,b: a ^ b,[self.visit(arg) for arg in node.nodes])
def visitCompare(se lf,node,**kw):
comparisons = {
"<": operator.lt, # strictly less than
"<=": operator.le,# less than or equal
">": operator.gt, # strictly greater than
">=": operator.ge, # greater than or equal
"==": operator.eq, # equal
"!=": operator.ne, # not equal
"<>": operator.ne, # not equal
"is": operator.is_, # object identity
"is not": operator.is_not # negated object identity
}
obj = self.visit(node .expr)
for op, compnode in node.ops:
compobj = self.visit(comp node)
if not comparisons[op](obj, compobj):
return False
obj = compobj
return True
def visitOr(self,no de,**kw):
return reduce(lambda a,b: a or b,[self.visit(arg) for arg in node.nodes])
# Name resolution
def visitGetattr(se lf,node,**kw):
obj = self.visit(node .expr)
return self.getAttribu te(obj,node.att rname)

def visitName(self, node, **kw):
return self.lookup(nod e.name)

def visitSlice(self ,node,**kw):
obj = self.visit(node .expr)
objslice = obj[self.visit(node .lower):self.vi sit(node.upper)]
return self.getObject( objslice)

def visitSubscript( self,node,**kw) :
obj = self.visit(node .expr)
subs = node.subs
if len(subs) > 1:
raise NotImplementedE rror, "Subscript must be integer or slice"
assert node.flags == "OP_APPLY"
return self.getObject( operator.getite m(obj,self.visi t(subs[0])))
# Callables
def visitCallFunc(s elf,node,**kw):
func = self.visit(node .node)

args = node.args
kwargs = self.visit(node .dstar_args) or {}
posargs = []
for arg in node.args:
if isinstance(arg, ast.Keyword):
keyword, value = self.visit(arg)
if keyword in kwargs:
raise TypeError, "%s() got multiple values for keyword
argument '%s'" \
% (func,keyword)
kwargs[keyword] = value
else:
posargs.append( self.visit(arg) )
posargs.extend( node.star_args or [])

return self.getObject( func(*posargs,* *kwargs))

def visitKeyword(se lf,node,**kw):
return node.name, self.visit(node .expr)

# Miscellaneous

def visitBackquote( self, node, **kw):
return repr(self.visit (node.expr))

# Function/class definition

def visitLambda(sel f, node, **kw):
raise NotImplementedE rror, "Lambda"

# Iterator evaluations

def visitGenExpr(se lf,node,*kw):
raise NotImplemetedEr ror, "GenExpr"
def visitListComp(s elf,node,*kw):
raise NotImplemetedEr ror, "ListComp"

# Some unexpected node type
def default(self, node, **kw):
raise Eval_Error("Uns upported source construct",
node.__class__, node)


def r_eval(source, context = None):
"""eval partial replacement,

Does not implement:
List Comprehensions, Generator Expressions, Lambda. Ellipsis

"""

walker = Eval(context or globals())
try:
ast = compiler.parse( source,"eval")
except SyntaxError, err:
raise
try:
return walker.visit(as t)
except Eval_Error, err:
raise
class tests(object):

def run(self):
"""Run all the tests"""
for name in dir(self):
if name.startswith ("test_"):
getattr(self,na me)()
print "%s: OK" % name

def test_const(self ):
cases = ["""[1, 2, 'Joe Smith', 8237972883334L, # comment
{'Favorite fruits': ['apple', 'banana', 'pear']}, # another comment
'xyzzy', [3, 5, [3.14159, 2.71828, []]]]"""]
for case in cases:
assert eval(case) == r_eval(case)

def test_algebra(se lf):
"""Show that r_eval matches eval on constant expressions"""
cases = [
"1+2/3 * 4.0 ** 5 % 2",
"(4 << 2 | 67 >> 2) ^ 0xFF",
]
for case in cases:
assert eval(case) == r_eval(case)
def test_names(self ):
cases = [
"sum",
"sys.module s['os']",
]
for case in cases:
assert eval(case) == r_eval(case)

def test_calling(se lf):
cases = [
"getattr(object , 'subclasses'.jo in(['_'*2]*2))",
"type('Name ', dict = {'a':1}, bases = (object,)).a",
"type(**dict(di ct = {'a':1}, name = 'Name', bases = (object,))).a"
]
for case in cases:
assert eval(case) == r_eval(case)
def testall():
tests().run()

Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1790
by: questioner | last post by:
Hi folks, Id appreciate if you can help: I want to start an exe which takes as an argument filename. What I tried was: os.spawnl(os.P_NOWAIT,('processor.exe'),'filename.ext')) I also tried: os.execl(r'DRIVE:\WINNT\system32\cmd.exe',
3
4199
by: Alastair | last post by:
Hello guys, I've been building a search facility for an intranet site I'm part of developing and we've been building a search engine using Index Server. It mostly works, however there have been a few niggling problems and fixing it seems to be a case of patching errors as we find them so I'm thinking that it might be worth starting the logic from scratch and rebuilding this again. Basically we have a simple search, which is simply a...
11
439
by: Marc Le Roy | last post by:
Hello, ADA Ravenscar is a restricted subset of the ADA language that has been defined for real-time software development in safety critical applications. Completed with additional restrictions like the ones defined in the SPARK profile, it allow to build very deterministic applications that support automatic static code analysis and schedulability analysis. http://www.acm.org/pubs/articles/proceedings/ada/289524/p1-dobbing/p1-dobbing.pdf...
4
1696
by: KatB | last post by:
Hi, I'm creating an asp.net application and one of the functions I need is to click on a "Where Is This Office Located?" button. In a table, each employee will have an office code location entered. I then need to have the office layout image load and have the name of that person highlighted such as bold/red (in the correct office location). Similar to an image map, but not quite. I do not want to click on an office "hotspot" and go...
8
1661
by: DQ dont quit | last post by:
I'm currently working on a ASP.Net / C# / SQL 2000 project that involves the entering of keywords, that a web user enters, and then searching MSWord documents for those words. This information will then be used to perform weighted searches on the keywords and text of multiple MSWord documents. How might this best be accomplished? Should I perform Full Text Searches on the Word files or store the data in a database (by coping and pasting...
3
1388
by: moi | last post by:
Hello, When user write a decimal number in a textbox with the numeric pad, he hits the "." button but in FRANCE, we use the ",". How to change the "." in the textbox with a "," ? Example : user write "34.45" and i would like "34,45" to be in the database (else i have a data type error) ... Is there two method ? with or without autopostback ? What's the best ? Thanks a lot !
4
1021
by: andreas | last post by:
F.e. I want to make a stringvariable str = "nr1 nr2 nr3" that it should display like "nr1 nr2 nr3" str = """ & str & """ do not work. Thanks for any response
11
6386
by: Bruce Lawrence | last post by:
Ok, I'm baffled... I'm making a query in access 97 between 2 tables. There is a field in both tables called "DWGNO". OPENORD has a record with a DWGNO of "00000012345" DIEDATA has a record with a DWGNO of "12345" I'm not doing this with VBA right now. I'm doing it through the query gui.
1
1551
by: unamas | last post by:
hi, Good day! Anyone generous enough to help me with this query. Anyway, I have a random acount number of 1, 2, 3, 4, 5 and i wanna get the results after this number in a table. Select * from table where account like ('1%','2%', '3%','4%','5%')
0
7934
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8424
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8415
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8286
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6742
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5445
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3912
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2438
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
1270
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.