A little bit of context for this: I am going to be a junior in high school next year and I thought it would be cool to code some equations for things I would be doing in school. I have done equations for algebra (solving for x in the quadratic equation and such), and I thought it would be cool to create some code for chemistry. I'm trying to figure out how to balance equations, and I was thinking I could enter in all of the amounts and using a certain key (let's say space) it would continue to the next part of the chemical equation. Here is basically what I was thinking.
reac1_chem1 = input("Enter the first chemical: ")
reac1_amount1 = input("Enter the amount of " + reac1_chem1 + " atoms: )
reac1_chem2 = input("Enter the second chemical: ")
reac1_amount2 = input("Enter the amount of " + reac1_chem2 + " atoms: )
I want to continue this process until space is entered in as a chemical. How would I make this process infinite? Is creating variables the way to go or should I make a list? Any suggestions would be appreciated! Let me know if this was in any way confusing and I can try to clear it up for you. Thanks!
A dictionary would be great:
chemicals = dict()
index = 1
while True:
chemical = input(f"Enter chemical {index}: ")
if chemical == " ":
break
else:
chemicals[chemical] = input("Enter the amount: ")
index += 1
print(chemicals)
You could try to store the information in a dictionary of dictionaries, example as follows:
dct = {"ReactionNameOrID": {"ChemicalName1":"ATOMS", "ChemicalName":"ATOMS2"}}
You can then access the information like this:
dct.get("ReactionNameOrID").get("ChemicalName1")
#which will return: "ATOMS"
You could then use a class to store everything inside including the functions.
class Reactions():
#initialize the dictionary
def __init__(self):
self.dict_reactions = {}
#add a function to the class to add more reactions
def add_chemical(self):
reaction_name = input("Enter the reaction name/id: ")
dict_chemicals = input("Enter the chemicals + atoms as dictionary: ")
self.dict_reactions[reaction_name] = dict_chemicals
MyReactions = Reactions()
# Enter the reaction name/id: FirstReaction
# Enter the reaction name/id: {"H":100, "O":500}
MyReactions.add_chemical()
print(MyReactions.dict_reactions)
#{'FirstReaction': '{"H":100, "O":500}'}
Related
I am a newbie to Python, and trying to create an input form using a nested dictionary with the following flow, but really struggling to cope with how to code having multiple values (as a list) that can be associated per topic within the dictionary:
Steps
Ask the user to input a topic / issue which is stored in an empty dictionary
Immediately after entering a topic / problem, prompt user to enter an action to resolve the problem, associate it with a due date entered by the user to complete by, and then linked to the topic / issue (key) created in step 1 as value to that key
Prompt user to add another action to the same topic if required with y/n or move to add another topic
add another topic / issue if required
print the dictionary with the topic / issues (keys) and associated values or multiple values with due dates.
Note I have not added due dates, and code to loop through the completed dictionary to list problems / actions with the due dates to amend, delete or change.
Any help really appreciated!! :)
here is a sample of my incomplete code:
problems = {}
problems_open = True
actions_open = True
while problems_open:
issue = input("\nPlease enter a topic / problem? ")
while actions_open:
action = input("What action are you going to take for this topic? ")
problems[issue] = action
repeat = input("Would you like to add another action y/n?")
if repeat == 'n':
actions_open = False
""" This is not appending multiple actions to the dictionary problems, just the
last entry """
""" Not sure how to add a due date to each action """
repeat = input("Would you like to add another topic / problem? ")
if repeat == "n":
problems_open = False
print("\n--- List of problems and actions with dates ---")
for issue, action in problems.items():
print("The problem: " + issue + " has " + "the following actions: " + action)
The problem in your code were the nested lists. The problem with nested lists is, that you can't iterate through them with numbers. That means to identify the specific value in the list would be very difficult.
The solution is to use lists (the ones with the square brackets).
I made a working code for your problem:
problems = []
actions = []
problems_open = True
actions_open = True
offset = -1
while problems_open:
issue = input("\nPlease enter a topic / problem? ")
problems.append(issue)
while actions_open == True:
action = input("What action are you going to take for this topic? ")
actions.append(action)
actions_open = False
repeat = input("Would you like to add another topic / problem? y/n ")
if repeat == "n":
problems_open = False
elif repeat == "y":
problems_open = True
actions_open = True
print("\n--- List of problems and actions with dates ---")
for problems, actions in zip(problems, actions):
print("The problem: " + problems + " has " + "the following actions: " + actions)
The only difference in this code is that you are not asked multiple times for taking another action on one problem again. I just made a working list for you. I hope it helped.
I am trying to create an attendance logger where I create a dictionary which I fill with student names. The names will be lists where I append their class attendance data (whether they attended class or not). The code I have so far is displayed below`
#! /bin/python3
#add student to dict
def add_student(_dict):
student=input('Add student :')
_dict[student]=[]
return _dict
#collect outcomes
def collector(student,_dict, outcome):
_dict[student].append(outcome)
return _dict
#counts target
def count(_dict,target):
for i in _dict:
# records total attendance names
attendance_stat = len(_dict[i])
# records total instances absent
freq_of_absence=_dict[i].count(target)
# records percentage of absence
perc_absence = float((freq_of_absence/attendance_stat)*100)
print(i,'DAYS ABSENT =',freq_of_absence)
print('TOTAL DAYS: ', i, attendance_stat)
print('PERCENTAGE OF ABSENCE:', i, str(round(perc_absence, 2))+'%')
#main function
def main():
#date=input('DATE: ')
outcomes=['Y','N']
student_names = {}
try:
totalstudents = int(input('NO. OF STUDENTS: '))
except ValueError:
print('input an integer')
totalstudents = int(input('NO. OF STUDENTS: '))
while len(student_names) < totalstudents:
add_student(student_names)
print(student_names)
i = 0
while i < totalstudents:
i = i + 1
target='Y'
student=str(input('student :'))
outcome=str(input('outcome :'))
collector(student,student_names,outcome)
count(student_names,target)
if __name__=='__main__':
main()
`
The code works well so far but the problem is when the number of students is too large, time taken to input is extensive cutting in on class time. Since the number of absentees is usually less than those present, is it possible to select from the dictionary students absent which will append the value Y for each selected absent, while appending N to the remaining lists in dictionary.
This isn't exactly what you're asking for, but I think it will help. Instead of asking the user to input a name each time for the second part, why not just print the name yourself, and only ask for the outcome? Your last while loop would then become a for loop instead, like this:
for student_name in student_names:
outcome = input("Outcome for {}: ".format(sudent_name))
collector(student_name, student_names, outcome)
You could also add some logic to check if outcome is an empty string, and if so, set it to 'N'. This would just allow you to hit enter for most of the names, and only have to type in 'Y' for the certain ones that are absent. That would look like this:
for student_name in student_names:
outcome = input("Outcome for {}: ".format(sudent_name))
if outcome = "":
outcome = "N"
collector(student_name, student_names, outcome)
So I was given a problem by my Computer Science teacher, but I have been sat here for ages and cannot for the life of me figure it out. There are plenty of tasks within the problem, but there is only one I'm having trouble with.
So, I am coding a program for a carpet shop, and the part that I am stuck on is this.
2: For each floor you need to carpet, ask the user for the name of the room that the floor is located in.
Basically X number of rooms; need to loop a sentence asking for the name of the room multiplied by X. So if the user has 3 rooms they need carpeted, I would end up with the name of 3 rooms (Lounge, Bedroom etc.), and be able to display these results back to the user later. Here is what I have so far...
#Generating An Estimate.
#Welcome message + setting base price to 0 + defining "getting_estimate" variable.
def getting_estimate ():
overallPrice = 0
print("Welcome!")
#Getting the information about the customer.
custID = input ("\n1. Please enter the customer's ID: ")
estimateDate = input ("\n2. Please enter the date: ")
numberOfRooms = input (int("\n3. Please enter the number of rooms that need to be carpeted: "))
#Add input allowing user to enter the
#name of the room, looped by the integer entered
#in the Variable "numberOfRooms", and possibly
#adding 1st room, 2nd room etc??
If someone can work this out they are helping me loads. Thanks :)
Perhaps using a for loop perhaps?
for i in range(numberOfrooms):
roomName = input("Blah blah")
Full code:
def getting_estimate ():
overallPrice = 0
print("Welcome!")
custID = input ("\n1. Please enter the customer's ID: ")
estimateDate = input ("\n2. Please enter the date: ")
numberOfRooms = int (input("\n3. Please enter the number of rooms that need to be carpeted: "))
cust_roster = {custID:[]}
for i in range(numberOfRooms):
roomName = input("Enter the name of room number "+str(i+1))
cust_roster[custID].append(roomName)
print("{} has {} rooms called: {}".format(custID,
len(cust_roster[custID]),
cust_roster[custID]))
Btw I'm doing a similar task for my OCR computing coursework ;) so good luck!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
This is my first post here and I am quite unsure on how to implement a vital piece of code in my coursework. I have created a very crude and basic recipe program on Python 3.4. Below is the piece I am missing.
• The program should ask the user to input the number of people.
• The program should output:
• the recipe name
• the new number of people
• the revised quantities with units for this number of people.
I am a complete beginner to programming and our teacher hasn't been very helpful and only explained the basics of file handling which I have attempted to implement into this program.
I will attach the code I have so far, but I would really appreciate some tips or an explanation on how I could implement this into my code and finally finish this task off as it is becoming very irksome.
Thank you!
Code:
I apologise if the code is cluttered or doesn't make sense. I am a complete novice.
#!/usr/bin/env python
import time
def start():
while True:
User_input = input("\nWhat would you like to do? " "\n 1) - Enter N to enter a new recipe. \n 2 - Enter V to view an exisiting recipe, \n 3 - Enter E - to edit a recipe to your liking. \n 4 - Or enter quit to halt the program " "\n ")
if User_input == "N":
print("\nOkay, it looks like you want to create a new recipe. Give me a moment..." "\n")
time.sleep(1.5)
new_recipe()
elif User_input == "V":
print("\nOkay, Let's proceed to let you view an existing recipe stored on the computer")
time.sleep(1.5)
exist_recipe()
elif User_input == "E":
print("\nOkay, it looks like you want to edit a recipe's servings. Let's proceed ")
time.sleep(1.5)
modify_recipe()
elif User_input == "quit":
return
else:
print("\nThat is not a valid command, please try again with the commands allowed ")
def new_recipe():
New_Recipe = input("Please enter the name of the new recipe you wish to add! ")
Recipe_data = open(New_Recipe, 'w')
Ingredients = input("Enter the number of ingredients ")
Servings = input("Enter the servings required for this recipe ")
for n in range (1,int(Ingredients)+1):
Ingredient = input("Enter the name of the ingredient ")
Recipe_data.write("\nIngrendient # " +str(n)+": \n")
print("\n")
Recipe_data.write(Ingredient)
Recipe_data.write("\n")
Quantities = input("Enter the quantity needed for this ingredient ")
print("\n")
Recipe_data.write(Quantities)
Recipe_data.write("\n")
for n in range (1,int(Ingredients)+1):
Steps = input("\nEnter step " + str(n)+ ": ")
print("\n")
Recipe_data.write("\nStep " +str(n) + " is to: \n")
Recipe_data.write("\n")
Recipe_data.write(Steps)
Recipe_data.close()
def exist_recipe():
Choice_Exist= input("\nOkay, it looks like you want to view an existing recipe. Please enter the name of the recipe required. ")
Exist_Recipe = open(Choice_Exist, "r+")
print("\nThis recipe makes " + Choice_Exist)
print(Exist_Recipe.read())
time.sleep(1)
def modify_recipe():
Choice_Exist = input("\nOkaym it looks like you want to modify a recipe. Please enter the name of this recipe ")
Exist_Recipe = open(Choice_Exist, "r+")
time.sleep(2)
ServRequire = int(input("Please enter how many servings you would like "))
start()
EDIT: This is the new code, however I can still not figure out how to allow a user to multiply the original servings by entering how many servings are required, as the default servings are in a text file. Does anyone know how this can be done? I am new to file-handling and have been researching constantly but to no avail.
For the number of people, you can get that from user input similar to how you got any other input in your code, with num_people = input("How many people?").
Something a little more concerning you should look at. Your start() function calls its self. Unless you are using recursion, functions should not call themselves, it will build up on the stack. Use a while loop with something like
while ( 1 ):
userinput = input("what would you like to do?")
if( userinput == "n"):
#new recipe
....
if (user input == "quit"):
sys.exit(1) #this will halt the program
else:
print "not valid input"
You stored the whole data in a text file. This makes storage and retrieval easy, but makes changing values real hard. In these cases, you usually use ... well nevermind: you asked the same question again and got a useful answer.
grade=[]
names=[]
highest=0
cases=int(input('Enter number of cases: '))
for case in range(1,cases+1):
print('case',case)
number=int(input('Enter number of students: '))
for numbers in range (1,number+1):
name=str(input('Enter name of student: '))
names.append(name)
mark=float(input('Enter mark of student:'))
grade.append(mark)
print('Case',case,'result')
print('name',list[list.index(max(grade))])
average=(sum(grade)/number)
print('average',average)
print('highest',max(grade))
print('name',names[grade.index(max(grade))])
I want to print name of the student with the highest mark. I have not learned anything other than list, while and for. NO dictionary ..nothing. I was wondering how can i do this?
ALSO i am getting this error!!! builtins.AttributeError: 'str' object has no attribute 'append'. HELP. thank you! :D
for number in range (1,number+1):
Don't reuse variable names for different things, call one of them numbers and the other number:
numbers=int(input('Enter number of students: '))
for number in range (1,numbers+1):
You made name a list in the beginning:
name=[]
but here you assign a single input to it:
name=str(input('Enter name of student: '))
The you append the new name to itself:
name.append(name)
which is not possible, because name is after the input no longer a list but a string. Again using different variable names for different things would help. Call the array names and the single input name:
names = []
#...
name=str(input('Enter name of student: '))
names.append(name)
And here:
print('name',list[list.index(max(grade))])
list is a build-in type, not one of your variables, so what you are trying to do is index a type, not a specific list. If you want to call index on a specific list you do so by using the variable name of that list. grade.index(...) will find the specific position matching the passed grade in grade and then you can use this position to get the corresponding name, because you know, that the name is at the same position in names:
print('name',names[grade.index(max(grade))])
Here is a somewhat more elaborated version; working through it should give you a better feel for the language.
from collections import namedtuple
import sys
# Python 2/3 compatibility shim
if sys.hexversion < 0x3000000:
inp, rng = raw_input, xrange # Python 2.x
else:
inp, rng = input, range # Python 3.x
def type_getter(type):
"""
Build a function to prompt for input of required type
"""
def fn(prompt):
while True:
try:
return type(inp(prompt))
except ValueError:
pass # couldn't parse as the desired type - try again
fn.__doc__ = "\n Prompt for input and return as {}.\n".format(type.__name__)
return fn
get_int = type_getter(int)
get_float = type_getter(float)
# Student record datatype
Student = namedtuple('Student', ['name', 'mark'])
def get_students():
"""
Prompt for student names and marks;
return as list of Student
"""
students = []
while True:
name = inp("Enter name (or nothing to quit): ").strip()
if name:
mark = get_float("Enter {}'s mark: ".format(name))
students.append(Student(name, mark))
else:
return students
def main():
cases = get_int("How many cases are there? ")
for case in rng(1, cases+1):
print("\nCase {}:".format(case))
# get student data
students = get_students()
# perform calculations
avg = sum((student.mark for student in students), 0.) / len(students)
best_student = max(students, key=lambda x: x.mark)
# report the results
print(
"\nCase {} average was {:0.1f}%"
"\nBest student was {} with {:0.1f}%"
.format(case, avg, best_student.name, best_student.mark)
)
if __name__=="__main__":
main()
which runs like:
How many cases are there? 1
Case 1:
Enter name (or nothing to quit): A
Enter A's mark: 10.
Enter name (or nothing to quit): B
Enter B's mark: 20.
Enter name (or nothing to quit):
Case 1 average was 15.0%
Best student was B with 20.0%