Milikeye
Milikeye

Reputation: 19

'int' object is not subscriptable error

I am a beginner at python, I am trying to make a program that quizzes you on what note is on what fret of the guitar.

I've changed my code up some, but now the error says -

Traceback (most recent call last):
  File "C:\Users\Jesse\Documents\Documents\Games I have created\Python games\Guitar Memorization.py", line 107, in <module>
    print (guessing(string, question_type, correct, notes, guess, note, other_string, guessed))
  File "C:\Users\Jesse\Documents\Documents\Games I have created\Python games\Guitar Memorization.py", line 46, in guessing
    note = random.choice(notes not in guessed)
  File "C:\Python33\lib\random.py", line 248, in choice
    i = self._randbelow(len(seq))
TypeError: object of type 'bool' has no len()

How can I fix it now?

import random
import sys

string1 = {"E":0,"F":1,"G":3,"A":5,"B":7,"C":8,"D":10,"E":12}
string2 = {"A":0,"B":2,"C":3,"D":5,"E":7,"F":8,"G":10,"A":12}
string3 = {"D":0,"E":2,"F":3,"G":5,"A":7,"B":9,"C":10,"D":12}
string4 = {"G":0,"A":2,"B":4,"C":5,"D":7,"E":9,"F":10,"G":12}
string5 = {"B":0,"C":1,"D":3,"E":5,"F":6,"G":8,"A":10,"B":12}
string6 = {"E":0,"F":1,"G":3,"A":5,"B":7,"C":8,"D":10,"E":12}

string = random.randint(1,6)
question_type = random.randint(1,2)
correct = 0
notes = []
guess = 0
note = 0
other_string = {}
guessed = []
def guessing (string, question_type, correct, notes, guess, note, other_string, guessed):
    if question_type == 1:
        if string == 1:
            other_string = string1
            for key,value in string1.items():
                notes.append(key)
            note = random.choice(notes not in guessed)
            guess = input("On the first string, where is the " + note + " note?")

        elif string == 2:
            other_string = string2
            for key,value in string2.items():
                notes.append(key)
            note = random.choice(notes not in guessed)
            guess = input("On the second string, where is the " + note + " note?")

        elif string == 3:
            other_string = string3
            for key,value in string3.items():
                notes.append(key)
            note = random.choice(notes not in guessed)
            guess = input("On the third string, where is the " + note + " note?")

        elif string == 4:
            other_string = string4
            for key,value in string4.items():
                notes.append(key)
            note = random.choice(notes not in guessed)
            guess = input("On the fourth string, where is the " + note + " note?")

        elif string == 5:
            other_string = string5
            for key,value in string5.items():
                notes.append(key)
            note = random.choice(notes not in guessed)
            guess = input("On the fifth string, where is the " + note + " note?")

        elif string == 6:
            other_string = string6
            for key,value in string6.items():
                notes.append(key)
            note = random.choice(notes not in guessed)
            guess = input("On the sixth string, where is the " + note + " note?")
    elif question_type == 2:
        if string == 1:
            other_string = string1
            for key,value in string1.items():
                notes.append(value)
            note = random.choice(notes not in guessed)
            guess = input("On the first string, what note is at the " + str(note) + " fret?")

        elif string == 2:
            other_string = string2
            for key,value in string2.items():
                notes.append(value)
            note = random.choice(notes not in guessed)
            guess = input("On the second string, what note is at the " + str(note) + " fret?")

        elif string == 3:
            other_string = string3
            for key,value in string3.items():
                notes.append(value)
            note = random.choice(notes not in guessed)
            guess = input("On the third string, what note is at the " + str(note) + " fret?")

        elif string == 4:
            other_string = string4
            for key,value in string4.items():
                notes.append(value)
            note = random.choice(notes not in guessed)
            guess = input("On the fourth string, what note is at the " + str(note) + " fret?")

        elif string == 5:
            other_string = string5
            for key,value in string5.items():
                notes.append(value)
            note = random.choice(notes not in guessed)
            guess = input("On the fifth string, what note is at the " + str(note) + " fret?")

        elif string == 6:
            other_string = string6
            for key,value in string6.items():
                notes.append(value)
            note = random.choice(notes not in guessed)
            guess = input("On the sixth string, what note is at the " + str(note) + " fret?")
        guessed.append(note)
        return guess
while correct < 8:
    return guessing(string, question_type, correct, notes, guess, note, other_string, guessed)
    if guess == other_string[note]:
        print("Good Job.")
        correct +=1
    else:
        print("Not quite")
        return guessing()
else:
    print ("Good Job! You got all of the questions right!")

Thanks to everyone who is helping me out with this.

Upvotes: 1

Views: 1109

Answers (4)

