Script gegen Bezahlung

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Ok, Programm startet - YEAH

Es kommt die Teamauswahl, drücke ich den blauen Button, kommt die folgende Fehlermeldung:
Traceback (most recent call last):
File "quidditch.py", line 232, in <module> main()
File "quidditch.py", line 220, in main teams = select_teams(queue)
File "quidditch.py", line 121, in select_teams selected.add(color)
AttributeError: 'dict' object has no attribute 'add'
Benutzeravatar
sparrow
User
Beiträge: 4188
Registriert: Freitag 17. April 2009, 10:28

Code: Alles auswählen

from RPi import GPIO
from queue import Queue, Empty
from termcolor import cprint
import spidev
import time
import random
import sys
import os

GREEN = 4
YELLOW = 3
RED = 27
BLUE = 17
SNATCH = 2

TEAM_LIGHTS = [BLUE, RED, YELLOW, GREEN]
ALL_LIGHTS = [SNATCH] + LIGHTS

BUTTONS = {
    14: GREEN,
    24: YELLOW,
    18: RED,
    15: BLUE,
    23: SNATCH,
}

TEAMS = {
    GREEN: ("Slytherin", "green"),
    YELLOW: ("Hufflepuff", "yellow"),
    RED: ("Gryffindor", "red"),
    BLUE: ("Ravenclaw", "blue"),
}

DURATIONS = {
    BLUE: (2, "blau", "blue"),
    RED: (5, "rot", "red"),
    YELLOW: (10, "gelb", "yellow"),
    GREEN: (15, "gruen", "green"),
}

LASER_GATES = [
    (26, 19), (13, 21), (20, 16)
]

class Team:
    def __init__(self, team_name, color):
        self.team_name = team_name
        self.color = color
        self.taster = taster
        self.points = 0

    def show_points(self):
        cprint(f"{self.team_name}: {self.points}", color=self.color)

def light_off(pin):
    GPIO.setup(pin, GPIO.HIGH)

def light_on(pin):
    GPIO.setup(pin, GPIO.LOW)

def play_lights1():
    for i in range(3):
        light_on(LIGHTS)
        time.sleep(0.2)
        light_off(LIGHTS)
        time.sleep(0.2)

def play_lights2():
    for led_pin in TEAM_LIGHTS:
        light_on(led_pin)
        time.sleep(0.2)
        light_off(led_pin)
        time.sleep(0.2)
    for i in range(3):
        light_on(TEAM_LIGHTS)
        time.sleep(0.2)
        light_off(TEAM_LIGHTS)
        time.sleep(0.2)

def play_lights3():
    for pin in ALL_LIGHTS:
        light_on(pin)
        time.sleep(1)
    time.sleep(4)
    for pin in ALL_LIGHTS:
        light_off(pin)
        time.sleep(1)

def checkstart():
    rings = []
    for gate_a, gate_b in LASER_GATES:
        rings.append(GPIO.input(gate_a) + GPIO.input(gate_b))
    for nr, ring in enumerate(rings, 1):
        p = [100, 50, 0][ring]
        cprint(f"Status Ring {nr}: {p}%s")

def check_gates():
    # TODO: keine Ahnung was das soll
    rings = []
    for gate_a, gate_b in LASER_GATES:
        rings.append((GPIO.input(gate_a), GPIO.input(gate_b)))
    if rings[2][1]:
        ring = 2
    elif rings[1][1] or not rings[1][0]:
        ring = 1
    elif rings[0][0] or rings[0][1]:
        ring = 0
    else:
        ring = 3
    if ring != 3:
        cprint("PUNKTE")
        cprint(str(ring))
        time.sleep(1)
    return ring

def clear_queue(queue):
    try:
        while True:
            queue.get_nowait()
    except Empty:
        pass

def select_teams(queue):
    light_off(ALL_LIGHTS)
    cprint("Bitte waehlen Sie mit den Farben die mitspielenden Teams aus. Bestaetigen Sie ihre Auswahl mit dem Schnatz")
    selected = []
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected:
                break
            # blink lights if no team is selected
            play_lights1()
        else:
            if color in selected:
                selected.remove(color)
                light_off(color)
            else:
                selected.add(color)
                light_on(color)
    light_off(ALL_LIGHTS)
    return [
        Team(color, *TEAMS[color])
    ]

