I am making a music key theory test.
In order to achieve something else that I won't explain right now here (maybe I will later though if this doesn't work), I need to take the root chord out of the list, store it somewhere else, and call back upon it for the user input when they are asked what key the chords come from.
I don't know how to do this, but I am pretty sure it is possible. I would love it if someone could help me. After I have this problem sorted out I will be much further.
Before, I was trying to find someway to have the actual variable represent the variable, while representing what the variable contains. So then after printing the randomized chords from the variable, the user can input the key from which the chords come from, which I have as the variable. But I don't think that will work.
import random
print('Key Theory Werkout')
Dmajor = {'D','E-','F⌗-','G','A','B-','C⌗dim'}
Gmajor = {'G','A-','B-','C','D','E-','F⌗dim'}
Cmajor = {'C','D-','E-','F','G','A-','Bdim'}
Fmajor = {'F','G-','A-','Bb','C','D-','Edim'}
Bbmajor = {'Bb','C-','D-','Eb','F','G-','Adim'}
Ebmajor = {'Eb','F-','G-','Ab','Bb','C-','Ddim'}
Abmajor = {'Ab','Bb-','C-','Db','Eb','F-','Gdim'}
Dbmajor = {'Db','Eb-','F-','Gb','Ab','Bb-','Cdim'}
Cxmajor = {'C⌗','D⌗-','E⌗-','F⌗','G⌗','A⌗-','B⌗dim'}
Gbmajor = {'Gb','Ab-','Bb-','Cb','Db','Eb-','Fdim'}
Fxmajor = {'F⌗','G⌗-','A⌗-','B','C⌗','D⌗-','E⌗dim'}
Bmajor = {'B','C⌗-','D⌗','E','F⌗','G⌗','A⌗dim'}
Cbmajor = {'Cb','Db-','Eb-','Fb','Gb','Ab-','B-dim'}
Emajor = {'E','F⌗-','G⌗-','A','B','C⌗-','D⌗dim'}
Amajor = {'A','B-','C⌗-','D','E','F⌗-','G⌗dim'}
questions = [Dmajor, Gmajor, Cmajor, Fmajor, Bbmajor, Ebmajor,
Abmajor, Dbmajor, Cxmajor, Gbmajor, Fxmajor, Bmajor, Cbmajor,
Emajor, Amajor]
print('Difficulty:Easy, Hard')
begin = input("Choose Difficulty:")
if begin == 'easy':
while begin == "easy":
q = random.choice(questions)
qq = random.sample(list(q), 7)
print(qq)
answer = input('Please Provide the key:')
if answer == q
'''HERE IS THE PROBLEM. Lets say the code outputs F, A-, Bb, C, D-
for Dmajor. How can I have the user type in Dmajor and have it
print correct, or incorrect? I am thinking I will have to put .
entire blocks for each question, and then have the easy choose
random out of all of those questions and that will be how I have to
do it. But maybe there is an easier way.
'''
print("correct")
I would like it to tell the user if they are correct or wrong, while keeping the randomness of questions, and chords it spits out exactly the way it is.
What do I need to do?
Maybe you can try using a dictionary to represent your questions, like this:
questions = {
'Dmajor': {'D','E-','F⌗-','G','A','B-','C⌗dim'},
'Gmajor': {'G','A-','B-','C','D','E-','F⌗dim'},
'Cmajor': {'C','D-','E-','F','G','A-','Bdim'},
'Fmajor': {'F','G-','A-','Bb','C','D-','Edim'},
'Bbmajor': {'Bb','C-','D-','Eb','F','G-','Adim'},
'Ebmajor': {'Eb','F-','G-','Ab','Bb','C-','Ddim'},
'Abmajor': {'Ab','Bb-','C-','Db','Eb','F-','Gdim'},
'Dbmajor': {'Db','Eb-','F-','Gb','Ab','Bb-','Cdim'},
'Cxmajor': {'C⌗','D⌗-','E⌗-','F⌗','G⌗','A⌗-','B⌗dim'},
'Gbmajor': {'Gb','Ab-','Bb-','Cb','Db','Eb-','Fdim'},
'Fxmajor': {'F⌗','G⌗-','A⌗-','B','C⌗','D⌗-','E⌗dim'},
'Bmajor': {'B','C⌗-','D⌗','E','F⌗','G⌗','A⌗dim'},
'Cbmajor': {'Cb','Db-','Eb-','Fb','Gb','Ab-','B-dim'},
'Emajor': {'E','F⌗-','G⌗-','A','B','C⌗-','D⌗dim'},
'Amajor': {'A','B-','C⌗-','D','E','F⌗-','G⌗dim'},
}
Then, you select a random question like this:
key = random.choice(list(questions))
set = questions[key]
sample = random.sample(set, 7)
Now, you only have to check if answer is equal to key.
I am translating a kids choose your own adventure book into a python program eg, 'If you choose x go to page y or if you choose a go to page b'
While this program works, by the end of the book there will be over 100 if statements is there any way to create a table that that compares a user input to a list of pages. An example I saw while researching displayed a similar table to this:
#this would hold the potential user inputs
[0,0,0,0,0,0]
[0,0,0,0,0,0]
[0,0,0,0,0,0]
However i am unsure how to implement it
#imports the pages of the book from another python file
from Content import *
clrscrn = (chr(27) + "[2J")
def page0():
print "\n %s" % page1
page0()
#User input loop
while True:
inp = raw_input(">>> ").lower()
#clears the screen then prints the variable (page)
if inp == '3':
print clrscrn
print '%s' % page3
if inp == '10':
print clrscrn
print '%s' % page10
if inp == '5':
print clrscrn
print '%s' % page5
if inp == '14':
print clrscrn
print '%s' % page14
#quits python
elif inp == 'quit':
raise SystemExit
The only difference in each if statement is which page variable you access. Since you want to get at page14 if the user enters "14" you can use the dictionary returned by globals() to access the page variables in a dynamic way.
So, instead of hundreds of if statement, you really don't need any at all. You can use the following lines instead.
print clrscrn
print globals()['page' + inp]
Define in your head what the inputs and outputs will be.
To me, it seems likely that you will have multiple questions, on different pages. So one input would be the "current page number." That would identify the question.
The other input, of course, would be the user's response. In a binary (yes/no) system, there would always be exactly two possible responses from the user (yes, or no). In a non-binary system, there might be more possible responses.
I'd suggest that you assume non-binary, and further, even if only one question is possibly non-binary, go with that. It helps keep things consistent.
Let's assume, then, that you've got a non-binary system with 100 questions. Each question appears at the end of a "page." (Maybe it's at the end of a "chapter" or "paragraph" or something. Feel free to replace words.) When the user answers, they are directed to go to a different "page."
So your mapping is going to be "current page + user input -> new page".
The easiest way to implement this in python is with a list of dictionaries. The list index can be the current page. That will identify the question, and the possible responses. The responses (keys in the dictionary) can be text strings. The results (values from the dictionary) will be integers, indicating the new page number. Thus:
Pages = [ # List of questions, one per page. Use {} for page with no Q
{}, # 0
{}, # 1
{
"yes": 12,
"no": 16,
}, # 2
]
If you want to be a little more efficient, you can store the questions in the same list, using a key like " q " which cannot be input by the user (because you will run .strip() on the user input, naturally)!
{
" q ": "Do you like pizza?",
"yes": 12,
"no": 16,
}
If you're feeling really energetic, you can make the dictionaries into a class, with attributes, store the various pages as JSON, etc.
In the book "Python for the absolute beginner" by Michael Dawson, in the chapter on Lists and Dictionaries I have learned a great deal and am trying to make a new program as practice using the old Magic 8-Ball as my inspiration. Below is the code I have come up with so far.
It works up to a point...the random generated number gets generated but the elif doesn't seem to work. I know there are better ways and simpler ways, but I am doing this to reinforce my understanding of dictionaries.
I have put several print statements in to see if I was getting a number selected and the else statement is if all goes bad. As the code stands now all I get is the number printed and the else produces "Does not compute. Exit works fine. I have also confirmed the dictionary is fine using the commented out print "ball" statement.
So my issue is why does the elif statement seem to not process the random number generated. Whom ever answers has my heartfelt thanks and appreciation.
# Import the modules
import sys
import random
# define magic 8-ball dictionary
ball = {"1" : "It is certain.",
"2" : "Outlook is good.",
"3" : "You may rely on it.",
"4" : "Ask again later.",
"5" : "Concentrate and ask again.",
"6" : "Reply is hazy, try again later.",
"7" : "My reply is no.",
"8" : "My sources say no"}
# for items in ball.items():
# print(items)
ans = True
while ans:
question = input("Ask the Magic 8 Ball a question: (press enter to quit) ")
answer = random.randint(1,8)
print(answer)
if question == "":
sys.exit()
elif answer in ball:
response = ball[answer]
print(answer, response)
else:
print("\nSorry", answer, "does not compute.\n")
random.randint() returns an integer. Your dictionary's keys are all strings. Thus, when you do answer in ball, it will always be False, because "1" != 1
What you can do is either make all the keys integers (remove the quotation marks), or make answer a string by doing:
answer = str(random.randint(1,8))
Note that you shouldn't be using an elif here. If your input is nothing, both your if and elif will be True, and most of the time you don't want this. Instead, change your elif/else to just an if/else:
if question == "":
sys.exit()
if answer in ball:
response = ball[answer]
print(answer, response)
else:
print("\nSorry", answer, "does not compute.\n")
One final thing. answer will always be in ball, because you dynamically created the dictionary. Here, you can use dict.get(). Eg:
if not question: # You can do this instead
sys.exit()
print(ball.get(answer))
You are looking up on the dictionary with a number whereas the keys are strings in the dict. So, you have to convert the number to string with str.
Change
answer = random.randint(1,8)
to
answer = str(random.randint(1,8))
The string "1" is not the int 1. So answer is actually not in ball.
Try converting it like answer = str(random.randint(1,8))
I am working on a quiz game and when I get asked any question, i type in the right answer, which I defined in the a variable that holds that correct answer but it says it is wrong if it isn't the first word for that variable (In this case, Metallica). Here is what my code looks like.
q1answer = "Metallica" or "metallica" or "Slayer" or "slayer" or "Anthrax" or "anthrax" or "Megadeth" or "megadeth"
answerinput = str(input("name one of the 'Big Four' metal bands'"))
if answerinput == q1answer:
print ("You got the right answer!")
else:
print ("That is the wrong answer...")
Now, if I was to type in 'Metallica' it would be correct because it is the first word for the q1answer variable. But, if I type metallica, Slayer, slayer, Anthrax, anthrax, megadeth or Megadeth, I would get the wrong answer text. Is there a way for all of these strings to be working for this one variable if i was to type anything but the first word in that variable? I'm a rookie in python so any help would be great.
Put them in a set and test for a correct answer using in instead:
q1answer = {"Metallica", "metallica", "Slayer", "slayer", "Anthrax", "anthrax", "Megadeth", "megadeth"}
...
if answerinput in q1answer:
Right now, your series of ors is just resulting in the first one - "Metallica". You can also stop duplicating every name for case-insensitivity and instead use lower:
if answerinput.lower() in q1answer:
Change your code like this:
q1answer = ("metallica", "slayer", "anthrax", "megadeth")
...
if answerinput.lower() in q1answer:
...