1

I'm trying to make a music player that allows a song to be put into the shell and is then played however, I'm having an issue with a type error in class Notes(): and I can't figure out why.

import winsound
import time

length = 125

class Notes():
    def processNote(note):
        if(note == 'C'):return Notes.processNote(262)
        if(note == 'D'):return Notes.processNote(294)
        if(note == 'D5'):return Notes.processNote(587)
        if(note == 'A'):return Notes.processNote(440)
        if(note == 'Ab'):return Notes.processNote(415)
        if(note == 'G'):return Notes.processNote(392)
        if(note == 'F'):return Notes.processNote(349)
        if(note == 'B'):return Notes.processNote(247)
        if(note == 'Bb'):return Notes.processNote(233)
song = "CCCCCCCCCCCD"
noteList = list(song)
print(noteList)

for note in noteList:
    print("Doing ", note)
    frequency = Notes.processNote(note)
    winsound.Beep(frequency, length)

The error:

Traceback (most recent call last):
  File "C:\Python\Tester.py", line 27, in <module>
    winsound.Beep(frequency, length)
TypeError: an integer is required (got type NoneType)
3
  • I believe you just mean return 262 and so on; currently you are calling your function twice, and the second time always returns None because you are passing it an integer your function only handles strings. Commented Oct 9, 2016 at 9:33
  • It seems like your .processNote method returns None. Commented Oct 9, 2016 at 9:33
  • Oh I didn't realise the fix was that simple thank you! Commented Oct 9, 2016 at 9:36

2 Answers 2

1

And if I can say something, instead of

class Notes():
    def processNote(note):
        if(note == 'C'):return Notes.processNote(262)
        if(note == 'D'):return Notes.processNote(294)
        if(note == 'D5'):return Notes.processNote(587)
        (thousands IFs)

You could use the python dictionary and create mapping:

class Notes():
    def processNote(note):
        signature_to_freq = {'C': 262, 'D': 294, 'D5': 587,
                            'B': 247}
        return signature_to_freq[note]
Sign up to request clarification or add additional context in comments.

2 Comments

Well it's also better (easier) to change the return of the function. Edited.
Oh that's a much tidier way of writing it. I'll try to swap that in thank you.
0

Currently, the function processNote() returns None for any valid input, because you are calling it twice instead of just returning the value. It may be helpful to look at how your code will be processed to understand why this happens:

Imagine processNote() is called with the note value "C". That will match the first if statement and it will return the result of calling processNote() with the value 262. Since there's no if statement that catches 262 in the processNote() function, it returns None (because this is the default for Python functions), so the frequency variable ends up being None.

You can solve this rather simply, by just returning the literal value:

def processNote(note):
    if note == 'C':
        return 262
    ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.