I'm writing a syntax controller for empirical formulas. It seems to be working fairly well, but there is one error that I can not seem to fix.
Here is the code:
import string
from linkedQFile import LinkedQ
ATOMER = ["H","He","Li","Be","B","C","N","O","F","Ne","Na","Mg","Al","Si","P","S","Cl","Ar"]
class Formelfel(Exception):
pass
def readFormel():
if q.peek() == None:
print("Formel saknas. ")
readMol()
print("Formeln är syntaktiskt korrekt")
#newline check?
def readMol():
if q.peek() == None:
return
readGroup()
readMol()
return
def readGroup():
if q.peek() == "(":
print(q.get(), end="")
if q.peek() in string.ascii_lowercase or q.peek() in string.ascii_uppercase:
readMol()
else:
raise Formelfel
if q.peek() == ")":
print(q.get(), end="")
readNum()
return
readAtom()
try:
readNum()
except Formelfel:
pass
return
def readAtom():
X = readLetter()
try:
x = readletter()
except Formelfel:
x = ""
atom = X+x
if atom in ATOMER:
return
rest=""
while not q.isEmpty():
rest += print(q.get(), end="")
raise Formelfel("Okänd atom vid radslutet "+rest)
def readNum():
try:
if q.peek() != None:
print(q.peek())
while not q.peek() in string.ascii_uppercase and not q.peek() in string.ascii_lowercase and not q.peek() == "(" and not q.peek()==")": # If q.peek() is a number
if q.peek() == None:
return
int(q.get())
return
except:
raise Formelfel
def readLetter():
if q.peek() in string.ascii_uppercase:
x =q.get()
print(x,end="")
return x
raise Formelfel
def readletter():
if q.peek() == None:
raise Formelfel
if q.peek() in string.ascii_lowercase:
x =q.get()
print(x,end= "")
return x
raise Formelfel
formel= "Si(C3(COOH)2)4(H2O)7"
q = LinkedQ()
for symbol in formel:
q.put(symbol)
readFormel()
I get the following output and error:
Si(
(C3
(CO
OO
OH
H)
)2
)4
(H2
O)
)7
Traceback (most recent call last):
File "formelkoll.py", line 59, in readNum
while not q.peek() in string.ascii_uppercase and not q.peek() in string.ascii_lowercase and not q.peek() == "(" and not q.peek()==")": # If q.peek() is a number
TypeError: 'in <string>' requires string as left operand, not NoneType
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "formelkoll.py", line 88, in <module>
readFormel()
File "formelkoll.py", line 12, in readFormel
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 19, in readMol
readGroup()
File "formelkoll.py", line 27, in readGroup
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 19, in readMol
readGroup()
File "formelkoll.py", line 27, in readGroup
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 19, in readMol
readGroup()
File "formelkoll.py", line 27, in readGroup
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 20, in readMol
readMol()
File "formelkoll.py", line 19, in readMol
readGroup()
File "formelkoll.py", line 32, in readGroup
readNum()
File "formelkoll.py", line 65, in readNum
raise Formelfel
__main__.Formelfel
I don't understand why this error occurs, as I have an if statement:
if q.peek() != None:
before the row where the error occurs. In other words, why is None allowed to slip through this if statement?