Given an input of something like Na(Cl2)3Al(AlCl2)4 I am trying to make a program without any libraries to do this and the code that I made is not working and I cant figure out why.
can someone show me exactly where i am going wrong (or fix it for me)? the output for the example input should look like NaCl6AlAl4Cl8 where brackets are removed also. thanks in advance for any help.
def format(equation):
equation_list = list(equation)
formated = ''
for i in range(len(equation_list)):
if equation_list[i] == '(':
opening = i
if equation_list[i] == ')':
closing = i
for i in range(opening+1,closing):
if equation_list[i].isdigit():
equation_list[i] = str(int(equation_list[i])*mult)
if equation_list[i].upper():
if equation_list[i+1].isupper():
equation_list[i+1] = str(mult)
elif equation_list[i+1].isdigit():
equation_list[i+1] = str(int(equation_list[i+1])*mult)
else:
if equation_list[i+2].isupper():
equation_list[i+2] = str(mult)
elif equation_list[i+2].isdigit():
equation_list[i+2] = str(int(equation_list[i+2])*mult)
else:
if equation[i+3].isdigit():
equation_list[i+3] = str(int(equation_list[i+3])*mult)
else:
equation[i+3] = str(mult)
for i in equation_list:
formated+=i
return formated
print(format('Na(Cl2)3Al(AlCl2)4'))
As the pointed duplicate has no voted-up answered, I'd like to propose one, based on regexes. I'm pretty sure it doesn't match all cases, but yours at least
import re
EQ_PATTERN = re.compile(r"([A-Z][a-z]+\d*|\((?:[A-Z][a-z]+\d*)+\)\d*)")
BLOCK_PATTERN = re.compile(r"\(((?:[A-Z][a-z]+\d*)+)\)(\d*)")
ELEMENT_PATTERN = re.compile(r"([A-Z][a-z]+)(\d*)")
def format_element(element: str, amount: str, factor: int):
return f"{element}{int(amount or '1') * factor}"
def format_block(block: str):
if '(' not in block:
return block
inside, factor = BLOCK_PATTERN.findall(block)[0]
return "".join(format_element(element, amount, int(factor))
for element, amount in ELEMENT_PATTERN.findall(inside))
def format_equation(eq: str):
return "".join(map(format_block, EQ_PATTERN.findall(eq)))
With some tests
for eq in ('(Al3Cl2Ag6Au)4', 'Na(Cl2)3Al(AlCl2)4', 'Na2(Cl2)3Al(Al3Cl2)4'):
print(f"{eq:20s} ==> {format_equation(eq)}")
(Al3Cl2Ag6Au)4 ==> Al12Cl8Ag24Au4
Na(Cl2)3Al(AlCl2)4 ==> NaCl6AlAl4Cl8
Na2(Cl2)3Al(Al3Cl2)4 ==> Na2Cl6AlAl12Cl8
Related
I'm currently writing a test function for class to test provided cases on provided solution code. However I'm running into an issue where a print statement is executing when I don't want it to.
This is the provided solution that I'm testing:
def alphapinDecode(tone):
phone_num = ''
if checkTone(tone): #or checkTone2
while len(tone) > 0:
# retrieve the first tone
next_tone = tone[0:2]
tone = tone[2:]
# find its position
cons = next_tone[0]
vow = next_tone[1]
num1 = consonants.find(cons)
num2 = vowels.find(vow)
# reconstruct this part of the number -
# multiply (was divided) and add back
# the remainder from the encryption division.
phone = (num1 * 5) + num2
# recreate the number
# by treating it as a string
phone = str(phone)
# if single digit, not leading digit, add 0
if len(phone) == 1 and phone_num != '':
phone = '0' + phone
phone_num = phone_num + phone
# but return in original format
phone_num = int(phone_num)
else:
print('Tone is not in correct format.')
phone_num = -1
return phone_num
Here's the (partially done) code for the test function I have written:
def test_decode(f):
testCases = (
('lo', 43),
('hi', 27),
('bomelela', 3464140),
('bomeluco', 3464408),
('', -1),
('abcd', -1),
('diju', 1234),
)
for i in range(len(testCases)):
if f(testCases[i][0]) == testCases[i][1] and testCases[i][1] == -1:
print('Checking '+ f.__name__ + '(' + testCases[i][0] + ')...Tone is not in correct format.')
print('Its value -1 is correct!')
return None
When executing test_decode(alphapinDecode), I get this:
Tone is not in correct format.
Checking alphapinDecode()...Tone is not in correct format.
Its value -1 is correct!
Tone is not in correct format.
Checking alphapinDecode(abcd)...Tone is not in correct format.
Its value -1 is correct!
As you can see, because of the print statement in alphapinDecode(I think), it is printing an extra "Tone is not in correct format." above the print statement I have written.
How would I prevent this print statement from executing, and why is it printing if the print statement I wrote in my test function doesn't ask for the result of alphapinDecode?
We are not allowed to alter the code of the given solution.
I'm fairly new to stackOverflow, so sorry for any formatting issues. Thank you!
Edit: Fixed the idents of the test_decode function
One easy solution would be to pass an extra parameter say, a boolean variable debug to the function. That would go something like this.
def func1(var1, debug):
if debug:
print("Printing from func1")
# Do additional stuff
Now when you call it. You now have the option of setting the debug variable.
func1("hello", debug=True) # will print the statement
func1("hello", debug=False) # will not print statement.
If you cannot modify the called function. Then you can follow this method. explained by #FakeRainBrigand here.
import sys, os
# Disable
def blockPrint():
sys.stdout = open(os.devnull, 'w')
# Restore
def enablePrint():
sys.stdout = sys.__stdout__
print 'This will print'
blockPrint()
print "This won't"
enablePrint()
print "This will too"
I am making a program which makes a mark list with a letter grade in python.
But the problem is the if-else statements to decide letter grade is only executing else statement when given inputs. But the if statement for 'A+' grade is working if maximum marks are given. I am a newbie and I can't understand where the bug is, please help. Below is my python code, here datails.html collects information from the user and mark list is displayed in the results.html page.
from flask import Flask, render_template, request
app=Flask(__name__)
#app.route("/")
def index():
return render_template('details.html')
#app.route("/send",methods=['POST','GET'])
def send():
if(request.method=='POST'):
getname=request.form['name']
getregno=request.form['regno']
getcollege=request.form['college']
getsem=request.form['sem']
getsub1=request.form['sub1']
getsub1m=request.form['sub1m']
getsub2=request.form['sub2']
getsub2m=request.form['sub2m']
getsub3=request.form['sub3']
getsub3m=request.form['sub3m']
getsub4=request.form['sub4']
getsub4m=request.form['sub4m']
malayalam_mark = int(getsub1)
malayalam_maxmark = int(getsub1m)
english_mark = int(getsub2)
english_maxmark = int(getsub2m)
maths_mark = int(getsub3)
maths_maxmark = int(getsub3m)
computer_mark = int(getsub4)
computer_maxmark = int(getsub4m)
percent_malayalam = malayalam_mark/malayalam_maxmark*100
percent_english = english_mark/english_maxmark*100
percent_maths = maths_mark/maths_maxmark*100
percent_computer = computer_mark/computer_maxmark*100
slist= [percent_malayalam,percent_english,percent_maths,percent_computer]
result_list=[]
for i in slist:
if i>=50 and i<58:
grade='D+'
result='pass'
elif i>=58 and i<65:
grade='C'
result='Pass'
elif i>=65 and i<72:
grade='C+'
result='Pass'
elif i>=72 and i<79:
grade='B'
result='Pass'
elif i>=79 and i<86:
grade='B+'
result='Pass'
elif i>=86 and i<93:
grade='A'
result='Pass'
elif i>=93 and i<=100:
grade='A+'
result='Pass'
else:
grade='D'
result='Fail'
result_list.append(grade)
result_list.append(result)
return render_template('/results.html',list=result_list,a=getname,b=getregno,c=getsem,d=getcollege,e=getsub1,e1=getsub1m,f=getsub2,f1=getsub2m,g=getsub3,g1=getsub3m,h=getsub4,h1=getsub4m)
if(__name__=='__main__'):
app.run(debug=True)
I am including a result page, here I included the final list in the bottom for reference, you can find that every input gives grade 'D' and result 'Fail' except maximum marks.
I guess this is being run in Python 2 which doesn't automatically promote integer division. If you rearrange your calculations like:
percent_malayalam = malayalam_mark * 100 / malayalam_maxmark
you might get the right answer… Previously all non-100% results were being (implicitly) rounded to 0%. 2 / 3 in Python 2 will be 0, not ~0.6. The defaults have been changed in Python 3 so it tends to do the right thing more often.
You could then read about integer division in Python 2 from various places, here's one at this site: What is the difference between '/' and '//' when used for division?
def specificChecker(someThing, checker):
if checker == None:
return someThing
elif checker == True:
return not someThing
else:
return None
def whatDoesTheCheckerSay(someThing):
if specificChecker(someThing) == someThing:
return 'The checker value was False on that one.'
elif specificChecker(someThing) == not someThing:
return 'The checker value was True on that one.'
elif specificChecker(someThing) == None:
return 'Something irregular happend. The checker value wasn\'t None or True.'
else:
return 'Something went really wrong. This doesn\'t even not work.'
reallySomeThing = input('Type in really some thing: ')
theChecker = input('Set the checker to something: ')
print(specificChecker(reallySomeThing, theChecker))
print(whatDoesTheCheckerSay(reallySomeThing)) # This can be made more efficient, right?
def one(someShit):
return someShit + ' AWWW YEAH!'
def two(someShit):
return one(someShit)
print(two(input('Type in some kind of stuff: ')))
I'm a self-taught beginner, so surely it's something awkwardly basic. I'm using the IDLE shell and have repeatedly gotten a syntax error at the second definition statement of my codes. Please help?
You cannot use the line:
elif specificChecker(someThing) == not someThing:
This must be written
elif specificChecker(someThing) != someThing:
to be valid Python.
This is also valid but is perhaps less readable:
elif (specificChecker(someThing)) == (not someThing):
After OP edit:
The new error is the mismatch in arguments (always 1) to a function that requires 2 arguments. You have to pass two arguments to specificChecker not one
Line 12: elif specificChecker(someThing) == not someThing:
If you want to check if some variable is not some variable, used is not for boolean or != for values and strings
I have a program that I'm working on that takes an input and checks it to see if it spelled correctly with a dictionary inside of a file. However, I want to return a suggestion or two as well of what the person means. Any suggestions of how to do this? I have found some modules that can do it, but not for a specific dictionary from a file. Any help is appreciated!!
Here is what I have now:
def getDictionary():
theDictionary = open("theDictionary.txt", "r")
dictionaryList = []
for eachLine in theDictionary:
splitLines = eachLine.split()
dictionaryList.append(splitLines[0])
theDictionary.close()
return dictionaryList
def spellChecker(theFile, theDictionary):
lowerItems = theFile.lower()
wordList = lowerItems.split()
wrongList = []
for item in wordList:
if item not in theDictionary:
result = False
wrongList.append(item)
else:
result = True
wrongItem = ""
return (result, wrongList)
def main():
theDictionary = getDictionary()
theText = getFile()
theInput = input("Input some words here:")
result, wrongList=spellChecker(theInput,theDictionary)
if result:
print("There are no spelling errors in the sentence! Hooray!")
else:
if len(wrongList) == 1:
print('There is a spelling error in the sentence! The word that is wrong is "' + str(wrongList) + '".')
elif len(wrongList) > 1:
print('There are some spelling errors in the sentence! The words that are wrong are"' + str(wrongList) + '".')
main()
You might want to have a look at the difflib module in the Standard Library. It allows you to do approximate string matching, which seems to be what you want.
It really does not matter if your dictionary is inside a file or not, since you are loading it into a list anyway. Maybe have a look at the get_close_matches() method in the said module.
I got an error. I did quick googling and it did not help me well.
I added the whole code, well kind of whole code. request from a user.
from derp_node import *
##############################################################################
# parse
##############################################################################
def parse(tokens, i = 0):
"""parse: tuple(String) * int -> (Node, int)
From an infix stream of tokens, and the current index into the
token stream, construct and return the tree, as a collection of Nodes,
that represent the expression.
NOTE: YOU ARE NOT ALLOWED TO MUTATE 'tokens' (e.g. pop())!!! YOU
MUST USE 'i' TO GET THE CURRENT TOKEN OUT OF 'tokens'
"""
if tokens == []:
raise TypeError("Error: Empty List.")
elif tokens[int(i)] == '*':
tokens.remove(int(i))
return mkMultiplyNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '//':
tokens.remove(int(i))
return mkDivideNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '+':
tokens.remove(int(i))
return mkAddNode(parse(tokens), parse(tokens))
elif tokens[int(i)] == '-':
tokens.remove(int(i))
return mkSubtractNode(parse(tokens), parse(tokens))
elif tokens[int(i)].isdigit():
return mkLiteralNode(tokens.remove(int(i)))
elif not tokens[int(i)].isdigit():
return mkVariableNode(tokens.remove(int(i)))
else:
raise TypeError("Error: Invalid Input")
##############################################################################
# main
##############################################################################
def main():
"""main: None -> None
The main program prompts for the symbol table file, and a prefix
expression. It produces the infix expression, and the integer result of
evaluating the expression"""
print("Hello Herp, welcome to Derp v1.0 :)")
inFile = input("Herp, enter symbol table file: ")
symTbl = {}
for line in open(inFile):
i = line.split()
symTbl[i[0]] = int(i[1])
print("Derping the symbol table (variable name => integer value)...")
for variable in sorted(symTbl):
print(variable + " => " + str(symTbl[variable]))
# STUDENT: CONSTRUCT AND DISPLAY THE SYMBOL TABLE HERE
print("Herp, enter prefix expressions, e.g.: + 10 20 (RETURN to quit)...")
# input loop prompts for prefix expressions and produces infix version
# along with its evaluation
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
# STUDENT: GENERATE A LIST OF TOKENS FROM THE PREFIX EXPRESSION
prefixLst = prefixExp.split()
# STUDENT: CALL parse WITH THE LIST OF TOKENS AND SAVE THE ROOT OF
# THE PARSE TREE.
tokens = []
parseLst = parse(prefixLst, tokens)
# STUDENT: GENERATE THE INFIX EXPRESSION BY CALLING infix AND SAVING
# THE STRING
infixLst = infix(parseLst)
print("Derping the infix expression:")
# STUDENT: EVALUTE THE PARSE TREE BY CALLING evaluate AND SAVING THE
# INTEGER RESULT
print("Derping the evaluation:")
print("Goodbye Herp :(")
if __name__ == "__main__":
main()
The error I received is:
File "derpNew.py", line 31, in parse
if tokens[int(i)] == '*':
TypeError: int() argument must be a string or a number, not 'list'
If I remove the int() from the variable i, then I would get this error: TypeError: list indices must be integers, not list
Am I suppose to convert the list to tuple? Any help would be great. Thank you.
If you guys are curious how I am calling the parse. I put this under main function.
tokens = []
parseLst = parse(tokens, i)
EDIT:
The loop:
while True:
prefixExp = input("derp> ")
if prefixExp == "":
break
prefixLst = prefixExp.split()
tokens = []
parseLst = parse(tokens, i)
parseLst = parse(tokens, i) - this line doesn't make sense unless you define i. If you want to pass default i=0, then just leave it out: parseLst = parse(tokens).
EDIT: After the whole code has been pasted, there is some (apparently irrelevant) i defined before, which is why there was no NameError.
The passed variable i is a list, that's why the errors! Would need more info on the arguments being passed to help you more!
List indices work like this
>>> my_list = [1, 2, 3, 4, 5]
>>> for index in range(5):
... print my_list[i]
1
2
3
4
5
>>> my_list[3]
4
What are you passing to the method parse(...) as second parameter? If it's a list, it shouldn't. You may want to change the value you are passing to parse.
You may also want to check if tokens is an empty list, before the other ifs, or it will cause another error.
if tokens == []:
raise TypeError("Error: Empty List.")
elif tokens[int(i)] == '*':
tokens.remove(int(i))
return mkMultiplyNode(parse(tokens), parse(tokens))
return mkSubtractNode(parse(tokens), parse(tokens))
elif tokens[int(i)].isdigit():
return mkLiteralNode(tokens.remove(int(i)))
elif not tokens[int(i)].isdigit():
return mkVariableNode(tokens.remove(int(i)))
else:
raise TypeError("Error: Invalid Input")