0

I did quite a lot of research both within and outside of stackoverflow. Yes, there are similar topics. But I could not find the answer to my specific problem. Maybe because I can not see the bigger picture yet with my current understanding of Python.

In the last line I get the error "No value for argument 'self' in method call". How would I have to properly call the method here? Or is it not possible at all to call methods within the same class?

class Main:
    metronomeState = True
    currentMillis = 0
    lastMillis = 0
    intervalMillis = 0
    bpm = 120
    measureCount = 0

    def bpmToMilliInterval(self):
            self.bps = Main.bpm/60
            return int((1/self.bps)*1000)

    Main.intervalMillis = Main.bpmToMilliInterval()

It might seem that there would be no reason for this class because I do not need to instantiate it. But I want to use the code of Main() in another class Gui() which is responsible for all the GUI stuff. So the different classes are a way for me to organize the code. Good approach or not?

Thanks in advance for your help!

3
  • 1
    Is that indentation correct? Also, you are calling a supposed instance method on the class. Do you want to set a class attribute during the class definition? Commented Oct 21, 2020 at 17:02
  • 3
    Your class's only instance attribute is bps, and it's not established in __init__; all the other attributes are class attributes. Is it supposed to be possible to make instances of Main? If not, this is a very weird class, but you'd probably want to just make bpmToMilliInterval an @classmethod (assuming bps needs to be preserved beyond the call) and (solely for proper style) change all references to self to cls. That final line would have to be outside the class definition (I suspect it is in your real code, since it wouldn't be legal to have it inside the class either way). Commented Oct 21, 2020 at 17:03
  • 1
    Just because you might not need more than one instance doesn't mean you shouldn't have an instance. If you class only has the one method (which could be a class method), it could simply be a regular function that takes a lot of arguments (most of which would have defaults values). Commented Oct 21, 2020 at 17:05

2 Answers 2

1

The problem here is that you are writing your class without a init function and that your class doesn't have self variables.

For example:

class Person:

  def __init__(self):
    health = 100
    name = "Harry"


  def changeName(self,newName):

    self.name = newName

Only works because there is the init function. The reasoning for self variables like self.name is so the values can be edited later, like you tried with Main.bps. If you have self.bps in an init function, it can be edited later within your function, given you also write self.bps in the function. I'm not sure about just using things like bpm on their own in a class rather than self.bps because i'm sure bps would be private within the scope of Main disregarding functions. Also, be sure to check your indentations! :)

Sign up to request clarification or add additional context in comments.

Comments

0

Thanks for all of your comments! I figured something out that works. I hope it makes sense, too. And I fixed my indentations.

import winsound
import time

class MetronomeCalc:
    def __init__(self):
        self.metronomeState = True
        self.currentMillis = 0
        self.lastMillis = 0
        self.intervalMillis = 0
        self.bpm = 120
        self.bps = 0
        self.bpms = 0
        self.measureCount = 0

    def getBpm(self):
        bpm = 120
        return bpm

    def bpmToMilliInterval(self):
        self.bps = self.bpm/60
        self.intervalMillis = int((1/self.bps)*1000)

    def playMetronome(self):
        self.bpmToMilliInterval()
        while self.measureCount < 8:
            if self.currentMillis - self.lastMillis >= self.intervalMillis:
                self.lastMillis = int(round(time.time()*1000))
                winsound.Beep(1000, 100)
                self.measureCount = self.measureCount + 1
            else:
                self.currentMillis = int(round(time.time()*1000))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.