Quadratpflanze

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
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Hallo,
die gestellte Aufgabe konnte ich zwar m. E. gut umsetzten, aber ich habe gerade einen Knoten im Kopf, was meine while-Schleife angeht.
Ich denke, dass sie nur 8mal durchlaufen muss, aber ich weis nicht, wie ich sie dazu bringe.
Hier die Aufgabe:
Entwickeln Sie eine Funktion quadratpflanze, welche den Wachstum einer quadratischen Pflanze berechnet, die gemäß folgender Abbildung wächst:

Quadratpflanze.png

In jedem Zyklus wachsen an allen drei Seiten der äußersten Quadrate kleinere Quadrate, jeweils mit einem Drittel der Seitenlänge.
Die Abbildung zeigt die Pflanze nach zwei Zyklen.
Der Funktion sollen die Basislänge b [cm] und optional die Anzahl an Zyklen, die berechnet werden sollen, übergeben werden.

Wenn keine Anzahl der Zyklen vorgegeben wird, soll berechnet werden, nach wie vielen Zyklen die Pflanze ausgewachsen ist. Dies ist der Fall, wenn die Fläche sich um weniger als 0.01cm² ändert. Die Ausgabe soll dann wie folgt aussehen:

Eine Quadratpflanze mit einer Basislänge von 10 cm ist nach 8 Zyklen ausgewachsen.
Umfang der ausgewachsenen Quadratpflanze: 200.0 cm
Fläche der ausgewachsenen Quadratpflanze: 149.99 cm²

Sollten die Zyklen jedoch vorgegeben sein, sollen Umfang und Fläche der Pflanze nach der gegebenen Anzahl an Zyklen ausgegeben werden. Die Ausgabe soll dann wie folgt aussehen:

Umfang der Quadratpflanze mit einer Basislänge von 10 cm nach 5 Zyklen: 140.0 cm
Fläche der Quadratpflanze mit einer Basislänge von 10 cm nach 5 Zyklen: 149.79 cm²

Hinweise
1. Beachten Sie unbedingt auf die Formatierung der einzelnen Zeilen, d. h. etwaige Leerzeichen, Doppelpunkte, etc. sind korrekt anzugeben!

2. Bei dem Umfang handelt es sich immer nur um die äußersten Seiten der Pflanze. In der Abbildung ist der Umfang durch die roten Linien gekennzeichnet.

3. Die Ergebnisse sollen auf 2 Nachkommastellen gerundet werden.

4. Für die Berechnung der Zuschläge kann es sinnvoll sein, eine Funktion zu schreiben, die anhand der Seitenlänge der aktuell äußersten Quadrate und dem aktuellen Zyklus die Zuschläge berechnet und diese zurückgibt.
Punkt 4 der Hinweise habe ich soweit erst mal "ignoriert", da ich eine grundlegend funktionierende Lösung gefunden habe. Wenn ihr dazu auch noch ne Meinung habe, in wie weit ich meinen Code verbessern kann, bin ich auch dafür dankbar.

Aber hier erst mal mein Stand der Dinge:

Code: Alles auswählen

def quadratpflanze(b, zyklen=None):
    
    umfang = 4 * b
    flaeche = b ** 2
    
    if zyklen is None:
        zyklen = 0
        aenderung_max = 0.01
        flaeche_aktuell = 0
        
        while True:
            zyklen += 1
            aenderung_aktuell = flaeche / ( 3 ** zyklen )
            flaeche_aktuell += aenderung_aktuell
            
            if aenderung_aktuell < aenderung_max:
                break
        umfang += zyklen * ( 3 * b/3 * 2 )
        flaeche = flaeche + flaeche_aktuell
        
        # print(aenderung_aktuell)
        print(f'Eine Quadratpflanze mit einer Basislänge von {b} cm ist nach {zyklen} Zyklen ausgewachsen.')
        print(f'Umfang der ausgewachsenen Quadratpflanze: {umfang:.2f} cm')
        print(f'Fläche der ausgewachsenen Quadratpflanze: {flaeche:.2f} cm²')
    else:
        umfang += zyklen * ( 3 * b/3 * 2 )
        flaeche_aktuell = 0
        for zyklus in range(zyklen + 1):
            flaeche_aktuell += flaeche / ( 3 ** zyklus )
        flaeche = flaeche_aktuell
        print(f'Umfang der Quadratpflanze mit einer Basislänge von {b} cm nach {zyklen} Zyklen: {umfang:.2f} cm')
        print(f'Fläche der Quadratpflanze mit einer Basislänge von {b} cm nach {zyklen} Zyklen: {flaeche:.2f} cm²')
