heyde.schule
MOSFET-Gundlagenvortrag


Technische Informatik

Link zum Skript


Logic-Sim

Komplexaufgabe 4

🛡🔑🛡

Komplexaufgabe 3: UrnenProjekt

Bitte erstelle in deiner PyCharm Community Edition Schritt für Schritt ein neues Projekt mit dem Namen

UrnenProjekt

Achte darauf, dass dieses Projekt auf deinem Home-Netzlaufwerk (H:) gespeichert wird.
Es bleibt dir überlassen, ob du für jede Teilaufgabe eine eigene .py-Datei anlegst oder ob du alle Teilaufgaben in einer einzigen Python-Datei programmierst. Wichtig ist allerdings, dass der Projektname exakt UrnenProjekt lautet und dass es im Laufwerk H: liegt.


Im Folgenden findest du fünf aufeinander aufbauende Aufgaben für die Programmierung eines kleinen Kugelzieh-Spiels in Python. Bitte halte dich genau an die vorgegebenen Funktionsnamen und erstelle für jede Aufgabe genau eine Funktion.
Am Schluss sollen alle Teilfunktionen in einer letzten Funktion zusammenspielen, damit ein komplettes Programm entsteht.

Allgemeiner Kontext

  • Du hast eine Urne mit 10 Kugeln, davon
    • 4 Kugeln mit der Farbe "rot",
    • 3 Kugeln mit der Farbe "grün",
    • 3 Kugeln mit der Farbe "blau".
  • Die Urne soll mittels einer Liste repräsentiert werden (keine anderen Datenstrukturen).
  • Es wird ohne Zurücklegen gespielt. Das bedeutet, jede gezogene Kugel wird aus der Liste entfernt.

Nach jeder Teilaufgabe findest du eine kurze Testanleitung. Du kannst die beschriebenen Zeilen eins-zu-eins in deinen Code einfügen, um deine Implementierung zu überprüfen. Diese Aufrufe stehen nicht in einer eigenen Testfunktion, sondern sind einfache Aufrufe, die du direkt ausführen kannst.


Aufgabe (a): Begrüßungsfunktion

Funktion: greet_user(name)

  1. Erstelle eine Funktion, die einen Namen als Parameter entgegennimmt.
  2. Innerhalb dieser Funktion soll ein Begrüßungstext ausgegeben werden, z. B.:
    Hallo <Name>, ich begrüße dich ganz herzlich im Kugelzieh-Spiel!
  3. Verwendet werden soll ausschließlich das Ausgabekommando (z. B. print(...)). Es erfolgt keine Rückgabe.

Hinweise

  • Definiere die Funktion so, dass sie genau einen Parameter erwartet, z. B. name.
  • Verwende ein Ausgabekommando, um die Begrüßung anzuzeigen.

Test
Um deine Lösung zu testen, kannst du folgenden Code (ohne weitere Änderungen) unterhalb deiner Funktionsdefinition einfügen und ausführen:

# Test für Aufgabe (a) greet_user("Max") greet_user("Anna")

Aufgabe (b): Erstellen der Urne

Funktion: setup_urn()

  1. Erstelle eine Funktion ohne Parameter, welche eine Liste zurückgibt, die genau 10 Elemente enthält:
    • "rot", 3× "grün", 3× "blau".
  2. Diese Liste stellt unsere Urne dar.

Hinweise

  • Verwende eine Liste mit eckigen Klammern und füge die entsprechenden Farbnamen ein.
  • Gib die Liste am Ende mit return zurück, damit andere Funktionen später darauf zugreifen können.

Test
Füge zum Testen deiner setup_urn()-Funktion z. B. Folgendes in deinen Code ein und führe es aus:

# Test für Aufgabe (b) urne = setup_urn() print("Erstellte Urne:", urne) print("Anzahl Kugeln:", len(urne))

Aufgabe (c): Eine Kugel ziehen

Funktion: draw_ball(urne)

  1. Erstelle eine Funktion, die eine Liste (urne) als Parameter entgegennimmt.
  2. Die Funktion soll genau eine Kugel zufällig auswählen und zurückgeben.
  3. Anschließend soll diese gezogene Kugel aus der Liste entfernt werden, damit sie nicht erneut gezogen werden kann.

Hinweise

  • Um eine zufällige Position in der Liste zu ermitteln, kannst du mit dem Modul random arbeiten.
    • Beispielsweise könntest du das randint-Verfahren verwenden, das dir eine zufällige ganze Zahl im gewünschten Bereich liefert (z. B. zwischen 0 und len(urne) - 1).
    • Alternativ kannst du random.choice(...) nutzen, das dir zufällig ein Element aus der Liste auswählt – beachte dann jedoch, wie du anschließend dieses Element aus der Liste entfernst.
  • Nachdem du die Position oder das Element ausgewählt hast, solltest du es mittels einer Listenmethode entfernen. Hier bietet sich pop(i) an, um eine Kugel an einer bestimmten Position iaus der Liste zu löschen. Alternativ kannst du remove(x) benutzen um das zuerst auftauchende Element mit dem Wert x aus der Liste zu löschen.
  • Gib die gezogene Kugel (also den Farbnamen) am Ende mit return zurück.

Test
Kopiere diese Aufrufe nach deiner Funktionsdefinition und führe sie aus:

# Test für Aufgabe (c) u = setup_urn() gezogene_kugel = draw_ball(u) print("Gezogene Kugel:", gezogene_kugel) print("Restliche Kugeln in der Urne:", u) print("Anzahl verbliebener Kugeln:", len(u))

Aufgabe (d): Mehrere Kugeln ziehen

Funktion: draw_multiple_balls(urne, anzahl)

  1. Erstelle eine Funktion mit zwei Parametern:
    • die Liste urne
    • die Zahl anzahl (wie viele Kugeln gezogen werden sollen).
  2. In der Funktion sollen mehrere Kugeln nacheinander gezogen werden, genau so oft wie in anzahl angegeben.
  3. Sammle die Farbnamen der gezogenen Kugeln in einer eigenen Liste und gib diese Liste am Ende mit return zurück.

Hinweise

  • Um die Kugeln mehrfach zu ziehen, kannst du in Kombination mit einer For-Schleife arbeiten. Beispielsweise lässt sich mit for i in range(anzahl): eine Schleife erzeugen, die genau so oft durchlaufen wird, wie Kugeln zu ziehen sind.
  • Innerhalb dieser Schleife kannst du wiederholt deine Funktion draw_ball(urne) aufrufen.
  • Speichere die gezogenen Kugeln in einer neu erstellten leeren Liste, der du die jeweiligen Farbnamen mittels append(...) hinzufügst.
  • Vergiss nicht, die gesammelten Farbnamen am Ende mit return zurückzugeben.

Test
Auch hier kannst du deinen Code mit den folgenden Zeilen überprüfen:

# Test für Aufgabe (d) u = setup_urn() ergebnis = draw_multiple_balls(u, 4) print("Gezogene Kugeln:", ergebnis) print("Restliche Kugeln in der Urne:", u) print("Anzahl verbliebener Kugeln:", len(u))

Aufgabe (e): Das gesamte Spiel

Funktion: play_game()

  1. Erstelle eine Funktion ohne Parameter, die den Ablauf des Kugelzieh-Spiels steuert:
    • Frage den Spieler zunächst nach seinem Namen (z. B. über input()).
    • Begrüße ihn mit der Funktion greet_user(...).
    • Erstelle die Urne mit setup_urn().
    • Frage den Spieler, wie viele Kugeln er ziehen möchte (über input(), anschließend Umwandlung in eine ganze Zahl).
    • Ziehe die gewünschte Anzahl Kugeln durch draw_multiple_balls(...).
    • Gib das Ergebnis am Bildschirm aus, damit der Spieler sieht, welche Kugeln er gezogen hat.
  2. Achte dabei darauf, dass du alle Teilfunktionen einsetzt, die du in den vorherigen Aufgaben erstellt hast.

Hinweise

  • Du kannst mit dem Befehl input() Eingaben vom Nutzer erfassen und anschließend mithilfe von int() in eine Zahl umwandeln.
  • Sorge für ausreichend Ausgabe per print(...), damit der Spieler den Spielablauf nachvollziehen kann.

Test
Rufe deine fertige Spielfunktion auf, um den Programmablauf zu testen:

# Test für Aufgabe (e) play_game()

Wenn alles korrekt ist, solltest du nach deinem Namen und nach der Anzahl zu ziehender Kugeln gefragt werden. Anschließend werden dir die gezogenen Kugeln angezeigt.

Komplexaufgabe 2: Münzwurf-Spiel
🛡🔑🛡 🛡🔑🛡
Komplexaufgabe 1: Würfelspiel

Python Aufgaben – Hauptaufgabe 1: Würfelspiel (ganz einfach)

🛡🔑🛡🛡🔑🛡🛡🔑🛡🛡🔑🛡🛡🔑🛡

🛡🔑🛡

🛡🔑🛡🛡🔑🛡🛡🔑🛡🛡🔑🛡

Aufgaben zur Programmierung: Blackjack

Aufgabe 1:

  1. Erstelle eine Python-App, die zunächst eine Liste mit den 52 Pokerkarten erstellt (Karo, Herz, Pik, Kreuz, 2,3,4,5,6,7,8,9,10,Junge,Dame, König, Ass) erstellt. Dabei soll jede Karte wiederum als Liste abgespeichert werden, bestehend aus ihrer Farbe, ihrer Bezeichnung und ihrem Wert.
  2. Erkundige dich über die Wertigkeiten beim Blackjack selbstständig und vervollständige so das Deck.
  3. Nach der Definition soll nun das Deck gemischt werden (das Deck ist eine Liste). Danach soll die erste Karte des Decks dem Nutzer als Text ausgegeben werden.
  4. Der Nutzer entscheidet sich, ob er nun noch eine Karte möchte oder der Dealer am Zug ist.
  5. Das Ganze wiederholt sich, bis der Spieler den Dealer an die Reihe kommen lässt, oder die Summe der Werte der aufgedeckten Karten 21 übersteigt. Ist die Summe an einem Punkt genau 21 hat der Spieler sofort gewonnen. Übersteigt die Summe an einem Punkt 21, so hat der Spieler sofort verloren.
  6. In jedem anderen Fall wird nun (für den Dealer) so oft eine Karte vom Stapel gezogen, bis seine Karten ebenfalls einen Wert von 21 übersteigen. Wenn das passiert, gewinnt der Spieler. Hat der Dealer aber zwischendurch eine Wertsumme, die über der des Spielers liegt, verliert der Spieler.
  7. Alle soeben aufgedeckten Karten, sowie die insgesamt aktuell aufgedeckten Karten sollen für jeden Spielschritt ausgedruckt werden.

Hinweise:

  • Deck erstellen:
Deck = [['Herz','Junge',10],['Pik','Dame',10],...
  • Erstelle für die aufgedeckten Karten des Spielers und des Dealers jeweils eine Liste und befülle sie mit den Karten (Karten sind selbst auch listen mit 3 Elementen), die du aus dem Deck entnimmst.
  • Die folgende Funktion mischt ein Liste:
from random import *
shuffle(Deck)
  • Die folgende Funktion verkleinert eine Liste um das nte Element und gibt dieses Element zurück:
karte = Deck.pop(n)
  • Die folgende Funktion fügt einer Liste ein Element hinzu:
Spielerkarten.append(karte)
  • Die Wertsummen sollten zunächst in separaten Variablen gespeichert werden.

🛡🔑🛡

Aufgabe 2

  1. Erweitere das Spiel so, dass zum Berechnen der Spielerkartenwerte/ der Dealer Kartenwerte eine selbstgeschriebene Funktion mit dem Namen berechneKartenwertsumme(Liste) verwendet wird.
  2. Die Funktion soll eine Liste aus Karten als Eingabewert erwarten (Also eine Liste aus Listen) und die Summe der Kartenwerte der Liste als Integer zurückgeben.

Tipp:

  • Die Kartenwerte stehen an Indexposition 2 in den Kartenlisten. Es muss also die übergebene Liste mithilfe einer for-Schleife durchgegangen werden und dann jeweils der dritte Wert auf die Summe (die vorher mit dem Wert 0 angelegt wurde) addiert werden. Danach wird die Summe zurückgegeben.


🛡🔑🛡


Aufgabe 3:

  1. Erweitere das Spiel so, dass statt die Karten als Unterlisten zu printen, eine Funktion printKarte(Liste) benutzt wird, die die Liste Stück für Stück als String zusammensetzt und dann auf der Konsole ausgibt.
  2. Auf diese weise können Colorcodes benutzt werden, um Text farbig darzustellen. Implementiere Colorcodes in die Kartentexte.

Tipp:

  • Die Colorcodes können oben einmal definiert werden, anstatt sie jedes Mal neu in die String zu schreiben:
BLACK = '\033[30m'
RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m' # orange on some systems
BLUE = '\033[34m'
MAGENTA = '\033[35m'
CYAN = '\033[36m'
LIGHT_GRAY = '\033[37m'
DARK_GRAY = '\033[90m'
BRIGHT_RED = '\033[91m'
BRIGHT_GREEN = '\033[92m'
BRIGHT_YELLOW = '\033[93m'
BRIGHT_BLUE = '\033[94m'
BRIGHT_MAGENTA = '\033[95m'
BRIGHT_CYAN = '\033[96m'
WHITE = '\033[97m'
RESET = '\033[0m' # called to return to standard terminal text color
  • Die Benutzung erfolgt, indem man dann die vordefinierten Far-Variablen mit den eigenen Strings verknüpft:
print(BLACK + "black" + RESET)
print(RED + "red" + RESET)
print(GREEN + "green" + RESET)
print(YELLOW + "yellow" + RESET)
print(BLUE + "blue" + RESET)
print(MAGENTA + "magenta" + RESET)
print(CYAN + "cyan" + RESET)
print(LIGHT_GRAY + "light gray" + RESET)
print(DARK_GRAY + "dark gray" + RESET)
print(BRIGHT_RED + "bright red" + RESET)
print(BRIGHT_GREEN + "bright green" + RESET)
print(BRIGHT_YELLOW + "bright yellow" + RESET)
print(BRIGHT_BLUE + "bright blue" + RESET)
print(BRIGHT_MAGENTA + "bright magenta" + RESET)
print(BRIGHT_CYAN + "bright cyan" + RESET)
print(WHITE + "white" + RESET)

Aufgaben zur Programmierung: Ratespiel
Aufgabe 1

  1. Erstelle ein Programm, welches zu Beginn eine zufällige Zahl in einer Variable speichert. Diese zahl ist die "Lösungszahl".
  2. Danach wird der Benutzer wiederholt nach einer Zahl gefragt, welche er eingeben soll.
  3. Ist die Zahl die gemerkte Zahl, so beendet sich das Programm, sonst wiederholt sich die Frage nach der Benutzerzahl.


  • Befehl für zufällige Zahl:
    • randint(untere Grenze, obere Grenze)
  • Damit der Befehl funktioniert muss die random-Bibliothek eingebunden werden. Die erste Zeile muss also lauten:
    • from random import *


    • Bonus: Alle möglichen fehlerhaften Eingaben werden abgefangen/führen nicht zum Abbruch des Programms (try - except)

    Lösung:

    🛡🔑🛡

    Aufgabe 2:

    • Erweitere das Programm so, dass, nach jedem erfolglosen Rateversuch, dem Nutzer zurückgemeldet wird, ob seine geratene Zahl zu groß oder zu klein war.

    Lösung:

    🛡🔑🛡

    Aufgabe 3:

    • Erweitere das Programm so, dass der Nutzer die Obergrenze der Zufallszahl selbst bestimmen darf.
    • Fange alle Fehler bei dieser Eingabe ab, und frage solange nach einer Obergrenze, bis eine gültige Zahl eingegeben wurde.

    Lösung:

    🛡🔑🛡

    Aufgabe 4

    • Erweitere das Programm so, dass als Obergrenze nur Zahlen akzeptiert werden, die größer als die Obergrenze sind.

    Lösung:

    🛡🔑🛡

    Aufgaben zur Programmierung: Auslosen von Namen
    Aufgabe 1

    1. Erstelle ein Programm, welches den Nutzer wiederholt nach der Eingabe von Namen fragt und diese Namen in eine Liste speichert.
    2. Gibt der Benutzer statt eines Namens das Wort "ende" ein, so wird die Eingabe der Namen beendet und die Liste wird dem Nutzer ausgegeben.

    Hinweis:

    • Die Liste muss zuvor mit [] initialisiert werden.
      • Bsp:

      liste = []
      • Der Befehl zum Hinzufügen eines Elements zu einer Liste lautet liste.append(element), wobei liste die liste ist und element das anzuhängende Element:
        • Bsp:

        liste.append('Thomas Müller')

        Musterlösung:

        🛡🔑🛡

        Aufgabe 2

        1. Erweitere das Programm so, dass das Wort ende in jeder beliebigen Schreibweise akzeptiert wird. (Ende, eNdE, enDe usw...)

        Hinweis:

        • die Funktion text.upper() wird auf einem String ausgeführt und gibt die Großbuchstabenschreibweise davon als String zurück.
        • die Funktion text.lower() wird auf einem String ausgeführt und gibt die Kleinbuchstabenschreibweise davon als String zurück.
        lowertext = originaltext.lower()
        uppertext = originaltext.upper()
        Musterlösung mit lower():
        🛡🔑🛡
        Aufgabe 3

        1. Erweitere das Programm so, dass nach der Eingabe der Liste ein zufälliger Name aus der Liste ausgegeben wird.

        Hinweis:

        • die Funktion len(liste) gibt die Anzahl der Elemente einer Liste zurück. Sie wird auf einer Liste ausgeführt.
        • (Alternativ kann auch die Methode __len__() verwendet werden.)
        • Bsp:
        anzahlElemente = len(liste)

        Alternativ:

        anzahlElemente = liste.__len__()

        Musterlösung:

        🛡🔑🛡

        Aufgabe 4

        1. Erweitere das Programm so, dass nach der Eingabe der Liste nach einer Anzahl der zufällig auszugebenden Namen gefragt wird. Danach wird genau diese Anzahl an zufälligen Namen aus der Liste ausgegeben. 
        2. Wird eine größere Zahl als die Anzahl der Elemente der Liste gefordert, so soll der Benutzer die Eingabe wiederholen, bis er eine gültige Zahl eingibt.
        3. Es dürfen keine Elemente der Liste doppelt ausgegeben werden.


        Hinweise:

        • pop() ist eine Methode von Listen, die das n-te Element der Liste dauerhaft aus der Liste entfernt und dieses Element zurückgibt (sodass man es sich in einer Variable speichern/"merken" kann.
        element_an_position_n = liste.pop(n)
        • die range(n)-Funktion erzeugt eine Liste mit n Elementen. Das in Kombination mit der for-Schleife erzeugt automatisch n Schleifendurchläufe.
        • Möchte ich eine Aktion z.B. 6 Mal wiederholen schreibe ich:
        for i in range(5):
        • Die Durchlaufvariable i ist dabei zweitrangig, sie muss angegeben werden und enthält im ersten Durchlauf den Integer-Wert 1, dann den Wert 2, bis zum Wert 5. Wenn sie nicht benötigt wird, ist das egal, ihre Angabe im Schleifenkopf ist aber leider nicht vermeidbar.
        Sonderaufgabe

        1. Programmiere eine Funktion inputInteger(a,b), die eine Ganzzahl vom Benutzer erfragt und dies solange wiederholt, bis dieser eine gültige Ganzzahl zwischen Grenze a und Grenze b eingibt und diese dann zurückgibt.
        def inputInteger(a,b):


        Pluspunkte inf2

        Ungenutzte Punkte in anderes Schul(halb)jahr verschieben...
        inf2
        Sommerhalbjahr 25
        (02. März 2024 - 27. Juni 2025)
        8950
        0
        0815
        0
        0812
        0
        7272
        0
        6128
        0
        0438
        0
        0305
        0
        0804
        0
        0161
        0
        3690
        0
        7385
        0
        0
        0710
        0
        0

        Pluspunkte inf1

        Ungenutzte Punkte in anderes Schul(halb)jahr verschieben...
        inf1
        Sommerhalbjahr 25
        (02. März 2024 - 27. Juni 2025)
        12345
        4
        1003
        0
        1379
        1
        0406
        2
        1348
        0
        1812
        2
        1902
        2
        1312
        0
        2405
        0
        0357
        -1
        2509
        -1
        0

        Vorträge

        Vortragsmodalitäten:

        • Partnerarbeit (Freie Wahl) oder Einzelarbeit
        • Präsentationsdauer min. 10, max. 15 Minuten
        • Themen sind frei wählbar, der Arbeitsauftrag lautet: Haltet einen Vortrag über angewandte Informatik in einem selbstgewählten Themengebiet. Er soll einen Ausblick auf einen Teilbereich der angewandten Informatik geben. Den konkreten Teilbereich bestimmt ihr selbst. Ordnet das Thema auch geschichtlich ein und berichtet über Vorteile der Anwendung der Informatik in euren Themengebieten, wie auch über Hürden, die diese mit sich bringen. Gebt einen Ausblick in die Zukunft. Umfang und Tiefgang des Themas bestimmt Ihr. Es muss ein informativer, unterhaltsamer, fachlich korrekter Vortrag entstehen, und Rückfragen kompetent beantwortet werden. Im Anschluss findet eine Reflexion statt. Pflichtinhalte sind:
          • Strukturierte Einordnung der Bedeutung des Anwendungsgebiets für die Menschheit
          • Mindestens oberflächliche Erklärung der Funktionsweise ausgewählter Beispiele
          • Erklärung jeglicher Fachbegriffe in einfacher Sprache
          • Angabe von Quellen
        • Beispiel: Im Fachbereich der Medizin wurden an verschiedensten Stellen informatische Konzepte angewandt, das reicht von der digitalen patientenverwaltung, über die Diagnose von Krankheiten und der KI-Erkennung von Krebsarten über bildgebende Verfahren bis hin zur robotischen Operation. Welche Entwicklung hat es in welcher Reihenfolge gegeben, was steht noch bevor, welche Probleme könnte es dabei geben und welche Vorteile hat man jetzt schon deswegen? Wie funktionieren die informatischen Lösungen technisch (grob zusammengefasst)?
        • Wird ein Thema doppelt gewählt, muss sich der Inhalt ergänzen, nicht überschneiden. Die Abstimmung unter diesen Gruppen halten die Gruppen selbst.
        • Übersichtliche Präsentation muss ungefragt, digital und mit Namen versehen, noch vor dem Vortrag, per Mail gesendet werden. (mail@paulheyde.de)
        • Das Abgabeformat ist pdf, pptx, ppt, odp, html oder mp4.
        • Bewertungskriterium: 25% Präsentationsdokument, 25% Präsentation, 25% Nachfragensicherheit, 25% Reflexion
          Tipp:
        • Vortragsbeginn: 3. September (Angepeilt ist 1 Vortrag pro Doppelstunde)
        • Reihenfolge der Vorträge: Erst freiwillige, dann zufällig

        Wissenschaft Informatik

        Klausurrelevante Themen:

        • Wissenschaft Informatik (Skript)
        • Algorithmentheorie (Skript)
        • Pythonprogrammierung:
          • Zuweisungsoperationen (x = 4), Variablennamen und Variablenzuweisung
          • Funktionen in Python (Funktionsdefinition, Funktionsaufruf) (Siehe Skript Pythonprogrammierung)
          • Übertragung der Pythonprogrammierung auf die dahinterarbeitende Hardware (Siehe Skript Algorithmenvisualisierung)
        • Die Klausur ist Multiple-Choice, die zwei letzten Themen werden nur angerissen, z.B. wird ein Beispielcode gezeigt und es soll erklärt werden, wie oft welche Variablen neu belegt werden, bzw. wo ggf. Fehler entstehen können usw.
        • Bei Fragen bitte per Mail an mich wenden


        Link zum Skript zum Thema Wissenschaft Informatik (vollumfänglich Klausurrelevant!)

        Link zum Skript zum Thema Algorithmentheorie (vollumfänglich Klausurrelevant!)

        Link zum Skript zum Thema Pythonprogrammierung (teilweise Klausurrelevant!)

        • Hier sind nur die Folien bis zu den Verzweigungen/Schleifen relevant.

        Link zum Skript Programmablaufvisualisierung (teilweise Klausurrelevant!)

        • Dieses Skript enthält ausführliche und bildhafte Erläuterungen rund um das Thema Programmablauf. Dabei wird auf die Rolle des Prozessors/Computers eingegangen und detailiert die Vorgehensweise des Computers beim Ablauf von Programmen erklärt. Bitte bis zur zur letzten Oktoberwoche anschauen.
        • Danach werden vor der Klausur nochmal Fragen geklärt. Die Vorträge verschieben sich.


        Python Online-Interpreter

        Für das Testen der Übungsaufgaben werden folgende Interpreter empfohlen:

        https://www.online-python.com/

        https://www.programiz.com/python-programming/online-compiler/

        🔑