Klassen und Zähler einbauen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
LauseJunge
User
Beiträge: 6
Registriert: Dienstag 8. November 2022, 17:07

Frohe Ostern ihr Hasen.
Ich hab mal eine Frage zu folgendem Problem.
Kurz vorab, ich bin noch recht frisch und versuche das Thema Klassen zu verstehen.
Aus diesem Grund habe ich mir ein kleines Programm überlegt:
Ein Tätowierer soll für einen Termin die genutzten Nadeln auswählen und abspeichern, damit er diese Daten beim erweitern des Tattoos wieder aufrufen kann und weiß was er benutzt hat.
In welcher form das gespeichert wird? soweit bin ich noch nicht und ist auch momentan noch nicht wichtig für mich, denn es geht um Folgendes.
Ich habe eine Klasse "Nadeln" erstellt.
In dieser sind in einer Methode die Attribute mit den Werten der Nadelspezifikationen in Listen gespeichert. In Listen, weil es feste Arten, Nadelanzahlen, Spitzenformen etc. gibt die dem Nutzer später als Auswahl zu Verfügung stehen sollen.
Also welche Nadelarten gibt es = Liste mit möglichen Nadelarten
wie viele Nadeln hat das Modul = Liste mit möglicher Anzahl der Nadeln
usw.
Später wird der Nutzer dann gefragt welche Art, welche Nadelanzahl, welche Spitze etc
So weit so gut:
und hier ein Beispiel für den Aufbau der KLasse:

Code: Alles auswählen

# die Klasse für die genutzten Nadeln
class Nadeln:
    # die Methode __init__()
    def __init__(self):
        # die Attribute für die Nadelspezifikationen
        self.nadel_art = ["RL", "RS", "SEM", "M", "FLAT"]
        self.nadel_anzahl = [1, 3, 5, 7, 9, 11, 15, 17, 19, 22]
        self.nadel_spitze = ["MT", "LT", "XLT"]
        self.nadel_dicke = [0.25, 0.30, 0.35, 0.40]

Ich möchte nun einen Zähler einbauen der die Nadeln im bestand entsprechend runtersetzt.
und da hänge ich ein bisschen im Aufbau.
würde es zum Beispiel nur das Kriterium nadel_art geben würde ich auf die einfachste Art eine Liste erstellen, die so viele "einzelne Stückzahlen" hat, wie es Arten gibt.
Also:

Code: Alles auswählen

self.anzahl_vorhanden = [20, 20, 20, 20, 20] 
 # oder 
self.anzahl_vorhanden = [anzahl1, anzal2, ...] 
und diese dann im Verlauf weiter bearbeiten und nutzen.
Jetzt ist meine Frage aber, da es ja für jede Nadelart bei jeder Nadeldicke und jeder Spitzenform die anzahlen der Nadeln gibt. Wie setze ich das um?
Ich kann doch nicht für jede mögliche Nadelkonstellation eine Gebindegröße angeben. Das muss doch einfacher/angenehmer gehen. Z.B. ein Attribut self.gebinde_groesse = 20 erstellen und dieses dann in einer variablen für die entsprechende Nadelkonfiguration abzulegen.
Ich steh da gerade voll auf dem Schlauch und hoffe ihr versteht meine Idee.
Würd mich freuen wenn ihr helfen könnt.
Mir geht es auch gerade nicht um die "Runterrechnung" bei be Benutzung (soll aber später natürlich gemacht werden), sondern wirklich nur darum wie ich, mit einfachsten Mitteln, jeder möglichen Nadelkonfiguration den Wert der Packungsgröße (am Anfang 20) übergebe ohne mich kaputt zuschreiben.
Da ich, wie gesagt gerade Klassen als Lernthema habe, wäre es mega wenn ihr mir keine Bibliotheken um die Ohren haut. Ich möchte es halt kapieren und da sind Bibliotheken nur bedingt hilfreich.
Dankeeehh!
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Modellierung ist schlecht. Stattdessen solltest du eine Klasse Nadel haben, die deine Attribute - Spitze, Dicke, Art - enthaelt. Eigentlich reicht dazu ein Tupel, aber es sollen ja Klassen sein. Dann kannst du eine Klasse Vorrat schreiben, in der du ein Woerterbuch von Nadel auf Anzahl dieses Modells vorhaelst. Und darauf kann man dann arbeiten.

Code: Alles auswählen

from collections import namedtuple, defaultdict

# Selbst schreiben! Inklusive der notwendigen Vergleichsmethoden
Nadel = namedtuple(field_names="art dicke spitze", typename="Nadel")

class NadelVorrat:

    def __init__(self):
        self._vorrat = defaultdict(int)

    def kaufe(self, typ, anzahl):
        self._vorrat[typ] += anzahl

    # Weiter Methoden zum entnehmen etc.

    #...

    def __repr__(self):
        return f"{self.__class__.__name__} {dict(self._vorrat)}"


def main():
    vorrat = NadelVorrat()
    dicke_nadel = Nadel("RL", 1000, "MT")
    vorrat.kaufe(dicke_nadel, 10)
    print(vorrat)