def select_duration():
    cprint("Bitte waehlen Sie die Dauer des Spiels aus:")
    for duration, name, color in sorted(DURATIONS.values()):
        cprint(f"{name} = {duration} Minuten", color=color)
    cprint ("Das Spiel wird mit dem Schnatz gestartet")
    selected_duration = 0
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected_duration != 0:
                break
            play_lights2()
        else:
            selected_duration = DURATIONS[color][0]
            light_off(TEAM_LIGHTS)
            light_on(color)
    return select_duration

def display_gates(gates):
    cprint("Tore", end=" ")
    for nr, gate in enumerate(gates, 1):
        cprint(f"Tor {nr} ", end=" ")
        if gate is None:
            cprint("DEFEKT", color="grey", end=" ")
        else:
            cprint(gate.team_name, color=gate.color, end=" ")

def schnatz_active(teams):
    selected = random.choice([None] + teams)
    if selected is None:
        licht_aus(LICHT_schnatz)
    else:
        licht_an(LICHT_schnatz)
        cprint("Der Schnatz wurde gesichtet! Er kann von folgendem Team gefangen werden:")
        cprint(selected.team_name, color=selected.color, end=" ")
    return selected

def display_results(teams):
    cprint("Das Spiel ist zu Ende! Eine herausragende Leistung von allen Teilnehmern!")
    cprint("ERGEBNIS:")
    teams = sort(teams, key=lambda t: t.points, reverse=True)
    for team in teams[:3]:
        team.show_points()
    play_lights3()

def run_game(teams, duration):
    schnatz_timer = None
    gate_time = 0
    start = time.time()
    ende = start + duration
    while True:
        akt_zeit = time.time()
        if akt_zeit > gate_time:
            gates = [
                random.choice([None] + teams)
                for _ in range(3)
            ]
            display_gates(gates)
            gate_time = akt_time + 10

        if akt_zeit > ende:
            if schnatz_timer is None:
                schnatz_status = schatz_active(teams)
                schnatz_timer = akt_zeit + random.randint(1,10)
            elif akt_zeit < schnatz_timer: #TODO: and schnatz == FALSE:
                break
        check_ring = check_gates()
        if check_ring != 3:
            team = gates[check_ring]
            if team is not None:
                team.points += 10
                team.show_points()
    cprint("Spielende")
    if schnatz_status is not None:
        schnatz_status.points += 150

def initialize(buttons):
    queue = Queue()
    GPIO.setmode(GPIO.BCM)
    for button, led in buttons.items():
        GPIO.setup(led, GPIO.OUT)
        GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(button, GPIO.FALLING, queue.put)
    for gates in LASER_GATES:
        GPIO.setup(gates, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    return queue

def main():
    try:
        queue = initialize(BUTTONS)
        while True:
            teams = select_teams(queue)
            duration = select_duration() * 60
            checkstart()
            cprint("Am Spiel nehmen die folgenden Mannschaften teil:")
            for team in teams:
                cprint(team.team_name, color=team.color)
            run_game(teams, duration)
            display_results(teams)
    finally:
        GPIO.cleanup()

if __name__ == "__main__":
    main()


selected = {} zu selected = []
Liste statt dict.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Keine Ahnung, was ich mir dabei gedacht hatte:

Code: Alles auswählen

def select_teams(queue):
    light_off(ALL_LIGHTS)
    cprint("Bitte waehlen Sie mit den Farben die mitspielenden Teams aus. Bestaetigen Sie ihre Auswahl mit dem Schnatz")
    selected = set()
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected:
                break
            # blink lights if no team is selected
            play_lights1()
        else:
            if color in selected:
                selected.remove(color)
                light_off(color)
            else:
                selected.add(color)
                light_on(color)
    light_off(ALL_LIGHTS)
    return [
        Team(color, *TEAMS[color])
        for color in selected
    ]
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

habe ich geändert - bleibt aber bei der gleichen Fehlermeldung:

...
...
AttributeError: 'list' object has no attribute 'add'
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Übrigens - habe jetzt auch mal Teamviewer auf dem Pi installiert - vielleicht ist es einfacher, wenn man sich mal zusammen drauf verbindet?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Netdeus: Du hast nicht meine Variante versucht, denn Listen haben nur eine append-Methode.
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Ok, sorry - gerade gesehen.

Habe nun deine Variante und theoretisch sind wir wohl nun einen Schritt weiter.

Bei der Auswahl müssen die "buttons" aber ziemlich schnell gedrückt werden und es ist mehr Zufall, dass sie gedrückt bleiben, hier müsste wohl noch ein kurzer Sleep rein...

Habe zum Test mal drei Teams gewählt und den Schnatz gedrückt, dann die nächste Fehlermeldung:
Traceback (most recent call last):
File "quidditch.py", line 232, in <module>
main()
File "quidditch.py", line 220, in main
teams = selct_teams(queue)
File "quidditch.py", line 125, in select_teams
Team(color, "TEAMS[color])
KeyError: 2
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Deine Variable color hat den Wert 2, in deinem Dictionary TEAMS gibt es aber keinen Key mit 2.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Wegen ›if color == SNATCH:‹ dürftest Du erst gar nicht 2 als Wert erhalten. Die Fehlermeldung ist auch komisch, weil es eine Funktion mit dem Namen ›selct_teams‹ geben dürfte, bei mir heißt die ›select_teams‹. Also welches Programm führst Du denn aus?
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Ich habe dein Programm verwendet, mich nur beim Abschreiben der Fehlermeldung vertan und verschrieben. Diese lautete natürlich select_teams
Benutzeravatar
__blackjack__
User
Beiträge: 13082
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Netdeus: Pssst, man muss Texte nicht abschreiben. Es gibt so etwas wie kopieren und einfügen. 🙂
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Danke für die Info - das ist aus anderen Gründen etwas komplizierter hier.

Aber so oder so - mir fehlt noch immer eine Lösung zur Fehlermeldung...jemand eine Idee??
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich hatte die doch geschrieben, dass die Fehlermeldung mit meinem Code so nicht aufgetreten kann, weil der Fall color == SNATCH weiter oben anders behandelt wird. Also führst du irgendeinen Code aus, den wir nicht kennen. Deshalb den vollen Code und die komplette Fehlermeldung hier hinein kopieren.
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Hi;

hier nochmal das aktuelle Script kopiert..

Code: Alles auswählen

from RPi import GPIO
from queue import Queue, Empty
from termcolor import cprint
import spidev
import time
import random
import sys
import os

GREEN = 4
YELLOW = 3
RED = 27
BLUE = 17
SNATCH = 2

TEAM_LIGHTS = [BLUE, RED, YELLOW, GREEN]
ALL_LIGHTS = [SNATCH] + TEAM_LIGHTS

BUTTONS = {
    14: GREEN,
    24: YELLOW,
    18: RED,
    15: BLUE,
    23: SNATCH,
}

TEAMS = {
    GREEN: ("Slytherin", "green"),
    YELLOW: ("Hufflepuff", "yellow"),
    RED: ("Gryffindor", "red"),
    BLUE: ("Ravenclaw", "blue"),
}

DURATIONS = {
    BLUE: (2, "blau", "blue"),
    RED: (5, "rot", "red"),
    YELLOW: (10, "gelb", "yellow"),
    GREEN: (15, "gruen", "green"),
}

LASER_GATES = [
    (26, 19), (13,21), (20,16)
]

class Team:
    def __init__(self, team_name, color):
        self.team_name = team_name
        self.color = color
        selt.taster = taster
        self.points = 0

    def show_points(self):
        cprint(f"{self.team_name}: {self.points}", color=self.color)

def light_off(pin):
    GPIO.setup(pin, GPIO.HIGH)

def light_on(pin):
    GPIO.setup(pin, GPIO.LOW)

def play_lights1():
    for i in range(3):
        light_on(LIGHTS)
        time.sleep(0.2)
        light_off(LIGHTS)
        time.sleep(0.2)

def play_lights2():
    for led_pin in TEAM_LIGHTS:
        light_on(led_pin)
        time.sleep(0.2)
        light_off(led_pin)
        time.sleep(0.2)
    for i in range(3):
        light_on(TEAM_LIGHTS)
        time.sleep(0.2)
        light_off(TEAM_LIGHTS)
        time.sleep(0.2)

def play_lights3():
    for pin in ALL_LIGHTS:
        light_on(pin)
        time.sleep(1)
    time.sleep(4)
    for pin in ALL_LIGHTS:
        light_off(pin)
        time.sleep(1)

def checkstart():
    rings = []
    for gate_a. gate_b in LASER_GATES:
        rings.append(GPIO.input(gate_a) + GPIO.input(gate_b))
    for nr, ring in enumerate(rings, 1):
        p = [100, 50, 0][ring]
        cprint(f"Status Ring {nr}: {p}%s")

def clear_queue(queue):
    try:
        while True:
            queue.get_nowait()
    except Empty:
        pass

def select_teams(queue):
    light_off(ALL_LIGHTS)
    cprint("Bitte waehlen Sie mit den Farben die mitspielenden Teams aus. Bestaetigen Sie ihre Auswahl mit dem Schnatz")
    selected = set()
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected:
                break
            #blink lights if no team is selected
            play_lights()
        else:
            if color in selected:
                selected.remove(color)
                light_off(color)
            else:
                selected.add(color)
                light_on(color)
    light_off(ALL_LIGHTS)
    return [
        Team(color, *TEAMS[color])
    ]

def select_duration():
    cprint("Bitte waehlen Sie die Dauer des Spiels aus:")
    for duration, name, color in sorted(DURATIONS.values()):
        cprint(f"{name} = {duration} Minuten", color=color)
    cprint ("Das Spiel wird mit dem Schnatz gestartet")
    selected_duration = 0
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected_duration != 0:
                break
            play_lights2()
        else:
            selected_duration = DURATIONS[color] [0]
            light_off(TEAM_LIGHTS)
            light_on(color)
    return selected_duration

def display_gates(gates):
    cprint("Tore", end=" ")
    for nr, gate in enumerate(gates, 1):
        cprint(f"Tor {nr} ", end=" ")
        if gate is None:
            cprint("DEFEKT", color="grey", end=" ")
        else:
            cprint(gate.team_name, color=gate.color, end=" ")

def schnatz_active(teams):
    selected = random.choice([None] + teams)
    if selected is None:
        licht_aus(LICHT_schnatz)
    else:
        licht_an(LICHT_schnatz)
        cprint("Der Schnatz wurde gesichtet! Er kann von folgendem Team gefangen werde:")
        cprint(selected.team_name, color=selected.color, end=" ")
    return selected

def display_results(teams):
    cprint("Das Spiel ist zu Ende! Eine herausragende Leistung von allen Teilnehmern:")
    cprint("Ergebnis:")
    teams = sort(teams, key=lambda t: t.points, reverse=True)
    for team in teams[:3]:
        team.show_points()
    play_lights3()

def run_game(teams, duration):
    schnatz_timer = None
    gate_time = 0
    start = time.time()
    ende = start + duration
    while Ture:
        akt_zeit = time.time()
        if akt_zeit > gate_time:
            gates = [
                random.choice([None] + teams)
                for _ in range (3)
            ]
            display_gates(gates)
            gate_time = akt_time + 10

        if akt_zeit > ende:
            if schnatz_timer is None:
                schnatz_sttatus = schnatz_active(teams)
                schnatz_timer = akt_zeit + random.randint(1,10)
            elif akt_zeit < schnatz_timer: #TODO: and schnatz == FALSE:
                break
            check_ring = check_gates()
            if check_ring !=3:
                team = gates[check_ring]
                if team is not None:
                    team.points += 10
                    team.show_points()
    cprint("Spielende")
    if schnatz_status is not None:
        schnatz_status.points += 150

def initialize(buttons):
    queue = Queue()
    GPIO.setmode(GPIO.BCM)
    for button, led in buttons.items():
        GPIO.setup(led, GPIO.OUT)
        GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(button, GPIO.FALLING, queue.put)
    for gates in LASER_GATES:
        GPIO.setup(gates, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    return queue

def main():
    try:
        queue = initialize(BUTTONS)
        while True:
            teams = select_teams(queue)
            duration = select_duration() * 60
            checkstart()
            cprint("Am Spiel nehmen die folgenden mannschaften teil:")
            for team in teams:
                cprint(team.team_name, color=team.color)
            run_game(teams, duration)
            display_results(teams)
    finally:
        GPIO.cleanup()

if __name__ == "__main__":
    main()


Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Ja, und warum hast Du meine Korrektur vom 19. August nicht umgesetzt?
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

So;

habe nun nochmal den Code anpasst:

Code: Alles auswählen

from RPi import GPIO
from queue import Queue, Empty
from termcolor import cprint
import spidev
import time
import random
import sys
import os

GREEN = 4
YELLOW = 3
RED = 27
BLUE = 17
SNATCH = 2

TEAM_LIGHTS = [BLUE, RED, YELLOW, GREEN]
ALL_LIGHTS = [SNATCH] + TEAM_LIGHTS

BUTTONS = {
    14: GREEN,
    24: YELLOW,
    18: RED,
    15: BLUE,
    23: SNATCH,
}

TEAMS = {
    GREEN: ("Slytherin", "green"),
    YELLOW: ("Hufflepuff", "yellow"),
    RED: ("Gryffindor", "red"),
    BLUE: ("Ravenclaw", "blue"),
}

DURATIONS = {
    BLUE: (2, "blau", "blue"),
    RED: (5, "rot", "red"),
    YELLOW: (10, "gelb", "yellow"),
    GREEN: (15, "gruen", "green"),
}

LASER_GATES = [
    (26, 19), (13,21), (20,16)
]

class Team:
    def __init__(self, team_name, color):
        self.team_name = team_name
        self.color = color
        selt.taster = taster
        self.points = 0

    def show_points(self):
        cprint(f"{self.team_name}: {self.points}", color=self.color)

def light_off(pin):
    GPIO.setup(pin, GPIO.HIGH)

def light_on(pin):
    GPIO.setup(pin, GPIO.LOW)

def play_lights1():
    for i in range(3):
        light_on(LIGHTS)
        time.sleep(0.2)
        light_off(LIGHTS)
        time.sleep(0.2)

def play_lights2():
    for led_pin in TEAM_LIGHTS:
        light_on(led_pin)
        time.sleep(0.2)
        light_off(led_pin)
        time.sleep(0.2)
    for i in range(3):
        light_on(TEAM_LIGHTS)
        time.sleep(0.2)
        light_off(TEAM_LIGHTS)
        time.sleep(0.2)

def play_lights3():
    for pin in ALL_LIGHTS:
        light_on(pin)
        time.sleep(1)
    time.sleep(4)
    for pin in ALL_LIGHTS:
        light_off(pin)
        time.sleep(1)

def checkstart():
    rings = []
    for gate_a. gate_b in LASER_GATES:
        rings.append(GPIO.input(gate_a) + GPIO.input(gate_b))
    for nr, ring in enumerate(rings, 1):
        p = [100, 50, 0][ring]
        cprint(f"Status Ring {nr}: {p}%s")

def clear_queue(queue):
    try:
        while True:
            queue.get_nowait()
    except Empty:
        pass

def select_teams(queue):
   light_off(ALL_LIGHTS)
   cprint("Bitte waehlen Sie mit den Farben die mitspielenden Teams aus. Bestaetigen Sie ihre Auswahl mit dem Schnatz")
   selected = set()
   clear_queue(queue)
   while True:
      color = BUTTONS[queue.get()]
      if color == SNATCH:
         if selected:
            break
         # blink lights if no team is selected
         play_lights1()
      else:
         if color in selected:
            selected.remove(color)
            light_off(color)
         else:
            selected.add(color)
            light_on(color)
   light_off(ALL_LIGHTS)
   return [
      Team(color, *TEAMS[color])
      for color in selected
   ]

def select_duration():
    cprint("Bitte waehlen Sie die Dauer des Spiels aus:")
    for duration, name, color in sorted(DURATIONS.values()):
        cprint(f"{name} = {duration} Minuten", color=color)
    cprint ("Das Spiel wird mit dem Schnatz gestartet")
    selected_duration = 0
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected_duration != 0:
                break
            play_lights2()
        else:
            selected_duration = DURATIONS[color] [0]
            light_off(TEAM_LIGHTS)
            light_on(color)
    return selected_duration

def display_gates(gates):
    cprint("Tore", end=" ")
    for nr, gate in enumerate(gates, 1):
        cprint(f"Tor {nr} ", end=" ")
        if gate is None:
            cprint("DEFEKT", color="grey", end=" ")
        else:
            cprint(gate.team_name, color=gate.color, end=" ")

def schnatz_active(teams):
    selected = random.choice([None] + teams)
    if selected is None:
        licht_aus(LICHT_schnatz)
    else:
        licht_an(LICHT_schnatz)
        cprint("Der Schnatz wurde gesichtet! Er kann von folgendem Team gefangen werde:")
        cprint(selected.team_name, color=selected.color, end=" ")
    return selected

def display_results(teams):
    cprint("Das Spiel ist zu Ende! Eine herausragende Leistung von allen Teilnehmern:")
    cprint("Ergebnis:")
    teams = sort(teams, key=lambda t: t.points, reverse=True)
    for team in teams[:3]:
        team.show_points()
    play_lights3()

def run_game(teams, duration):
    schnatz_timer = None
    gate_time = 0
    start = time.time()
    ende = start + duration
    while Ture:
        akt_zeit = time.time()
        if akt_zeit > gate_time:
            gates = [
                random.choice([None] + teams)
                for _ in range (3)
            ]
            display_gates(gates)
            gate_time = akt_time + 10

        if akt_zeit > ende:
            if schnatz_timer is None:
                schnatz_sttatus = schnatz_active(teams)
                schnatz_timer = akt_zeit + random.randint(1,10)
            elif akt_zeit < schnatz_timer: #TODO: and schnatz == FALSE:
                break
            check_ring = check_gates()
            if check_ring !=3:
                team = gates[check_ring]
                if team is not None:
                    team.points += 10
                    team.show_points()
    cprint("Spielende")
    if schnatz_status is not None:
        schnatz_status.points += 150

def initialize(buttons):
    queue = Queue()
    GPIO.setmode(GPIO.BCM)
    for button, led in buttons.items():
        GPIO.setup(led, GPIO.OUT)
        GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(button, GPIO.FALLING, queue.put)
    for gates in LASER_GATES:
        GPIO.setup(gates, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    return queue

def main():
    try:
        queue = initialize(BUTTONS)
        while True:
            teams = select_teams(queue)
            duration = select_duration() * 60
            checkstart()
            cprint("Am Spiel nehmen die folgenden mannschaften teil:")
            for team in teams:
                cprint(team.team_name, color=team.color)
            run_game(teams, duration)
            display_results(teams)
    finally:
        GPIO.cleanup()

if __name__ == "__main__":
    main()
Wenn ich nun Teams auswählen möchte und mit dem Schnatz bestätige kommt folgende Meldung:
Traceback (most recent call last):
File "quidditch.py", line 233, in <module>
main()
File "quidditch.py", line 221, in main
teams = select_teams(queue)
File "quidditch.py", line 126, in select_teams
for color in selected
File "quidditch.py", line 126, in <listcomp>
for color in selected
TypeError: __init__() takes 3 positional arguments but 4 were given
Benutzeravatar
__blackjack__
User
Beiträge: 13082
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Netdeus: Die Fehlermeldung passt aber nicht zum Quelltext. Da werden 3 Argumente übergeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Etwas Eigeninitiative: was erwartet Team an Argumenten? Da war wohl noch etwas von einer frühen Version übrig geblieben.

Code: Alles auswählen

Team(*TEAMS[color])
Netdeus
User
Beiträge: 25
Registriert: Sonntag 19. Juli 2020, 12:18

Ich habe sowohl beim Quelltext als auch bei der Fehlermeldung nur kopiert und hier eingefügt.

Zum Verständnis:

Ich habe bei der Auswahl der Teams drei Teams ausgewählt und dann mit dem Schnatz bestätigt.

Deine Zeile habe ich geändert, hier also der neue Quelltext:

Code: Alles auswählen

from RPi import GPIO
from queue import Queue, Empty
from termcolor import cprint
import spidev
import time
import random
import sys
import os

GREEN = 4
YELLOW = 3
RED = 27
BLUE = 17
SNATCH = 2

TEAM_LIGHTS = [BLUE, RED, YELLOW, GREEN]
ALL_LIGHTS = [SNATCH] + TEAM_LIGHTS

BUTTONS = {
    14: GREEN,
    24: YELLOW,
    18: RED,
    15: BLUE,
    23: SNATCH,
}

TEAMS = {
    GREEN: ("Slytherin", "green"),
    YELLOW: ("Hufflepuff", "yellow"),
    RED: ("Gryffindor", "red"),
    BLUE: ("Ravenclaw", "blue"),
}

DURATIONS = {
    BLUE: (2, "blau", "blue"),
    RED: (5, "rot", "red"),
    YELLOW: (10, "gelb", "yellow"),
    GREEN: (15, "gruen", "green"),
}

LASER_GATES = [
    (26, 19), (13,21), (20,16)
]

class Team:
    def __init__(self, team_name, color):
        self.team_name = team_name
        self.color = color
        selt.taster = taster
        self.points = 0

    def show_points(self):
        cprint(f"{self.team_name}: {self.points}", color=self.color)

def light_off(pin):
    GPIO.setup(pin, GPIO.HIGH)

def light_on(pin):
    GPIO.setup(pin, GPIO.LOW)

def play_lights1():
    for i in range(3):
        light_on(LIGHTS)
        time.sleep(0.2)
        light_off(LIGHTS)
        time.sleep(0.2)

def play_lights2():
    for led_pin in TEAM_LIGHTS:
        light_on(led_pin)
        time.sleep(0.2)
        light_off(led_pin)
        time.sleep(0.2)
    for i in range(3):
        light_on(TEAM_LIGHTS)
        time.sleep(0.2)
        light_off(TEAM_LIGHTS)
        time.sleep(0.2)

def play_lights3():
    for pin in ALL_LIGHTS:
        light_on(pin)
        time.sleep(1)
    time.sleep(4)
    for pin in ALL_LIGHTS:
        light_off(pin)
        time.sleep(1)

def checkstart():
    rings = []
    for gate_a. gate_b in LASER_GATES:
        rings.append(GPIO.input(gate_a) + GPIO.input(gate_b))
    for nr, ring in enumerate(rings, 1):
        p = [100, 50, 0][ring]
        cprint(f"Status Ring {nr}: {p}%s")

def clear_queue(queue):
    try:
        while True:
            queue.get_nowait()
    except Empty:
        pass

def select_teams(queue):
   light_off(ALL_LIGHTS)
   cprint("Bitte waehlen Sie mit den Farben die mitspielenden Teams aus. Bestaetigen Sie ihre Auswahl mit dem Schnatz")
   selected = set()
   clear_queue(queue)
   while True:
      color = BUTTONS[queue.get()]
      if color == SNATCH:
         if selected:
            break
         # blink lights if no team is selected
         play_lights1()
      else:
         if color in selected:
            selected.remove(color)
            light_off(color)
         else:
            selected.add(color)
            light_on(color)
   light_off(ALL_LIGHTS)
   return [
      Team(*TEAMS[color])
      for color in selected
   ]

def select_duration():
    cprint("Bitte waehlen Sie die Dauer des Spiels aus:")
    for duration, name, color in sorted(DURATIONS.values()):
        cprint(f"{name} = {duration} Minuten", color=color)
    cprint ("Das Spiel wird mit dem Schnatz gestartet")
    selected_duration = 0
    clear_queue(queue)
    while True:
        color = BUTTONS[queue.get()]
        if color == SNATCH:
            if selected_duration != 0:
                break
            play_lights2()
        else:
            selected_duration = DURATIONS[color] [0]
            light_off(TEAM_LIGHTS)
            light_on(color)
    return selected_duration

def display_gates(gates):
    cprint("Tore", end=" ")
    for nr, gate in enumerate(gates, 1):
        cprint(f"Tor {nr} ", end=" ")
        if gate is None:
            cprint("DEFEKT", color="grey", end=" ")
        else:
            cprint(gate.team_name, color=gate.color, end=" ")

def schnatz_active(teams):
    selected = random.choice([None] + teams)
    if selected is None:
        licht_aus(LICHT_schnatz)
    else:
        licht_an(LICHT_schnatz)
        cprint("Der Schnatz wurde gesichtet! Er kann von folgendem Team gefangen werde:")
        cprint(selected.team_name, color=selected.color, end=" ")
    return selected

def display_results(teams):
    cprint("Das Spiel ist zu Ende! Eine herausragende Leistung von allen Teilnehmern:")
    cprint("Ergebnis:")
    teams = sort(teams, key=lambda t: t.points, reverse=True)
    for team in teams[:3]:
        team.show_points()
    play_lights3()

def run_game(teams, duration):
    schnatz_timer = None
    gate_time = 0
    start = time.time()
    ende = start + duration
    while Ture:
        akt_zeit = time.time()
        if akt_zeit > gate_time:
            gates = [
                random.choice([None] + teams)
                for _ in range (3)
            ]
            display_gates(gates)
            gate_time = akt_time + 10

        if akt_zeit > ende:
            if schnatz_timer is None:
                schnatz_sttatus = schnatz_active(teams)
                schnatz_timer = akt_zeit + random.randint(1,10)
            elif akt_zeit < schnatz_timer: #TODO: and schnatz == FALSE:
                break
            check_ring = check_gates()
            if check_ring !=3:
                team = gates[check_ring]
                if team is not None:
                    team.points += 10
                    team.show_points()
    cprint("Spielende")
    if schnatz_status is not None:
        schnatz_status.points += 150

def initialize(buttons):
    queue = Queue()
    GPIO.setmode(GPIO.BCM)
    for button, led in buttons.items():
        GPIO.setup(led, GPIO.OUT)
        GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(button, GPIO.FALLING, queue.put)
    for gates in LASER_GATES:
        GPIO.setup(gates, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    return queue

def main():
    try:
        queue = initialize(BUTTONS)
        while True:
            teams = select_teams(queue)
            duration = select_duration() * 60
            checkstart()
            cprint("Am Spiel nehmen die folgenden mannschaften teil:")
            for team in teams:
                cprint(team.team_name, color=team.color)
            run_game(teams, duration)
            display_results(teams)
    finally:
        GPIO.cleanup()

if __name__ == "__main__":
    main()
Erneut ein Test mit drei Teams und nach Drücken des Schnatz hier der Fehler:
Traceback (most recent call last):
File "quidditch.py", line 233, in <module>
main()
File "quidditch.py", line 221, in main
teams = select_teams(queue)
File "quidditch.py", line 126, in select_teams
for color in selected
File "quidditch.py", line 126, in <listcomp>
for color in selected
File "quidditch.py", line 49, in __init__
selt.taster = taster
NameError: name 'taster' is not defined

Oh, und wo kann ich ein time.sleep(0.2) setzen, damit ich die Taste für die Teams besser drücken kann? Habe es an mehreren Stellen versucht, doch leider ohne Erfolg.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Guck dir halt die __init__()-Signatur von der Team-Klasse an. Da kommt "taster" nicht drin vor, soll aber trotzdem an self gebunden werden. Das schlägt natürlich fehl und führt zur Fehlermeldung. Also würde ich mal sagen, dass du die betreffende __init__() anpassen musst...
Antworten