Für Hinweise und konkrete Hilfestellungen wäre ich sehr dankbar.
VG
Fabian
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: Erst einmal bricht der Code zu spät ab, denn Du hast eine Fläche von 150 cm², die Aufgabe sagt aber da sollten 149,99 cm² heraus kommen.

Und damit verbunden: Ein Zyklus ist ja erst fertig wenn die Pflanze tatsächlich gewachsen ist. Du zählst den aber schon hoch bevor Du überhaupt weisst ob die Pflanze noch wächst, oder ob die Schleife abgebrochen wird. Das heisst beim Abbruch musst Du Zyklen wieder 1 runterzählen, denn den 9. Zyklus, wo die Abbruchbedingung erreicht ist, solltest Du nicht drauf addieren, also zählt der auch nicht.

Was sonst noch Verbesserungswürdig wäre: die beiden Zweige enthalten viel sehr ähnlichen Code. Da sollte man Gemeinsamkeiten heraus ziehen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: Bei der ``while``-Schleife ist `zyklen` als Name falsch, denn das ist ja genau wie im anderen Beispiel der aktuelle `zyklus` der da repräsentiert wird.

Hier mal nur mit einer Schleife für beide Fälle:

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import count


def quadratpflanze(basislaenge, zyklen=None):
    umfang = 4 * basislaenge
    flaeche = basislaenge**2

    aenderung_max = 0.01 if zyklen is None else 0
    ausgewachsen = False
    zusaetzliche_flaeche = 0
    for zyklus in count(1) if zyklen is None else range(1, zyklen + 1):
        aenderung = flaeche / 3**zyklus
        if aenderung < aenderung_max:
            zyklus -= 1
            ausgewachsen = True
            break
        
        zusaetzliche_flaeche += aenderung

    umfang += zyklus * (3 * basislaenge / 3 * 2)
    flaeche += zusaetzliche_flaeche

    if ausgewachsen:
        template = (
            "Eine Quadratpflanze mit einer Basislänge von {basislaenge} cm ist nach {zyklus} Zyklen ausgewachsen.\n"
            "Umfang der ausgewachsenen Quadratpflanze: {umfang:.2f} cm\n"
            "Fläche der ausgewachsenen Quadratpflanze: {flaeche:.2f} cm²"
        )
    else:
        template = (
            "Umfang der Quadratpflanze mit einer Basislänge von {basislaenge} cm nach {zyklus} Zyklen: {umfang:.2f} cm\n"
            "Fläche der Quadratpflanze mit einer Basislänge von {basislaenge} cm nach {zyklus} Zyklen: {flaeche:.2f} cm²"
        )

    print(
        template.format(
            basislaenge=basislaenge,
            zyklus=zyklus,
            umfang=umfang,
            flaeche=flaeche,
        )
    )


def main():
    quadratpflanze(10)
    quadratpflanze(10, 5)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Hier mal der Ansatz, der funktioniert:

Code: Alles auswählen

def quadratpflanze(b, zyklen=None):
    umfang = 4 * b
    flaeche = b ** 2
    flaeche_aktuell = 0
    
    if zyklen is None:
        zyklen = 0
        aenderung_max = 0.01
        
        while True:
            zyklen += 1
            aenderung_aktuell = flaeche / (3 ** zyklen)
            
            if aenderung_aktuell < aenderung_max:
                break
            
            flaeche_aktuell += aenderung_aktuell
        
        zyklen -= 1
        umfang += zyklen * (3 * b / 3 * 2)
        flaeche += flaeche_aktuell
        
        print(f'Eine Quadratpflanze mit einer Basislänge von {b} cm ist nach {zyklen} Zyklen ausgewachsen.')
        print(f'Umfang der ausgewachsenen Quadratpflanze: {umfang:.2f} cm')
        print(f'Fläche der ausgewachsenen Quadratpflanze: {flaeche:.2f} cm²')
    else:
        umfang += zyklen * (3 * b / 3 * 2)
        
        for zyklus in range(zyklen + 1):
            flaeche_aktuell += flaeche / (3 ** zyklus)
        
        flaeche = flaeche_aktuell
        
        print(f'Umfang der Quadratpflanze mit einer Basislänge von {b} cm nach {zyklen} Zyklen: {umfang:.2f} cm')
        print(f'Fläche der Quadratpflanze mit einer Basislänge von {b} cm nach {zyklen} Zyklen: {flaeche:.2f} cm²')
