monchovarela
6/7/2019 - 7:24 PM

Metronomo

# Metronome - Johnathon Kwisses (Kwistech)
from tkinter import *
from winsound import Beep


class Metronome:
    """Create Metronome app with class instance."""

    def __init__(self, root, beats):
        """Initiate default values for class and call interface().

        Args:
            root (tkinter.Tk): Main class instance for tkinter.
            beats (list): Contains time signatures for metronome.
        """
        self.root = root
        self.beats = beats

        self.start = False
        self.bpm = 0
        self.count = 0
        self.beat = 0
        self.time = 0

        self.var = StringVar()
        self.var.set(self.count)

        self.interface()

    def interface(self):
        """Set interface for Metronome app."""
        frame = Frame()
        frame.pack()

        entry = Entry(frame, width=8, justify="center")
        entry.insert(0, "60")
        entry.grid(row=0, column=0, padx=5, sticky="E")

        spinbox = Spinbox(frame, width=5, values=self.beats, wrap=True)
        spinbox.grid(row=0, column=1, sticky="E")

        label_bpm = Label(frame, text="BPM:")
        label_bpm.grid(row=0, column=0, sticky="W")

        label_time = Label(frame, text="Time:")
        label_time.grid(row=0, column=1, padx=5, sticky="W")

        label_count = Label(frame, textvariable=self.var, font=("Arial", 30))
        label_count.grid(row=1, column=0, columnspan=2)

        button_start = Button(frame, text="Start", width=10, height=2,
                              command=lambda: self.start_counter(entry,
                                                                 spinbox))
        button_start.grid(row=2, column=0, padx=10, sticky="W")

        button_stop = Button(frame, text="Stop", width=10, height=2,
                             command=lambda: self.stop_counter())
        button_stop.grid(row=2, column=1, padx=10, sticky="E")

    def start_counter(self, entry, spinbox):
        """Start counter if self.start is False (prevents multiple starts).

        Args:
            entry (tkinter.Entry): tkinter Entry widget for app.
            spinbox (tkinter.Spinbox): tkinter Spinbox widget for app.

        Raises:
            ValueError: if bpm field (self.bpm) on tkinter app is left blank.
        """
        if not self.start:
            try:
                self.bpm = int(entry.get())
            except ValueError:
                self.bpm = 60
            else:
                if self.bpm > 300:  # Limits BPM
                    self.bpm = 300

            self.start = True
            self.counter(spinbox)

    def stop_counter(self):
        """Stop counter by setting self.start to False."""
        self.start = False

    def counter(self, spinbox):
        """Control counter display and audio with calculated time delay.

        Args:
            spinbox (tkinter.Spinbox): tkinter Spinbox widget to get beat.
        """
        if self.start:
            self.beat = int(spinbox.get()[0])

            if self.beat == 6:  # 6/8 time
                self.time = int((60 / (self.bpm / .5) - 0.1) * 1000)
            else:
                self.time = int((60 / self.bpm - 0.1) * 1000)  # Math for delay

            self.count += 1
            self.var.set(self.count)

            if self.count == 1:
                Beep(480, 100)
            elif self.count >= self.beat:
                self.count = 0
                Beep(435, 100)
            else:
                Beep(440, 100)

            # Calls this method after a certain amount of time (self.time).
            self.root.after(self.time, lambda: self.counter(spinbox))


def main():
    """Call Metronome class instance with tkinter root class settings."""
    root = Tk()
    root.title("Metronome")

    beats = ["4/4", "6/8", "2/4", "3/4"]
    Metronome(root, beats)

    root.mainloop()

if __name__ == "__main__":
    main()
# Metronome (4/4)

from time import sleep
from winsound import Beep


def metronome(bpm):
    """Metronome that asks the user for the BPM (Beats-Per-Minute) and prints 4-count and windows audio beep.

    Args:
        bpm (int): Beats-Per-Minute.

    """
    count = 0

    while count <= 4:
        sleep(float(60 / bpm - 0.1))
        count += 1
        print(count)
        Beep(440, 100)

        if count == 4:
            count = 0

metronome(int(input("Enter BPM: ")))