jonrsharpe
jonrsharpe

Reputation: 122024

Although others have identified the specific error, I thought you might be interested to see an alternative implementation addressing the concerns I raised in my comment:

import random

class Guitar:

    NAMES = {1: "first", 2: "second", 3: "third",
               4: "fourth", 5: "fifth", 6: "sixth"}

    STRINGS = {1: "E", 2: "B", 3: "G", 4: "D", 5: "A", 6: "E"}

    NOTES = ["A", "A#", "B", "C", "C#", "D",
             "D#", "E", "F", "F#", "G", "G#"] * 2

    FRETS = 12

    def play(self, guesses=8):
        while True:
            question = random.randrange(2)
            self.string = random.choice(self.STRINGS.keys())

            if question:
                answer = random.choice(self.NOTES)
                template = "On the {0} string, which fret is {1}? "
                valid_input = self.valid_fret
                checker = self.note_at_fret                
            else:
                answer = random.randint(0, self.FRETS)
                template = "On the {0} string, which note is fret {1}? "
                valid_input = self.valid_note
                checker = self.fret_of_note

            prompt = template.format(self.NAMES[self.string], answer) 
            for _ in range(guesses):
                if checker(valid_input(prompt)) == answer:
                    print("Correct!\n")
                    break
                print("Incorrect.")
            else:
                print("Out of guesses.\n")

    def valid_fret(self, prompt):
        while True:
            fret = input(prompt)
            try:
                fret = int(fret)
            except ValueError:
                print("Not a valid fret.")
            else:
                if fret in range(self.FRETS+1):
                    return fret
                print("Not a valid fret.")

    def valid_note(self, prompt):
        while True:
            note = input(prompt).upper()
            if note in self.NOTES:
                return note
            print("Not a valid note.")

    def note_at_fret(self, fret):
        return self.string_notes()[fret]

    def fret_of_note(self, note):
        return self.string_notes().index(note)

    def string_notes(self):
        open_string = self.STRINGS[self.string]
        return self.NOTES[self.NOTES.index(open_string):]

if __name__ == "__main__":
    Guitar().play()

Note:

  1. A class has been defined to hold the state required, removing the global variables;
  2. Factored out the "magic number" 8 to an easy-to-understand argument;
  3. Dictionaries, str.format and assignment of methods (e.g. self.valid_note) to local names (e.g. valid_input) have been used to reduce duplication;
  4. Separate functions have broken the program up into smaller, easier-to-understand "chunks" of functionality;
  5. Input validation has been added to prevent the user crashing the program;
  6. Minimal data in variable names (e.g. string1, string2 is bad practice that suggests that a list should have been used); and
  7. No limitation on the notes/frets to be selected - it's all dealt with automatically.

You can even use sub-classing to easily test yourself on non-standard tunings:

class OpenG(Guitar):
    STRINGS = {1: "D", 2: "B", 3: "G", 4: "D", 5: "G", 6: "D"}


OpenG().play()

Upvotes: 0

Haifeng Zhang
Haifeng Zhang

Reputation: 31895

string1 = {"E":0,"F":1,"G":3,"A":5,"B":7,"C":8,"D":10,"E":12}
string2 = {"A":0,"B":2,"C":3,"D":5,"E":7,"F":8,"G":10,"A":12}
string3 = {"D":0,"E":2,"F":3,"G":5,"A":7,"B":9,"C":10,"D":12}
string4 = {"G":0,"A":2,"B":4,"C":5,"D":7,"E":9,"F":10,"G":12}
string5 = {"B":0,"C":1,"D":3,"E":5,"F":6,"G":8,"A":10,"B":12}
string6 = {"E":0,"F":1,"G":3,"A":5,"B":7,"C":8,"D":10,"E":12}
  1. When initilize other_string, use other_string = {} other than other_string = 0, this will tell you other_string is a dictionary, and you should only use it as dictionary other than any other data structures; the other_string[note] is an int value.

  2. declare other_string as global in your guessing() method, then you can modify it in the body of guessing()

  3. print(guessing()) will not print anything, you did not return any value in your guessing() method, you should add return guess at the end, and it should be aligned with the outer if-elif statement.

Upvotes: 1

freude
freude

Reputation: 3832

other_string is not an iterable object. You might initialize it as other_string=[]

Upvotes: 0

mshildt
mshildt

Reputation: 9352

You don't have other_string marked as global in guessing, so when you assign it to a string in guessing() it is creating a new variable other_string that is just in the scope of the guessing() function. To fix this, add global other_string to the top of guesing() to make your reassignment of it within guessing() visible at the global scope. Without this, other_string is still seen as an int in the global namespace, and ints cannot be subscripted .

Upvotes: 1

Related Questions