Das mit den 150.00 war ja genau das Problem, da der Code einen Zyklus zu weit gegangen ist und statts 149.992... zu 149.99 zu runden wurde 149.997... zu 150.00 gerunden. Aber das sollte ja nun behoben sein, da der Code m. E. nun grundsätzlich passen sollte.

Aber was genau könnte man da auslagern?
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

Oh, deinen zweiten Beitrag leider zu spät gesehen. :?

Ich setzt mich noch mal dran.
PS: neue Bibliotheken wie hier itertools ist zwar immer cool, führen aber aktuell dazu, dass ich mich in solchen Dingen sehr schnell verliere. Und das Programmieren darf in meinem Studium keinen allzu großen Stellenwert einnehmen. Ich bleibe dann für diese Übung bei dem, was ich kenne bzw. uns "beigebracht wurde".
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn ich sowas wie "Programmieren darf in meinem Studium keinen allzu großen Stellenwert einnehmen" lese, kommt mir die Galle hoch. Ich weiss nicht, woher das kommt - ob durch Bologna, oder was anderes. Oder ob ich das einfach aus meiner Biografie selbst nicht nachvollziehen kann, und es schon immer so war. Ist darum auch nicht persoenlich gemeint, ich stecke nicht in deinen Schuhen.

Ich habe ganze Semester fuer Mars-Robotor-Prototypen der DLR, an denen ich gewerkelt habe, draufgehen lassen. Und was ich dabei gelernt habe, uebersteigt jede verpasste Vorlesung um Groessenordnungen. Mein Diplom habe ich 19 Jahre nach Studienbeginn abgeschlossen. Aber zu dem Zeitpunkt war ich schon 10 Jahre senior engineer in diversen Firmen. Das ist dermassen irrelevant gewesen, dass ich es nur abgeschlossen habe, weil die Uni den Studiengang zugunsten von Bachelor/Master abkuendigen wollte. In dem Zusamenhang war der alte Mann dann auch nochmal mit den jungen Leuten in einem Raum & hat ein Projekt gemacht. Da kamen auch so Sprueche bei den Angeboten aus der Projektbetreuung fuer coole Dinge "ja, aber was bringt mir das denn an Credit-Points?".

In der Lage zu sein (und Willens...), sich abseits ausgetretener Pfade etwas neues draufschaffen zu koennen, ist ein so wichtiger Skill - das kann gar nicht hoch genug bewertet werden. Egal ob beim Programmieren, oder was auch immer. Die Credit-Points hingegen, auf die du oder andere so scharf sind - die intressieren wirklich *kein* Schwein. Nirgendwo in der Welt da draussen bekommt man schoene Gummipunkte, die man in sein Sammelalbum kleben kann. Probleme loesen, das zaehlt. Ja, auch unter Zeitdruck, und nicht immer mit dem neuesten heissen Scheiss. Das kann auch schlecht sein. Aber wenn's nen Zeitpunkt fuer sowas gibt, dann doch das Studium.

Sorry fuer den Rant. Aber musst mal raus.
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Feedback1000: `itertools` (und das externe `more_itertools`) gehören IMHO zu den Grundwerkzeugen. Genau wie `collections`, `enum`, `functools`, `operator`, und `contextlib` beispielsweise. Da sind allgemein nützliche Sachen drin, die einem das Leben einfacher machen. Und sei es nur um sich immer wieder die selben paar Zeilen Code zu sparen, denn `itertools.count()` ist ja nicht kompliziert selbst zu schreiben. Die Funktionalität die im Beispiel hier verwendet wird, läuft letztlich auf diese einfache Funktionsdefinition hinaus, wenn man sich das nicht importieren will:

Code: Alles auswählen

def count(start_value=0):
    while True:
        yield start_value
        start_value += 1
Aber importieren ist halt *noch* einfacher, man kann keine Flüchtigkeitsfehler machen, und man hat nicht in mehreren Projekten immer wieder diese gleiche simple Funktion stehen.

Für mich persönlich gehört dann noch `attrs` in den allgemeinen Werkzeugkasten, um das schreiben von Klassen zu vereinfachen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Feedback1000
User
Beiträge: 88
Registriert: Dienstag 20. September 2022, 21:21

__deets__ hat geschrieben: Sonntag 4. Juni 2023, 12:48 Wenn ich sowas wie "Programmieren darf in meinem Studium keinen allzu großen Stellenwert einnehmen" lese, kommt mir die Galle hoch. Ich weiss nicht, woher das kommt - ob durch Bologna, oder was anderes. Oder ob ich das einfach aus meiner Biografie selbst nicht nachvollziehen kann, und es schon immer so war. Ist darum auch nicht persoenlich gemeint, ich stecke nicht in deinen Schuhen.

Ich habe ganze Semester fuer Mars-Robotor-Prototypen der DLR, an denen ich gewerkelt habe, draufgehen lassen. Und was ich dabei gelernt habe, uebersteigt jede verpasste Vorlesung um Groessenordnungen. Mein Diplom habe ich 19 Jahre nach Studienbeginn abgeschlossen. Aber zu dem Zeitpunkt war ich schon 10 Jahre senior engineer in diversen Firmen. Das ist dermassen irrelevant gewesen, dass ich es nur abgeschlossen habe, weil die Uni den Studiengang zugunsten von Bachelor/Master abkuendigen wollte. In dem Zusamenhang war der alte Mann dann auch nochmal mit den jungen Leuten in einem Raum & hat ein Projekt gemacht. Da kamen auch so Sprueche bei den Angeboten aus der Projektbetreuung fuer coole Dinge "ja, aber was bringt mir das denn an Credit-Points?".

In der Lage zu sein (und Willens...), sich abseits ausgetretener Pfade etwas neues draufschaffen zu koennen, ist ein so wichtiger Skill - das kann gar nicht hoch genug bewertet werden. Egal ob beim Programmieren, oder was auch immer. Die Credit-Points hingegen, auf die du oder andere so scharf sind - die intressieren wirklich *kein* Schwein. Nirgendwo in der Welt da draussen bekommt man schoene Gummipunkte, die man in sein Sammelalbum kleben kann. Probleme loesen, das zaehlt. Ja, auch unter Zeitdruck, und nicht immer mit dem neuesten heissen Scheiss. Das kann auch schlecht sein. Aber wenn's nen Zeitpunkt fuer sowas gibt, dann doch das Studium.

Sorry fuer den Rant. Aber musst mal raus.
Ich kann deinen Unmut über meine zugegeben unpräzise Aussage voll und ganz nachvollziehen. Ich bin selbst auch nicht mehr der jüngste und habe mich mit Mitte 30 auch noch einmal für ein Studium entschieden - nachdem ich viele Jahre als Facharbeiter coolen Shit gemacht habe.
Mein Anspruch in diesem Studium ist es auch nicht um jeden Preis jede Prüfung mit der besten Noten beim ersten Versuch zu bestehen. Ganz im Gegenteil: ich schaue abseits von den "Soll-Dingen" ganz viel nach Links und Rechts, dass der Haufen gerade etwas zu groß geworden ist und ich muss zusehen, dass ich wieder Luft zum Atmen bekomme.
Mir ist absolut bewusst, dass das Programmieren auch in meiner Branche (Geodäsie) einen verdammt großen Stellenwert hat und ein mächtiges Werkzeug ist, und ich würde mich wirklich gern damit auseinander setzen, aber an meinen anderen Dingen hängen auch noch andere Personen dran, die sich auf mich verlassen.
Sobald ich wieder Land sehe, werde ich mir weitere Tools in der Programmierung drauf schaffen.
Ich hoffe, dass ich dir meine Situation klar machen konnte.
Nichts desto trotz danke ich dir für deine offenen Worte und hoffe, dass sie einen Signal auch für andere sind (auch wenn ich glaube, dass nur sehr wenige diesen Thread lesen werden).
Antworten