Passt Python auf die Aufgabe? Eintrittskarten!

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
taurui
User
Beiträge: 3
Registriert: Dienstag 19. Februar 2019, 15:48

Hi Leute,
Beruflich bedingt hab ich ein bisschen Python gelernt und frage mich gerade, ob ich damit folgende Aufgabe gut bearbeiten könnte:
Ich bin in einem Theaterverein und wir haben für jede Veranstaltung immer einen großen Aufwand damit, Karten zu drucken.
Was wir bräuchten, ist eine Funktion, die eine aufsteigende Ticketnummer (am besten mit dazugehörigem Barcode) auf ein bereits fertiges Bild klatschen könnte und dann platzoptimiert druckt.
Am besten dann auch mit weiterem, konfigurierbarem Text (z.B. Datum, Stücktitel, Uhrzeit..).
Da Python auch mit Bild-, html- und pdf-Funktionen daherkommt, habe ich mir gedacht, vielleicht könnte ich das hier nutzen.

Lohnt es sich, das mit Python weiter zu verfolgen, oder bieten sich da andere Sprachen/Tools eher an?

Danke :)
-taurui
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@taurui: So grundsätzlich würde ich sagen das lässt sich mit Python machen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ _blackjack_ :
du schaffst das auch mit dem C64, oder ?

@ taurui :
was du auf jeden Fall mit Python machen kannst, ist die Vorbelegung der Sitzplätze im Theater zu managen, Reihe und Sitz auf die Karte zu drucken, Name der Vorstellung, Uhrzeit, Datum, und und und .... also alles, was ein Theater-Manager (oder wie man das nennen mag) macht. Auch ein Saalplan, also die Verteiluing der Sitze und Reihen im Saal, mit bereits besetzten/verkauften/vorbestellten Sitzen zuzüglich beispielsweise der Initialen des Besuchers/Käufers ...
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

PDF könnte auf dem C64 schwer werden. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ _blackjack_ :
:lol:
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für die automatisierte Bildbearbeitung empfehle ich die PIL (mittels pillow). Hier ein Beispiel zum Erzeugen von Texten.

Bedenke dabei, dass es anfangs sicherlich viel Gefrickel ist bis du brauchbare Ergebnisse erhälst. Eine Vorlage in GIMP oder Photoshop dürfte deutlich einfacher zu erstellen sein. Die Änderungen für einzelne Karten lassen sich dann über ein passendes Makro einpflegen. In GIMP nennt sich diese Technik Skript-Fu.

Und ganz allgemein gesagt geht natürlich so ziemlich alles auch in Python. Die Frage ist nur ob das immer so zielführend ist...
Benutzeravatar
__blackjack__
User
Beiträge: 13102
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei ich hier eher zu zu Scribus oder Inkscape tendieren würde um zumindest den Text als Vektorgrafik auf die Eintrittskarte(n) zu bekommen. Beides lässt sich auch in Python scripten. Oder in reinem Python dann Reportlab statt oder zusätzlich zu PIL/Pillow.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

Wie druckt ihr die Tickets denn zur Zeit? Verwendet ihr einen speziellen Ticketdrucker?
Ich kenne mich da nicht so aus, aber bei professionellen Ticketdruckern scheint es mir so zu sein, dass das über proprietäre Software bzw. Programmiersprachen abgehandelt wird.

Prinzipiell ist es sonst halt so, dass man neben Python für die meisten Lösungsansätze noch weitere Software braucht, dir das eigentliche Layout übernimmt und im besten Fall eine Postscript oder PDF ausspuckt. Das können neben den genannten Lösungen diverse weitere sein, z.B. tex (am besten ConTeXt) oder auch was XML-basiertes.
taurui
User
Beiträge: 3
Registriert: Dienstag 19. Februar 2019, 15:48

Wow, danke für die ganzen Informationen und Anregungen, das muss ich erstmal verarbeiten :-)
@nezzcarth: Wir sind hier sehr hemdsärmelig unterwegs und drucken mit einem stinknormalen Drucker. Vielleicht ändert sich das ja irgendwann, aber nicht in nächster Zeit ;-)
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich würde da auch stark zu ReportLab tendieren, um druckfähige PDFs zu erzeugen.

ReportLab kann da von high-level Layout via Platypus bis low-level Operationen auf dem Canvas alles. ReportLab kann auch Barcodes, ist nur ein bisschen versteckt.

Gruß, noisefloor
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

Aus einem Buch (Python3 von Michael Weigend) hab ich ein Ticketsystem was sich relativ einfach adaptieren lässt. So hast du schonmal ein Grundbau und

Das Theater Stück

Code: Alles auswählen

#----------------------------------------------------
# Dateiname: musical.py
# Modul mit Klassen zur Modellierung eines Musicals
#
# Objektorientierte Programmierung mit Python
# Kap. 12 
# Michael Weigend 2.10.09
#----------------------------------------------------


# musical.py  - Modell eines Musicals
import pickle

class Musical: 
    def __init__(self, titel, eintrittspreis, saal):
       self.titel = titel
       self.eintrittspreis = eintrittspreis
       self.saal = saal
       self.vorstellungen = [] # Liste von Vorstellungen

    def getVorstellung(self, datum):
        """Rückgabe eines Vorstellungs-Objektes mit
        passendem Datum, falls vorhanden, sonst None"""        
        for vorstellung in self.vorstellungen:
          if vorstellung.datum == datum: return vorstellung
        # Nach dem return bricht die Ausführung der Funktion ab

    def neueVorstellung(self, vorstellung):
        """Objekt vorstellung wird in Liste eingefügt"""
        self.vorstellungen += [vorstellung]

    def __str__(self):                               #1
        beschreibung = '\n' + self.titel + '\n' + \
                       len(self.titel)*'=' + '\n'
        for vorstellung in self.vorstellungen:
            beschreibung += str(vorstellung) + '\n'
        return beschreibung 

class Vorstellung:
    def __init__(self, datum, beginn, saal ):
        self.datum = datum
        self.beginn = beginn
        self.saalbelegung = Saalbelegung(saal)
        self.saal = saal

    def __str__(self):                               #1
        beschreibung = self.datum + '\n' + \
        str(self.saalbelegung.getFreiePlaetze()) + \
        ' freie Plätze\n' 
        return beschreibung

class Saalbelegung:
    """pflegt Liste von Listen mit Platz-Objekten"""
    def __init__(self, saal):
        self.belegung = []
        self.saal = saal
        for i in range(len(saal.plaetzeProReihe)):   #2
            reihe = []
            for j in range(saal.plaetzeProReihe[i]):
                platz = Platz()
                reihe += [platz]
            self.belegung += [reihe]

    def buche(self, reihe, platz, zuschauer):        #3
        '''weist dem Platz platz in Reihe reihe einen
        Zuschauer zu'''
        if not self.belegung[reihe][platz].belegt():
           self.belegung[reihe][platz].belege(zuschauer)
           return 'Platz gebucht'
        else: return 'Platz schon belegt'

    def getFreiePlaetze(self):
        """liefert Anzahl der freien Plaetze"""
        frei=0
        for reihe in self.belegung:
            for platz in reihe:
                if not platz.belegt(): frei += 1
        return frei

    def __str__(self):                               #1
        beschreibung = 'Saalbelegung\n'
        beschreibung += '   Platz: 1  2  3  4  5  6  7  8  9  10 '
        beschreibung += '11 12 13 14\n'
        nr = 1                           # Reihennummer
        for reihe in self.belegung:
            beschreibung += 'Reihe ' + format(nr, '2d') + ': '
            for platz in reihe:
                beschreibung += str(platz)
            nr += 1
            beschreibung += '\n'         # neue Zeile
        return beschreibung

class Zuschauer:
    def __init__(self, name, tel):
        self.name, self.tel = name, tel

class Platz:
    def __init__(self):
        self.zuschauer = None

    def belegt(self):
        if self.zuschauer: return True
        else: return False

    def belege(self, zuschauer):
        self.zuschauer = zuschauer

    def __str__(self):                              #1
        if self.belegt():
            return self.zuschauer.name[:2] + ' '   
            # vom Zuschauername nur die ersten beiden Zeichen   
        else:
            return '-- '       # freier Platz

class Saal:
    def __init__(self, liste):
        self.plaetzeProReihe = liste  
Und das Ticketsystem dazu

Code: Alles auswählen

#----------------------------------------------------
# Dateiname: musicaltickets.py
# Verwaltung eines Musicals - Kartenverkauf
#
# Objektorientierte Programmierung mit Python
# Kap. 12 
# Michael Weigend 2.10.09
#----------------------------------------------------

import pickle
from musical import *

class Kartenverkauf:
    __menuetext = '''
    Musical-Ticketservice
    ---------------------
    (B)uchung
    (U)eberblick Vorstellungen
    (E)nde
    '''

    def __init__(self, datei):
        self.__datei = datei
        self.__lade_musical()
        self.__run()

    def __lade_musical(self): 
        ''' versucht, aus Datei Musical zu laden'''
        try:
            f = open(self.__datei, 'rb')
            self.__musical = pickle.load(f)
            f.close()
            print('\n              W I L L K O M M E N')
            print('beim Buchungssystem für das Musical', 
                  self.__musical.titel)
        except:
            print('Kein Musical gespeichert. ')

    def __run(self):
        ''' Menü und Verarbeitung von Auswahlen'''
        print(self.__menuetext)
        wahl = '-'
        while wahl not in 'eE':
            wahl = input('Auswahl: ')
            if wahl in 'bB': self.__buchen()
            elif wahl in 'uU': print(self.__musical)
            print(self.__menuetext)
        print('Danke für die Benutzung von Musical-Ticketservice')
        self.__speichern()

    def __buchen(self):                               #1
        '''Dialog zum Buchen mehrerer Plätze '''
        datum = input('Datum der Vorstellung: ')
        vorstellung = self.__musical.getVorstellung(datum)
        if not vorstellung:                           #2
            print('An diesem Tag gibt es keine Vorstellung')
        else:
          print(vorstellung.saalbelegung)
          name = input('Name: ')
          tel = input('Telefonnummer: ')
          zuschauer = Zuschauer(name, tel)
          reihe = 'x'                                 #3 
          while reihe != '':
            reihe = input('Reihe: ')
            if reihe != '':                           #4
                platz = input('Platz: ')
                print(vorstellung.saalbelegung.buche(
                  int(reihe)-1, int(platz) - 1, zuschauer))

    def __speichern(self):
        f = open(self.__datei, 'wb')
        pickle.dump(self.__musical, f)
        f.close()

kasse1 = Kartenverkauf('daten/hairspray.txt')

bei zweiten kann ich mir gut vorstellen, dass du die hier vorgeschlagenen Drucksysteme integrieren kannst.
Ich wollte dir diesen Code nur zeigen, da ich denke, das er für dich vielleicht zum Teil verwartbar ist.

BTW: Ich kann das Buch auch sehr empfehlen. Gibt jetzt sogar die Auflage 7. Ich hab aber nur die Auflage 6. Hänge gerade selbst wieder darüber. Aber nach der Arbeit ist das Hobbycoden manchmal sehr träge...
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Tholo: `pickle` ist nicht dafür gedacht, Daten für länger zu speichern. Vor allem, wenn man eine der Klassen weiterentwickelt, kann es passieren, das vorher gespeicherte Daten nicht mehr lesbar sind.

Die Namensschreibweise der Methoden hält sich nicht an die Konvention. `getVorstellung` hat nicht in jedem Zweig ein `return`. Sieht also so aus, als ob es fehlerhaft ist.
Um Elemente an eine Liste anzuhängen, gibt es, append. Extra eine Einelementige Liste zu erzeugen ist unsinnig. Und in __str__ wird ein String mit + zusammengestückelt, statt .format zu benutzen.
Saalbelegung.__init__ benutzt das absolute Antipattern for i in range(len(...)) statt direkt über die Elemente der Liste zu iterieren. Saalbelegung.__str__: sollte man wirklich mal einen Index benötigen, gibt es `enumerate`. Warum ist Platz 1 bis 14 hier hardcodiert? Oh, hier wird format verwendet, daber total umständlich.

Übrigens eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2, mal 3, mal 4. Nach einem : der einen Block einleitet, wird immer eine neue Zeile angefangen.

Platz.belegt: das geht auch einfacher mit `return self.zuschauer is not None`.
In `Kartenverkauf` sind dann die ganzen doppelten _ ein Designfehler. menuetext ist eine Konstante und sollte auch so geschrieben werden: MENUETEXT. Dateien öffnet man mit dem with-Statement. Keine nackten Excepts, das verdeckt wirklich jeden Fehler und macht das Debugging unmöglich.
__init__ sollte eine Instanz initialisieren und nicht ewig laufen. `run` hat darin nichts verloren.
In `buchen` sollte man eine while-True-Schleife benutzen, um den Dummywert von reihe zu sparen.
Fehleingaben sollten behandelt werden.

Insgesamt enthält also der Code viele Anfängerfehler, die man in einem Lehrbuch vermeiden sollte und erst die Konzepte dahinter behandeln, bevor man mit so einem komplexen Beispiel starten kann.
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

@Sirius3
Ich weiß das! Ich hab das Script 1:1 kopiert. Mit der Vermutung, dass das einer von euch anprangert ;)
Ich hatte den Code schon kopiert und wollte ihn anpassen...Aber die Faulheit hat Obsiegt. Immerhin kommt das aus einem Python Fachbuch und nicht meiner Feder :P
Ich wollte taurui aber nur die Möglichkeit aufzeigen, da das Script ja zumindest in die Richtung geht.

Ich kann mir nur vorstellen, dass verschiedene Sachen durch die Didaktik geschuldet sind. Und der Author nicht iterieren oder enumerate nutzen wollte, da diese noch nicht behandelt würden.Oder mehrere Möglichkeiten der String Modulation zeigen will.

Trotzdem muss ich sagen, bin ich mit dem Inhalt des Buchs zufrieden.
Bei meinen Aufgaben und Test wende ich zb. F-Strings, import ohne * uvm. an. Da mir das bereits aufgefallen ist. Wie gesagt, meine Faulheit hat dazu beigetragen
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ Tholo:
hier fremde, unveränderte Skripte posten? Hast du seine Zustimmung? Urheberrecht?

ich habe die 7.Auflage als PDF ...
der Autor arbeitet sehr schlampig, und die Lektoren scheinen auch zu schlafen ... habe auch die 5.Auflage und finde die gleichen und noch mehr Fehler in der 7. ...
er wird bald mal eine Email von mir bekommen ... :P
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Sich an Konventionen zu halten, kostet nichts. `format` wird ja benutzt, aber nicht konsequent und dann auch noch ungünstig. Und wenn man noch keine for-Schleife kann, dann kann man erst recht noch nicht Klassen lernen.
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

Perlchamp hat geschrieben: Donnerstag 21. Februar 2019, 21:33 @ Tholo:
hier fremde, unveränderte Skripte posten? Hast du seine Zustimmung? Urheberrecht?
Genau das würde ja eher gegen eine Veränderung durch mich sprechen. Ich hab den Shebang mit Absicht drin gelassen und auch im Text direkt auf das Buch verwiesen. In der Hinsicht fühl ich mich eher unbelastet
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ Tholo :
moinsen,
ich will dir ja nichts Böses, oder dergleichen. Ich kenne mich auch nicht sehr gut im Urheberrecht aus. Eines weiß ich aber:
wenn du Veränderungen vornimmst, dann entspricht es NICHT MEHR dem Original, womit das Urheberrecht nicht mehr greift. Wie marginal oder bedeutend diese Veränderungen sein müssen, ist wohl Definitions- oder Ansichtssache ...

Hier mal ein Auszug aus dem Buch :
Dieses Werk, einschließlich aller seiner Teile, sind urheberrechtlich geschützt. Jede Verwendung außerhalb der *engen* Grenzen des Urheberrechsgesetzes ist ohne Zustimmung des Verlages unzulässig und strafbar. Dies gilt insbesondere für *Vervielfältigungen*, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen.
Unterm Strich verstehe ich es so:
eine *maßgebliche* [im Sinne der *engen* Grenzen des Urheberrechtsgesetzes - da reicht möglicherweise bereits das Austauschen eines einzigen Befehls] Veränderung zu veröffentlichen ist straffrei oder -mildernd, dagegen das Original zu veröffentlichen, nicht.
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

@tholo: rein rechtlich macht das keinen Unterschied denke ich, ob du den Code unverändert veröffentlichst oder nicht. Er bleibt erkennbar. Wenn ich Artikel des Spiegel unverändert selbst veröffentliche, bekomme ich trotzdem Ärger mit dem dazugehörigen Verlag. Und wenn ich nur kosmetisch dran rum Schraube auch.

Ich denke auf der anderen Seite nicht, das es hier wirklich zu Konsequenzen käme. Diese Forum hat keine Werbung, womit auch keine gewinnabsicht die Situation verschärft. Und die Diskussion der Inhalte des Buchs zwecks besserem Verständnis sind auch sicherlich gewollt. Das der Verlag sich da dann aufrafft & eine Klage oder Abmahnung anstößt ist denke ich eher unwahrscheinlich.
taurui
User
Beiträge: 3
Registriert: Dienstag 19. Februar 2019, 15:48

Konventionen hin oder her, das ist eine super Inspiration! :) Vielen Dank dafür!
Antworten