Script für Sitzplatzreservierung (Listen & Schleifen)

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
delobre
User
Beiträge: 2
Registriert: Montag 28. Mai 2018, 14:59

Hallo!
Ich habe eine Aufgabe bekommen, ein Scrip für die Sitzplatzbuchung in einem Kino zu schreiben. Ich bin jetzt schon seit Stunden dran und hab schon stackoverflow durchforstet, aber derzeit weiß ich einfach nicht weiter.
Ich verlang hier natürlich keinesfalls komplette Lösung, sondern freue mich über jeden Denkansatz und Verbesserungen :)

Folgende Aufgabe:
Aufgabe 1: Programmieren Sie den Kinosaal und erzeugen Sie mittels einer Schleife ein leeres Kino (alle Sitze
sind auf O gesetzt)
Aufgabe 2: Programmieren Sie eine Prozedur die den gesamten Kinosaal in der Konsole ausgibt. Dabei soll hier
Zeilenweise und ohne Klammern ausgegeben werden.
Aufgabe 3: Programmieren Sie eine Funktion, die einen leeren Kinosaal übernimmt und für jeden Platz zufällig
entscheidet, ob dieser bereits belegt ist oder nicht. Als Rückgabewert geben Sie den geänderten Kinosaal
zurück.
Aufgabe 4: Für Reservierungen ist es wichtig zu erfassen, welche Sitze frei sind und welche nicht.
Programmieren Sie eine Funktion die den ersten freien Sitzplatz aus einem übergebenen Kinosaal ermittelt und
dessen Nummer zurückgibt. Also 101, 304, 730 usw.
Aufgabe 5: Wenn mehrere Personen zusammen ins Kino gehen, wollen diese nebeneinander Sitzen. Deswegen
müssen Sie eine Funktion programmieren, die neben einem Kinosaal auch die Anzahl benötigter Sitze
übergeben bekommt. Die Funktion soll dann den Kinosaal nach der ersten freien Kette von Sitzen mit der
richtigen Länge ermitteln und ausgeben. Wenn im Saal nicht genug Plätze frei sind, soll dies als Fehlermeldung
ausgegeben werden.

Am Ende muss die Ausgabe so aussehen:

Code: Alles auswählen

 
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
1 O X X O X O X X O X O O X O X X O O X X X X X X X O X X X X
2 X O O O O X O O X O O O O O O O O X X O O X X O O O X O X O
3 O X X O X O O X X O O O O X O O O O X O O O X X X O X X X O
4 O X O O O X O X O O X X X O X O X X X X O X X X O O X O X O
5 O O O X O O O X O X X O O O X X O O O X X O O X O X X O O O
6 X X O X X X X X O X O X X O O X O X X X O X O X O X X X O O
7 X X O O X O O O X X O O X O X O X X X X O X O O X X X X X X
Der erste freie Platz ist:
101
Geben Sie bitte eine Anzahl an Personen an: 4
Der erste freie Platz ist:
202
Process finished with exit code 0

Aufgabe 1-3 habe ich im Prinzip fertig (hier und da fehlen noch nebensächliche Dinge). Ich weiß jetzt leider überhaupt nicht, wie ich Aufgabe 4 und 5 lösen soll. Wie genau kann ich den Listen (in denen "X" und "O" enthalten ist) die Sitzplatznummer zuweisen oder errechnen lassen?

Mein Code sieht wie folgt aus:

Code: Alles auswählen


import random


print("1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30")
#7 Reihen mit jeweils 30 Sitzen erstellen. X und O zufällig gewählt
reihe = []
sitze = []
xo = ["X  ", "O  "]
for i in range(7):
  reihe = []
  for i in range (30):
    reihe.append(random.choice(xo))
  sitze.append(reihe) #Alles in die Liste "Sitze" einfügen, am Ende also 210 Werte
  print ( "".join(map(str, reihe)))


Es ist nicht viel, was ich bisher habe, aber wie gesagt, ich will die Aufgabe selber lösen und brauche eigentlich nur Denkansätze. Ich freue mich über jede Antwort
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Kleiner Realitätscheck: 4/5 der Aufgaben erfordern eine Funktion. Dein Code hat keine einzige Funktion. Du kannst also bestenfalls nur 1/5 Aufgaben gelöst haben, konkret die erste Aufgabe. Die erste Aufgabe verlangt dass du einen leeren Kinosaal erstellst, dein Code tut dies nicht. Tatsächlich wird zu keinem Zeitpunkt während der Laufzeit deines Codes, etwas existieren was eine leeren Kinosaal repräsentieren könnte. Du hast also bis jetzt keine einzige Aufgabe richtig gelöst.

Wenn man das Bedingungen der Funktion mal ignoriert, bist du natürlich schon etwas weiter. Ich würde also also erstmal den Code umstrukturieren, so dass er der Aufgabenstellung entspricht aus mehreren Funktionen besteht.

Ansonsten schau dir mal Slicing für 4 an.
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Halb-OT: Kann man bei Aufgabe 3 von einer Funktion sprechen? Immerhin wird hier das übergebene Objekt manipuliert, wenngleich es dann (unnötigerweise) zurückgeben wird.

Der Aufgabensteller unterscheidet hier offensichtlich zwischen Prozeduren <-- kein Rückgabewert und Funktionen <-- Rückgabewert.

Meiner (engen) Auffassung nach dürfen Funktionen die übergebenen Objekte nicht verändern.

Sind diese Begriffe definiert oder definiert der jeweilige Kontext (Programmiersprache, Projekt, Dozent, ...) diese?
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
delobre
User
Beiträge: 2
Registriert: Montag 28. Mai 2018, 14:59

DasIch hat geschrieben: Montag 28. Mai 2018, 15:29 Kleiner Realitätscheck: 4/5 der Aufgaben erfordern eine Funktion. Dein Code hat keine einzige Funktion. Du kannst also bestenfalls nur 1/5 Aufgaben gelöst haben, konkret die erste Aufgabe. Die erste Aufgabe verlangt dass du einen leeren Kinosaal erstellst, dein Code tut dies nicht. Tatsächlich wird zu keinem Zeitpunkt während der Laufzeit deines Codes, etwas existieren was eine leeren Kinosaal repräsentieren könnte. Du hast also bis jetzt keine einzige Aufgabe richtig gelöst.

Danke euch beiden für die Antwort. Ich hab mich mal etwas rangesetzt bis spät abends bin anscheinend auch (fast) fertig geworden: (hab übrigens alles auf englisch umgeschrieben, macht man doch so beim programmieren? :D )

Code: Alles auswählen

import random

number_of_seats = 30
number_of_rows = 7
kinosaal = []

def createKinosaal(seats): #Erstellt leeren Saal
    print("  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30")
    xo = [" X ", " O "] # X und O in Array legen
    for i in range(number_of_rows): #7 Durchläufe
        row = [] # Nach jeder Reihe Array leeren, sonst addiert sich die Liste
        row.append(i + 1) #Reihennummer anzeigen
        for i in range(number_of_seats): #30 Durchgänge
            row.append(" O ")
        #seats.append(row)  # Alles in die Liste "Sitze" einfügen, am Ende also 210 Werte
        print("".join(map(str, row)))
    return seats

def createKinosaalRandom(seats): #Füllt leeren Saal mit " O " oder " X "
    print("  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30")
    xo = [" X ", " O "] # X und O in Array legen
    for i in range(number_of_rows): #7 Durchläufe
        row = [] # Nach jeder Reihe Array leeren, sonst addiert sich die Liste
        row.append(i + 1) #Reihennummer anzeigen
        for i in range(number_of_seats): #30 Durchgänge
            row.append(random.choice(xo))
       # seats.append(row)  # Alles in die Liste "Sitze" einfügen, am Ende also 210 Werte
        print("".join(map(str, row)))
    return seats

def searchFirstSeat(seats): #Suche ersten freien Sitz
    seatPos = 0
    rowPos = 0
    found = False

    for row in range (number_of_rows):
        for seat in range (number_of_seats + 1):
            if not found and seats[row][seat] == " O ":
                found = True #Beende Schleife
                seatPos = seat  #Position der Sitze
                rowPos = row    #Position der Sitze
    return rowPos * 100 + seatPos + 100

createKinosaalRandom(kinosaal)

def searchFirstSeatNumber(seats,desired_seats): #Sucht 5 Sitze nebeneinander
    seatPos = 0
    rowPos = 0
    found = False
    counter = 0

    for row in range (number_of_rows):
        for seat in range (number_of_seats + 1):
            if not found and seats[row][seat] == " O ":
                if counter == 0:
                    seatPos = seat
                    rowPos = row
                counter += 1
                if counter == desired_seats:
                    found = True
            else: counter = 0

    if not found: return "Keine freien Plätze nebeneinander gefunden"
    return rowPos * 100 + seatPos + 100

print("\nErster freier Platz: " + str(searchFirstSeat(kinosaal)))
print("\nErster freier Platz: " + str(searchFirstSeatNumber(kinosaal,5))) # 5 Plätze nebeneindander frei

Wie siehts jetzt aus? Die Ausgabe scheint zumindest schon richtig zu sein.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Bei `createKinosaal` und `createKinosaalRandom` erwarte ich laut Aufgabenstellung keine Ausgabe, dafür sollte es eine extra Funktion geben. Zur Namenskonvention: Konstanten werden groß geschrieben: NUMBER_OF_SEATS. Funktionen werden klein_mit_unterstrich geschrieben: create_kinosaal. Ebenso Variablen: seat_pos.

Wenn Du schon auf Modulebene ausführbaren Code hast, dann sammle den am Ende und nicht in der Mitte (Zeile 5 & 44).
Bei create_kinosaal erwarte ich, dass gar kein Argument benutzt wird, und bei create_kinosaal_random, dass number_of_rows und number_of_seats nicht gebraucht werden.

`create_kinosaal` erzeugt gar keinen Kinosaal. `seats` ist am Schluß genauso leer wie am Anfang. Ebenso bei create_kinosaal_random, was laut Aufgabenstellung eher fill_kinosaal_random heißen sollte.

In `search_first_seat` iterierst Du über einen Index statt über die übergebenen Listen (seats). Das ist umständlich und fehleranfällig. Willst Du zusätzlich den Index wissen, so gibt es `enumerate`. Du scheinst in der ersten Position jeder Reihe tatsächlich die Reihennummer zu speichern. Die hat aber in den Daten nichts verloren. Laut Aufgabe sollten leere Sitze den Wert "O" und volle "X" enthalten, nicht " O " und " X " (obwohl insgesamt ein Wahrheitswert besser wäre, aber so ist die Aufgabenstellung nunmal.) Wenn Du einen leeren Platz gefunden hast, kannst Du die Schleifen und die Funktion per "return" verlassen, dann sparst Du Dir `found`, `seat_pos` und `row_pos`.

`searchFirstSeatNumber` findet auch zusammenhängende Sitze, die am einen Ende einer Reihe rausgehen und am anderen wieder rein.

Statt Strings mit + und str zusammenzustückeln, benutze .format.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Quellcode wird üblicherweise auf englisch abgefasst, da auch die Keywords englisch sind und sich der Code so flüssiger liest. Ich habe Dir hier eine Alternative beigefügt, die auf Strings basiert. Sobald Du Sitze mit Preisen versiehst, nicht in jede Reihe die gleiche Zahl von Sitzen hat oder anderes mehr, dann genügt dieses einfache Modell natürlich nicht mehr.

Code: Alles auswählen

import random

def get_cinema_hall(rows, seats_per_row):
    return ["0"*seats_per_row for row in range(rows)]

def populate_hall(hall):
    seats_per_row = len(hall[0])
    populated_hall = []
    for row in hall:
        populated_hall.append(''.join([random.choice("X0") for _ in range(seats_per_row)]))
    return populated_hall

def get_first_unoccupied_seat(hall, seats=1):
    for row_num, row in enumerate(hall):
        seat = row.find("0"*seats)
        if seat >= 0:
            return f"{row_num+1}{seat+1:02}"
    return None

def print_hall(hall):
    for row in hall:
        print(row)
        
hall = get_cinema_hall(7, 30)
print_hall(hall)
populated_hall = populate_hall(hall)
print_hall(populated_hall)
print(get_first_unoccupied_seat(populated_hall))
print(get_first_unoccupied_seat(populated_hall, seats=4))
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: ich glaube nicht, dass die Hausaufgaben schon abgegeben worden sind. Da Strings unveränderlich sind, läßt sich noch einiges einfacher schreiben:

Code: Alles auswählen

def get_cinema_hall(rows, seats_per_row):
    return ["0"*seats_per_row] * rows

def populate_hall(hall):
    return [
        ''.join(random.choice("X0") for _ in row)
        for row in hall
    ]

def get_first_unoccupied_seat(hall, seats=1):
    for row_num, row in enumerate(hall, 1):
        seat = row.find("0"*seats) + 1
        if seat > 0:
            return f"{row_num}{seat:02d}"
    raise ValueError("not found")
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sirius3: Die Aufgabe war auch noch nicht komplett gelöst, jedenfalls, was die Darstellung der Ausgabe betrifft. Weiter wäre es geradezu töricht, eine abgeschriebene Lösung abzugeben, falls man Gefahr läuft, diese später präsentieren und erläutern zu müssen.

Auf die Schachtelung eines Generator-Ausdrucks mit einer List-Komprehension habe ich hier verzichtet, da dies nicht immer der Lesbarkeit zuträglich ist. Wer den Ansatz gerne noch weiter optimieren möchte – nur zu.

Meine Lösung zeigt, wie man mit Strings umgehen kann und wie Funktionen ohne Seiteneffekte verwendet werden. Aus der Grundidee der Aufgabe, ein einfaches System zur Sitzplatzreservierung umzusetzen, könnte man allerdings viel mehr machen – und dann wären Strings nicht mehr der geeignete Ansatz.
Antworten