# main guard
if __name__ == '__main__':
    main()
LauseJunge
User
Beiträge: 6
Registriert: Dienstag 8. November 2022, 17:07

@__deets__
Guten Morgen:
Ich werde mal versuchen deinen Rat umzusetzen.
Die Idee kam weil wir gerade Klassen bearbeiten und darüber als Beispiel einen
"Getränkeautomaten" programmieren.
Um das Thema besser zu verstehen und ein wenig zu üben,

Sicher nicht die optimalste Form für das Ziel des Programms, aber es geht ja für mich um
die Möglichkeit ein bisschen mit Klassen "herumzuspielen" und den Umgang mit Ihnen zu verinnerlichen.
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@LauseJunge: Für Aufzählungstypen gibt es etwas in der Standardbibliothek: `enum`. Und wenn man wirklich alle Varianten von Nadeln erzeugen will, ohne die alle ausschreiben zu müssen, ist das `itertools`-Modul hilfreich:

Code: Alles auswählen

#!/usr/bin/env python3
from collections import defaultdict, namedtuple
from enum import Enum, auto
from itertools import product


Needle = namedtuple("Needle", "type thickness tip")


class NeedleType(Enum):
    RL = auto()
    RS = auto()
    SEM = auto()
    M = auto()
    FLAT = auto()


class TipType(Enum):
    MT = auto()
    LT = auto()
    XLT = auto()


class Needles:
    def __init__(self, needle_to_count=None):
        self._needle_to_count = defaultdict(int)
        if needle_to_count:
            self._needle_to_count.update(needle_to_count)

    def __repr__(self):
        return f"{self.__class__.__name__}({dict(self._needle_to_count)!r})"

    def add(self, needle, count):
        self._needle_to_count[needle] += count


def main():
    needles = Needles()
    for type_, thickness, tip in product(
        NeedleType, [0.25, 0.30, 0.35, 0.40], TipType
    ):
        needles.add(Needle(type_, thickness, tip), 20)
    print(needles)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
LauseJunge
User
Beiträge: 6
Registriert: Dienstag 8. November 2022, 17:07

Super.
Danke an euch.
Mir ist beim probieren noch eine neue Idee gekommen.
Nehmen wir mal an, das ganze wird ein Organizer mit allem Schnickschnack..
Da ist es ja eig. quatsch alle möglichen Nadelkonfigurationen auf eine feste Anzahl zu setzen.
Da müsste der Tätowierer ja eig. bei der ersten Nutzung seinen Bestand aufnehmen (Nicht jeder Tätowierer hat alle Module. Jeder hat Vorlieben).
Diese müssten ja dann im Vorfeld entsprechend gespeichert, beim Termin XY zur Auswahl zur Verfügung gestellt und dementsprechend heruntergesetzt werden.

Wenn ich dann also beim öffnen abfrage, ob sich "Inventarmäßig" was verändert hat und wenn ja was und wieviel etc, ansonsten False, das sollte doch am Ende realistischer sein oder?
Und wie gesagt, das ist für mich ein "ich möchte Klassen verstehen lernen Projekt" .
LauseJunge
User
Beiträge: 6
Registriert: Dienstag 8. November 2022, 17:07

Ps: Die Idee mit den Tupeln für die festen konfigurationsarten macht bei meinem Kenntnisstand absolut Sinn! Danke!!
Ich weiß, für viele alles voll selbstverständlich, aber ich bin noch recht frisch in der Materie.
Da ist das oft nicht ganz so einfach alles zu bedenken und zum richtigen Punkt einzusetzen. :D
Benutzeravatar
Dennis89
User
Beiträge: 1555
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

an sich ist es ja "nur" eine Datenbank (welcher Form sei erst mal dahin gestellt). Bevor das fröhliche Stechen losgeht, öffnet der Tätowierer das Programm, im Hintergrund wir die Datenbank abgefragt und schließlich wird der Bestand angezeigt. Dann wird ausgewählt welche Nadel genutzt wird und eventuell bestätigt und dadurch wird der Bestand um eine Nadel herunter gesetzt. Beim nächsten Abfragen des Bestands steht da eine Nadel weniger drin.
Wenn du willst, dass noch angezeigt wird, wann sich was "Inventarmäßig" geändert hat, dann musst du die Information auch noch speichern. Das mit dem 'False' verstehe ich nicht, was du damit meinst.

Also kurz gesagt, ja so ein Programm zu schreiben ist realistisch und einmal muss der Bestand aufgenommen werden. Einmal im Jahr macht man eine Inventur und vergleicht den Bestand im Programm mit dem "echten" Bestand.
Als Datenbank kannst du so etwas wie MySQL verwenden, eine *.csv-Datei oder eine *.xlsx-Datei. Vielleicht würde die Excel Sinn machen, dann kannst du dich weiterhin auf Python konzentrieren und du kannst die Datenbank zum testen schnell und "wie gewohnt" befüllen.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten