What is wrong with thiis code. I am trying to write a program of infix to postfix conversion in python - stack

infix to postfix conversion using python
I am using deque for creating stack
from collections import deque
class Infix_to_prefix:
def __init__(self):
self.container = deque()
self.output = deque()
def push(self,val):
self.container.append(val)
def pop(self):
self.container.pop()
def peek(self):
return self.container[-1]
def is_empty(self):
if len(self.container)==0:
return True
else:
return False
def is_operator(self, ch):
if ch in "+-*/^":
return True
else:
return False
def is_operand(self,ch):
if (ch>='A' and ch<='Z') or (ch>='a' and ch<='z'):
return True
else:
False
def ranking(self, top, ch):
rank = {
'+': 1,
'-': 1,
'*': 2,
'/': 2,
'^': 3
}
if rank[top]<rank[ch]:
return True
else:
return False
def Conversion(self, exp):
for ch in exp:
if self.is_operand(ch):
self.output.append(ch)
elif self.is_operator(ch):
while True:
if self.is_empty():
self.push(ch)
else:
top = self.peek()
if top == '(':
self.push(ch)
break
elif self.ranking(top, ch):
self.push(ch)
break
else:
cpop = self.pop()
self.output.append(cpop)
elif ch == '(':
self.push(ch)
elif ch == ')':
cpop = self.pop()
while cpop!='(':
self.output.append(cpop)
cpop = self.pop()
while not self.is_empty():
cpop = self.pop()
self.output.append(cpop)
print(("").join(self.output))
exp = "a+b*(c^d-e)^(f+g*h)-i"
s = Infix_to_prefix()
s.Conversion(exp)
When I am running this code it just keep running.
Is there is another method or another program for solving infix to postfix.
point out what is wrong in this code.
Please ignore from this line
also tell me why stack flow always keeps telling me to add some more detail every time i atry to ask a question.

Related

Why is this string not splitting in lua

So I am working on a project and I need to split a string that would look something like this:
if (x == 2){ output("Hello") }
This is my code:
local function splitIfStatement(str)
local t = {}
t[1] = ""
t[2] = ""
t[3] = ""
local firstSplit = false
local secondSplit = false
local thirdSplit = false
str:gsub(".", function(c)
if c == "(" then
firstSplit = true
end
if firstSplit == true then
if c == "=" then
firstSplit = false
secondSplit = true
else
if c == "(" then
else
t[1] = t[1] .. c
end
end
end
if secondSplit == true then
if c == ")" then
secondSplit = false
thirdSplit = true
else
if c == "=" then
else
t[2] = t[2] .. c
end
end
end
end)
return t
end
I need to split the string at "(" so t[1] is only equal to "x" and t[2] is equal to 2 and then t[3] is equal to the "output()"
But when I run my code(note I haven't added the t[3]) t[1] returns: "x "Hello") }" and t[2] returns 2 like it should.
Anyways why isn't the split function working on the first split but it works on the second.
Thanks!
In your loop you set firstSplit true if it hits a ( this happens in 2 places in your example, before x and right before "Hello"
you can fix this by setting firstSplit true and ignore the leading if ( before you beginning the loop. Then you allow the logic you have to handle the rest.
I also notice you dont have any logic that references t[3] right now.
That all said you really should use a pattern to parse something like this.
local function splitIfStatement(str)
t = {str:match("if%s*%((%w+)%s*[=<>]+%s*(%d+)%)%s*{(.+)}")}
return t
end
this pattern is very narrow and expects a specific type of if statement, you can learn more about lua patterns here: Understanding Lua Patterns
If the input is of the form
if (AAA == BBB){ CCC("Hello") }
with possible whitespace around the fields in question, then this code works:
S=[[if (x == 2){ output("Hello") } ]]
a,b,c = S:match('%(%s*(.-)%s.-%s+(.-)%)%s*{%s*(.-)%(')
print(a,b,c)

How to implement the exercise 15.5 in pil4?

I am working on this exercise in pil4.
Exercise 15.5:
The approach of avoiding constructors when saving tables with cycles is too radical. It is
possible to save the table in a more pleasant format using constructors for the simple case, and to use
assignments later only to fix sharing and loops. Reimplement the function save (Figure 15.3, “Saving
tables with cycles”) using this approach. Add to it all the goodies that you have implemented in the previous
exercises (indentation, record syntax, and list syntax).
I have tried this with the code below, but it seems not to work on the nested table with a string key.
local function basicSerialize(o)
-- number or string
return string.format("%q",o)
end
local function save(name,value,saved,indentation,isArray)
indentation = indentation or 0
saved = saved or {}
local t = type(value)
local space = string.rep(" ",indentation + 2)
local space2 = string.rep(" ",indentation + 4)
if not isArray then io.write(name," = ") end
if t == "number" or t == "string" or t == "boolean" or t == "nil" then
io.write(basicSerialize(value),"\n")
elseif t == "table" then
if saved[value] then
io.write(saved[value],"\n")
else
if #value > 0 then
if indentation > 0 then io.write(space) end
io.write("{\n")
end
local indexes = {}
for i = 1,#value do
if type(value[i]) ~= "table" then
io.write(space2)
io.write(basicSerialize(value[i]))
else
local fname = string.format("%s[%s]",name,i)
save(fname,value[i],saved,indentation + 2,true)
end
io.write(",\n")
indexes[i] = true
end
if #value > 0 then
if indentation > 0 then io.write(space) end
io.write("}\n")
else
io.write("{}\n")
end
saved[value] = name
for k,v in pairs(value) do
if not indexes[k] then
k = basicSerialize(k)
local fname = string.format("%s[%s]",name,k)
save(fname,v,saved,indentation + 2)
io.write("\n")
end
end
end
else
error("cannot save a " .. t)
end
end
local a = { 1,2,3, {"one","Two"} ,5, {4,b = 4,5,6} ,a = "ddd"}
local b = { k = a[4]}
local t = {}
save("a",a,t)
save("b",b,t)
print()
And I got the wrong ouput.
a = {
1,
2,
3,
{
"one",
"Two",
}
,
5,
{
4,
5,
6,
}
a[6]["b"] = 4
,
}
a["a"] = "ddd"
b = {}
b["k"] = a[4]
How could I make the text ' a[6]["b"] = 4 ' jump out of the table constructor?

Converting base-10 to base2 in Ruby using recursion (Binary converter)

I would like to convert a base10 number to base2 in Ruby without using the built in to_s(2) method, using recursion.
I wrote this:
def to_binary(d)
if d<1
return ""
else
return to_binary(d/2).to_s + (d%2).to_s
end
end
This would return all correct results EXCEPT 0. Is there any way to return 0 for 0 without having leading zeroes for numbers greater than 0?
You can modify your checks a bit:
def to_binary(d)
return d.to_s if [0,1].include?(d) # same as "if d == 0 || d == 1"
to_binary(d/2) + (d%2).to_s
end
to_binary(10) == "1010"
#=> true
to_binary(0) == "0"
#=> true
You could also write above method as:
def to_binary(d)
return d.to_s if [0,1].include?(d)
div,mod = d.divmod(2)
to_binary(div) + mod.to_s
end

Parsing complex operands in boolean expressions in Python 2.7

I am trying to modify the example code in pyparsing to handle operands that are key value pairs, like:
(Region:US and Region:EU) or (Region:Asia)
This is a boolean expression with three operands - Region:US, Region:EU and Region:Asia. If they were simple operands like x, y and z, I'd be good to go. I don't need to do any special processing on them to break up the key-value pairs. I need to treat the operand in its entirety as though it might have just been x, and need to assign truth values to it and evaluate the full expression.
How might I modify the following code to handle this:
#
# simpleBool.py
#
# Example of defining a boolean logic parser using
# the operatorGrammar helper method in pyparsing.
#
# In this example, parse actions associated with each
# operator expression will "compile" the expression
# into BoolXXX class instances, which can then
# later be evaluated for their boolean value.
#
# Copyright 2006, by Paul McGuire
# Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility
#
from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas
# define classes to be built at parse time, as each matching
# expression type is parsed
class BoolOperand(object):
def __init__(self,t):
self.label = t[0]
self.value = eval(t[0])
def __bool__(self):
return self.value
def __str__(self):
return self.label
__repr__ = __str__
__nonzero__ = __bool__
class BoolBinOp(object):
def __init__(self,t):
self.args = t[0][0::2]
def __str__(self):
sep = " %s " % self.reprsymbol
return "(" + sep.join(map(str,self.args)) + ")"
def __bool__(self):
return self.evalop(bool(a) for a in self.args)
__nonzero__ = __bool__
__repr__ = __str__
class BoolAnd(BoolBinOp):
reprsymbol = '&'
evalop = all
class BoolOr(BoolBinOp):
reprsymbol = '|'
evalop = any
class BoolNot(object):
def __init__(self,t):
self.arg = t[0][1]
def __bool__(self):
v = bool(self.arg)
return not v
def __str__(self):
return "~" + str(self.arg)
__repr__ = __str__
__nonzero__ = __bool__
TRUE = Keyword("True")
FALSE = Keyword("False")
boolOperand = TRUE | FALSE | Word(alphas,max=1)
boolOperand.setParseAction(BoolOperand)
# define expression, based on expression operand and
# list of operations in precedence order
boolExpr = infixNotation( boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
if __name__ == "__main__":
p = True
q = False
r = True
tests = [("p", True),
("q", False),
("p and q", False),
("p and not q", True),
("not not p", True),
("not(p and q)", True),
("q or not p and r", False),
("q or not p or not r", False),
("q or not (p and r)", False),
("p or q or r", True),
("p or q or r and False", True),
("(p or q or r) and False", False),
]
print("p =", p)
print("q =", q)
print("r =", r)
print()
for t,expected in tests:
res = boolExpr.parseString(t)[0]
success = "PASS" if bool(res) == expected else "FAIL"
print (t,'\n', res, '=', bool(res),'\n', success, '\n')
Instead of p, q, r, I'd like to use "Region:US", "Region:EU" and "Region:Asia." Any ideas?
EDIT: Using Paul McGuire's suggestion, I tried writing the following code which breaks on parsing:
#
# simpleBool.py
#
# Example of defining a boolean logic parser using
# the operatorGrammar helper method in pyparsing.
#
# In this example, parse actions associated with each
# operator expression will "compile" the expression
# into BoolXXX class instances, which can then
# later be evaluated for their boolean value.
#
# Copyright 2006, by Paul McGuire
# Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility
#
from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas
# define classes to be built at parse time, as each matching
# expression type is parsed
class BoolOperand(object):
def __init__(self,t):
self.label = t[0]
self.value = validValues[t[0]]
def __bool__(self):
return self.value
def __str__(self):
return self.label
__repr__ = __str__
__nonzero__ = __bool__
class BoolBinOp(object):
def __init__(self,t):
self.args = t[0][0::2]
def __str__(self):
sep = " %s " % self.reprsymbol
return "(" + sep.join(map(str,self.args)) + ")"
def __bool__(self):
return self.evalop(bool(a) for a in self.args)
__nonzero__ = __bool__
__repr__ = __str__
class BoolAnd(BoolBinOp):
reprsymbol = '&'
evalop = all
class BoolOr(BoolBinOp):
reprsymbol = '|'
evalop = any
class BoolNot(object):
def __init__(self,t):
self.arg = t[0][1]
def __bool__(self):
v = bool(self.arg)
return not v
def __str__(self):
return "~" + str(self.arg)
__repr__ = __str__
__nonzero__ = __bool__
TRUE = Keyword("True")
FALSE = Keyword("False")
boolOperand = TRUE | FALSE | Word(alphas+":",max=1)
boolOperand.setParseAction(BoolOperand)
# define expression, based on expression operand and
# list of operations in precedence order
boolExpr = infixNotation( boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
if __name__ == "__main__":
validValues = {
"Region:US": False,
"Region:EU": True,
"Type:Global Assets>24": True
}
tests = [("Region:US", True),
("Region:EU", False),
("Region:US and Region:EU", False),
("Region:US and not Region:EU", True),
("not not Region:US", True),
("not(Region:US and Region:EU)", True),
("Region:EU or not Region:US and Type:Global Assets>24", False),
("Region:EU or not Region:US or not Type:Global Assets>24", False),
("Region:EU or not (Region:US and Type:Global Assets>24)", False),
("Region:US or Region:EU or Type:Global Assets>24", True),
("Region:US or Region:EU or Type:Global Assets>24 and False", True),
("(Region:US or Region:EU or Type:Global Assets>24) and False", False),
]
print("Region:US =", validValues["Region:US"])
print("Region:EU =", validValues["Region:EU"])
print("Type:Global Assets>24 =", validValues["Type:Global Assets>24"])
print()
for t,expected in tests:
res = boolExpr.parseString(t)[0]
success = "PASS" if bool(res) == expected else "FAIL"
print (t,'\n', res, '=', bool(res),'\n', success, '\n')
Thanks to Paul McGuire's help, here is the solution:
boolOperand = TRUE | FALSE | Combine(Word(alphas)+":"+quotedString) | Word(alphas+":<>")
This does the parsing as I wanted it.
There are two parts to making this change: changing the parser, and then changing the post-parsing behavior to accommodate these new values.
To parse operands that are not just simple 1-character names, change this line in the parser:
boolOperand = TRUE | FALSE | Word(alphas,max=1)
The simplest (but not strictest would be to just change it to:
boolOperand = TRUE | FALSE | Word(alphas+":")
But this would accept, in addition to your valid values of "Region:US" or "TimeZone:UTC", presumably invalid values like "XouEWRL:sdlkfj", ":sldjf:ljsdf:sdljf", and even ":::::::". If you want to tighten up the parser, you could enforce the key entry to:
valid_key = oneOf("Region Country City State ZIP")
valid_value = Word(alphas+"_")
valid_kv = Combine(valid_key + ":" + valid_value)
boolOperand = TRUE | FALSE | valid_kv
That should take care of the parser.
Second, you will need to change how this entry is evaluated after the parsing is done. In my example, I was emphasizing the parsing part, not the evaluating part, so I left this to simply call the eval() builtin. In your case, you will probably need to initialize a dict of valid values for each acceptable key-value pair, and then change the code in BoolOperand to do a dict lookup instead of calling eval. (This has the added benefit of not calling eval() with user-entered data, which has all kinds of potential for security problems.)

lua - calling a function from a string

From what I've read on this site the below should work.
Can some kindly soul please point out where I'm going wrong?
I've embedded more description and print returns in the code hopefully to make easier reading
local m = {
{opt = "Solar Panels", cmd = "solarPanel"}
-- There are many more options here.
}
function doTheMenu()
print("Welcome to Spyder's Factory")
print("")
print("What would you like to make?")
local n = 1
local l = #m - 1
while true do --This while loop may or may not be relevant to the question, it's the menu
term.clear() --this is ComputerCraft lua, the term function is defined
term.setCursorPos(1,2) --elsewhere in an API
for i, j in pairs(m) do
if i == n then
if i < 10 then print(i, " ["..j.opt.."]") else print(i, " ["..j.opt.."]") end
fsel = j.cmd --set fsel to the function name I require in case of a break
tsel = j.opt --Ditto, tsel, human-friendly name
else
if i < 10 then print(i, " "..j.opt) else print(i, " "..j.opt) end
end
end
local a, b = os.pullEvent("key")
if b == 200 and n > 1 then n = n - 1 end
if b == 208 and n <= l then n = n + 1 end
if b == 28 then break end
end
write("\nSure, how many "..tsel.."? ")
qty = tonumber(read())
req[fsel] = req[fsel] + qty
str = fsel.."("..qty..")"
print("Loading function '"..fsel.."("..qty..")'") --Returns "Loading function 'solarPanel(1)'"
func = loadstring(str)
print(func) --Returns "function: 2cdfc5a7"
print("Loading function")
func() --The error line, Returns "string:1: attempt to call nil"
--tellUserWhatNeed()
--makeItHappen()
end
doTheMenu()
The issue is the code fails to run with the error:
string:1 attempt to call nil
Also what is term variable, if that's all your code, term is not defined and is null)
That said: either _G[fsel] is nil or fsel is nil ?
Are you sure you have function declared in _G with the name stored in fsel?
e.i. call before the problem line print (_G[fsel]) to see what it gives you.
This was the solution that ended up working:
local f = loadstring(str)
if f then
setfenv(f, getfenv())
f()
end
This replaces the lines above:
print("Loading function '"..fsel.."("..qty..")'")
func = loadstring(str)
print(func)
print("Loading function")
func()
As well as adding basic error handling for loading the function

Resources