Benutzer-Werkzeuge

Webseiten-Werkzeuge


schule:programmieruebungen

Dies ist eine alte Version des Dokuments!


Programmierübungen

Programmieren lernt man am besten durch Programmieren. Nicht durch das Zugucken, auch nicht durch das Lesen von Büchern und Webseiten, und auch nicht durch das Schauen von Videos.

Übungen zu Schleifen

Bei den folgenden Aufgaben ist die Lösung mit einer for-Schleife einfach zu erstellen. Kannst du sie auch mit einer while-Schleife lösen?

Für Profis, dich sich mit Rekursion auskennen: Man kann die Aufgaben sogar komplett ohne Schleife lösen.

Zahlen bis maximum

Von der Tastatur wird eine Zahl maximum eingelesen. Anschließend gibt das Programm alle Zahlen von 1 bis maximum aus.

Eingabe: 8
Ausgabe: 1, 2, 3, 4, 5, 6, 7, 8

Gerade Zahlen

Von der Tastatur wird eine Zahl maximum eingelesen. Anschließend gibt das Programm alle geraden Zahlen von 0 bis maximum aus.

Eingabe: 6
Ausgabe: 0, 2, 4, 6

Hoch- und Runterzählen

Das Programm gibt die Zahlen von 1 bis 10 und dahinter die Zahlen von 10 bis 1 aus. Es zählt also einmal rauf und dann wieder runter. Versuche, nur eine for-Schleife zu verwenden.

Ausgabe: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

Sternenreihe

Schreiben Sie ein Programm, das zunächst die Eingabe einer positiven Zahl anzahl über die Tastatur erwartet. Anschließend soll das Programm anzahl-mal ein Sternchen (*) auf den Bildschirm ausgeben. Beispielablauf des Programms (Benutzereingaben in <>):

Anzahl (>0): <8>
********

Sternentreppe

Schreiben Sie ein Programm, das nach Eingabe einer positiven Zahl hoehe eine Treppe der im folgenden Beispielprogramm skizzierten Form auf den Bildschirm ausgibt. Die Treppe soll aus hoehe-Zeilen bestehen. Beispielablauf des Programms (Benutzereingaben in <>):

Hoehe (>0): <5>

*
**
***
****
*****

Sternendreieck

Schreiben Sie ein Programm, das nach Eingabe einer ungeraden Zahl basislaenge ein Sterndreieck auf den Bildschirm ausgibt. Die unterste Reihe soll dabei aus basislaenge Sternchen bestehen. Beispielablauf des Programms (Benutzereingaben in <>):

Basislaenge (>0 und ungerade): <9>

    *
   ***
  *****
 *******
*********

BMI-Rechner

Der Body-Mass-Index (BMI) ist eine Maßzahl für die Bewertung des Körpergewichts eines Menschen. Der BMI berechnet sich aus dem Körpergewicht [kg] dividiert durch das Quadrat der Körpergröße [m²]. Die Formel lautet: BMI = Körpergewicht / (Körpergröße in m)². Die Einheit des BMI ist demnach kg/m². Implementieren Sie einen BMI-Rechner.

Beispielablauf des Programms (Benutzereingaben in <>):

Bitte geben Sie Ihr Gewicht ein (in kg): <75>
Bitte geben Sie ihre Größe ein (in m): <1.81>
BMI = 22.89307408198773

Notenrechner

Der Notenrechner berechnet die Note bei Eingabe der Gesamtpunktzahl und der erreichten Punkte nach dem IHK-Schlüssel.

Noteab
1 92%
2 81%
3 67%
4 50%
5 30%

Beispielablauf eines Programms (Nutzereingaben in <>):

Maximale Punktzahl: <10>
Note	ab
1 	9.2
2 	8.1
3 	6.7
4 	5.0
5 	3.0
6 	0.0

Maximale Punktzahl: <5>
Note	ab
1 	4.6
2 	4.05
3 	3.35
4 	2.5
5 	1.5
6 	0.0

Zahlenraten

Bei dem Spiel Zahlenraten geht es darum, möglichst schnell eine Zahl zwischen 0 und 100 zu erraten, die sich der Computer zufällig ausgedacht hat. Man kann dem Computer immer wieder eine Zahl nennen und er antwortet jeweils mit Die gesuchte Zahl ist kleiner oder Die gesuchte Zahl ist größer oder Richtig geraten.

Erstelle ein Programm, mit dem du das Spiel gegen den Computer spielen kann.

Tipp: Eine Zufallszahl zwischen a und b kann in Python mit import random und dann mit random.randint(a, b) erzeugt werden.

Klasse Auto

Für ein Autohaus ist eine Klasse Auto zu entwickeln. Folgende Datenfelder sind bei einem Auto zu verwalten:

  • Hersteller (String)
  • Laufleistung in km (Ganzzahl)
  • Preis in EUR (Kommazahl)
  • Farbe (String)
  • Unfallwagen (boolean)
  • Kraftstoff (String)
  • Leistung in PS (Kommazahl)

Ein Objekt vom Typ Auto soll mit folgender Codezeile erzeugt werden können:

  a = Auto(hersteller="Ford", laufleistung=125000, preis=7999.99,
           farbe="silber metallic", unfallwagen=False, kraftstoff="Diesel",
           ps=101.0)

Der Aufruf a.ausgabe()) sollte in etwa folgendes Ergebnis ausgeben:

  Hersteller: Ford
  Preis: 7999.99 EUR
  Motor: 101.0 PS (Diesel)
  KM-Stand: 125000 km
  Farbe: silber metallic
  unfallfrei

Der Zusatz “unfallfrei” soll nur ausgegeben werden, wenn das Datenfeld “Unfallwagen” den Wert false hat. Entwickeln Sie nun bitte diese Klasse Auto und testen Sie diese mit den folgenden Codezeilen.

Klassen für geometrische Objekte

+----------------------------+
| Kreis                      |
+----------------------------+
| radius: double             |
| farbe: string              |
+----------------------------+
| __init__(radius:double)    |
| get_radius(): double       |
| berechne_flaeche(): double |
| berechne_umfang(): double  |
+----------------------------+
  1. Erstelle eine Klasse Kreis nach dem obigen Klassendiagramm. Der Default-Wert für die Farbe soll „rot“ sein.
  2. Erstelle drei unterschiedliche Instanzen und teste damit die Methoden.
  3. Erstelle auf ähnliche Weise ein Klassendiagramm und den Quelltext für eine Klasse „Rechteck“.
geometrie.py
import math
 
class Kreis:
    'Ein Kreis'
 
class Rechteck:
    'Ein Rechteck'
 
# Tests
k = Kreis(3)
assert hasattr(k, "radius")
assert k.radius == 3
assert k.get_radius() == 3
assert 28.2 < k.berechne_flaeche() < 28.3
assert 18.8 < k.berechne_umfang() < 18.9

Klasse für Brüche

In Python gibt es keinen vordefinierten Datentyp für Brüche. Mit der Klasse Bruch soll diese Lücke geschlossen werden.

Wir beginnen mit dem folgenden Klassendiagramm zur Klasse Bruch:

+---------------------+
| Bruch               |
+---------------------+
| zaehler: int        |
| nenner: int         |
+---------------------+
| Bruch(z:int, n:int) |
| erweitern(k: int)   |
| kuerzen(k: int)     |
+---------------------+

(a) Entwickle eine geeignete Implementierung zu dieser Klasse, so dass Python-Dialoge der folgenden Art möglich werden:

>>> b = Bruch(4, 6)
>>> b.erweitern(3)
>>> b.kuerzen(2)
>>> b.zaehler
6.0
>>> b.nenner
9.0

(b) (eher schwierig) Ergänze die Klasse Bruch um eine Operation vollstaendigKuerzen. Entwickle auch dazu eine geeignete Implementierung.

>>> b.vollstaendigKuerzen()
>>> b.zaehler
2.0
>>> b.nenner
3.0

Quelle

Klasse für Zähler

Ein Zähler ist ein Gerät (Objekt), mit dem man hochzählen kann, und den man gezielt wieder auf Null setzen kann. Man benutzt solche Geräte z.B. bei Verkehrszählungen.

(a) Modelliere eine Klasse Zaehler, mit der man Objekte erzeugen kann, die sich wie Zähler in der Wirklichkeit verhalten. Berücksichtige vorerst noch nicht, dass es für die Zahl eine Obergrenze gibt. Stell die modellierte Klasse mit einem Klassendiagramm dar. Implementiere und teste anschließend die entwickelte Klasse.

(b) Wenn man eine Uhr simulieren möchte, dann benötigt man einen Sekunden- bzw. Minutenzähler, der so zählt:

0, 1, 2, 3, ..., 58, 59, 0, 1, 2, 3, ..., 58, 59, 0, 1, 2, ...

Ein Stundenzähler zählt entsprechend:

0, 1, 2, 3, ..., 23, 0, 1, 2, 3, ..., 23, 0, 1, 2, ...

Modelliere und implementiere auch für Zählsituationen mit einer Obergrenze eine geeignete Klasse.

Quelle

Klassen für Adam und Eva

In der Bibel steht, dass Adam und Eva die ersten Menschen auf der Erde waren und von Gott geschaffen wurden.

Du bist nun in der Rolle von Gott. Erstelle eine Methode god(), die zwei Menschen Adam und Eva zurückliefert. Adam ist vom Typ Man und Eva vom Typ Woman. Sowohl Man als auch Woman sind von Human abgeleitet sind.

god.py
def god():
    "Return a man and a woman"
 
class Man:
    "A Man"
 
class Woman:
    "A Woman"
 
 
# Tests
paradise = God()
assert len(paradise) == 2
m, w = paradise
assert isinstance(m, Man)
assert isinstance(w, Woman)
assert isinstance(m, Human)
assert isinstance(w, Human)

Klasse für Geister

Erstelle eine Klasse Ghost. Sie wird ohne Parameter instanziiert und besitzt das Attribut color, das zu Beginn zufällig auf „weiß“, „gelb“ oder „rot“ gesetzt wird.

ghost.py
class Ghost:
    'A Ghost with attribute color'
 
 
# Tests
g = Ghost()
assert g.color in ["weiß", "gelb", "rot"]
 
hundred_ghosts = [Ghost() for _ in range(100)]
white_ghosts = [g for g in hundred_ghosts if g.color == "weiß"]
assert len(white_ghosts) > 10
yellow_ghosts = [g for g in hundred_ghosts if g.color == "gelb"]
assert len(yellow_ghosts) > 10
red_ghosts = [g for g in hundred_ghosts if g.color == "rot"]
assert len(red_ghosts) > 10

Klasse für Bankkonto

Erstelle für eine Bank eine Klasse User mit den folgenden Methoden:

  • withdraw method
    • Subtracts money from balance
    • One parameter, money to withdraw
    • Raise ValueError if there isn't enough money to withdraw
  • check method
    • Adds money to baleance
    • Two parameters, other user and money
    • Other user will always be valid
    • Raise a ValueError if other user doesn't have enough money
    • Raise a ValueError if checking_account isn't true for other user
  • add_cash method
    • Adds money to balance
    • One parameter, money to add
    • Return a string with name and balance(see examples)

Additional Notes:

  • Checking_account should be stored as a boolean
  • No input numbers will be negitive
  • Float numbers will not be used so, balance should be integer
  • No currency will be used
konto.py
class User:
    'Ein Kunde mit einem Konto.'
 
 
# Tests
 
jeff = User(name='Jeff', balance=70, checking_account=True)
joe = User(name='Joe', balance=70, checking_account=False)
 
jeff.withdraw(2)
assert jeff.balance == 68
 
joe.check(jeff, 50)
assert joe.balance == 120
assert jeff.balance == 18
 
try:
    jeff.check(joe, 80)  # raises ValueError
    assert False, "Value Error missing"
except ValueError:
    assert True
 
joe.checking_account = True # Enables checking for Joe
jeff.check(joe, 80) 
jeff.balance == 98
joe.balance == 40
 
try:
    joe.check(jeff, 100) # Raises a ValueError
    assert False
except ValueError:
    assert True
 
jeff.add_cash(20.00)
jeff.balance == 118

Fehler-Erzeuger

Erzeuge die folgenden Fehlermeldungen mit Hilfe kleiner Programme und erläutere, was die Ursache des Fehlers ist oder sein könnte.

  1. NameError: name 'math' is not defined
  2. TypeError: unsupported operand type(s) for +: 'int' and 'str'
  3. SyntaxError: invalid syntax
  4. IndentationError: expected an indented block
  5. AttributeError: 'Person' object has no attribute 'speed'
  6. TypeError: move_faster() missing 1 required positional argument: 'new_speed'

Exception-Erzeuger

Erstelle ein Programm, das den folgenden Stacktrace produziert. Schaffst du es auch, die korrekten Zeilennummern zu verwenden?

Traceback (most recent call last):
  File "circle.py", line 22, in <module>
    circ.area()
  File "circle.py", line 8, in area
    return self.get_radius() ** 2 * math.pi
  File "circle.py", line 11, in get_radius
    self.check_radius_sign()
  File "circle.py", line 17, in check_radius_sign
    raise Exception("Radius is negative:" + str(self.radius))
Exception: Radius is negative:-3

Schlechter Stil

Welche stilistischen Probleme erkennst du bei der folgenden Funktion?

def handleStuff(inputRec, crnQtr, empRec, estimRevenue, ytdRevenue, screenx, screeny, newColor, prevColor, status, expenseType):
	for i in range(100):
		inputRec[i] = 0
		inputRec[i] = corpExpense[ crnQtr ][ i];
 
	UpdateCorpDatabase(empRec)
	estimRevenue = ytdRevenue * 4.0 / double(crnQtr)
	newColor = prevColor
	status = SUCCESS
	if expenseType == 1:
		for i in range(12):
			profit[i] = revenue[i] - expense.type2[i]
	elif expenseType == 2:
		profit[i] = revenue[i] - expense.type2[i]
	elif expenseType == 3:
			profit[i] = revenue[i] - expense.type3[i]

Verschiedene Laufzeiten

Erstelle die Funktionen, linear(n), quadratic(n), cubic(n), exponential(n), die in Abhängigkeit von n eine lineare, quadratische, kubische oder exponentielle Laufzeit haben.

Tic Tac Toe

Ergänze eine Gewinnüberprüfung für das Spiel TicTacToe in der folgenden Klasse. Programmiere dafür die Methoden `x_wins` und `o_wins`.

ttt.py
class TicTacToe:
    'A game of tic tac toe.'
 
    def __init__(self):
        # mapping (x,y) to 'x' or 'o'
        self.stones = {}
 
    def place_x_at(self, x, y):
        assert 0 <= x <= 2 and 0 <= y <= 2
        self.stones[(x, y)] = "x"
 
    def place_o_at(self, x, y):
        assert 0 <= x <= 2 and 0 <= y <= 2
        self.stones[(x, y)] = "o"
 
    def x_wins(self):
        'Return whether player x has three in a row.'
 
    def o_wins(self):
        'Return whether player o has three in a row.'
 
 
# Tests
 
ttt = TicTacToe()
'''
o.x
xxo
x.o
'''
for x, y in [(2, 0), (1, 0), (1, 1), (0, 2)]:
    ttt.place_x_at(x, y)
for x, y in [(0, 0), (2, 1), (2, 2)]:
    ttt.place_o_at(x, y)
assert len(ttt.stones) == 7
assert ttt.x_wins()
assert not ttt.o_wins()

IBAN-Prüfsumme

Die IBAN ist eine international standardisierte Notation für Bankkontonummern. Ein Beispiel seht ihr hier.

DE68 2105 0170 0012 3456 78

Sie wird z.B. bei Überweisungen verwendet, um das Empfängerkonto anzugeben. Diese IBAN hat im vorderen Bereich zwei Prüfziffern, mit denen geprüft werden kann, ob die IBAN korrekt eingetragen wurde.

  1. Schreibe ein Programm, das eine IBAN überprüft und ausgibt, ob eine eingegebene IBAN korrekt ist oder nicht.
  2. (schwieriger) Schreibe ein Programm, dass eine Prüfziffer berechnet.

FizzBuzz Katas

Bei dem FizzBuzz-Spiel werden die Zahlen von 1 bis 100 durchlaufen. Nun können folgende Fälle eintreten:

  1. Wenn die Zahl durch 3 teilbar ist, wird „Fizz“ ausgegeben
  2. wenn sie durch 5 teilbar ist, wird „Buzz“ ausgegeben und
  3. wenn sie durch 3 und 5 teilbar ist, wird „FizzBuzz“ ausgegeben.
  4. Tritt keiner dieser Fälle ein, wird die Zahl ausgegeben.

Ob eine Zahl durch eine andere Zahl teilbar ist, kann mit Hilfe des Modulo-Operators (oder Restwert-Operator) % herausgefunden werden. Er berechnet den Divisionsrest: 10 % 3 ist 1, da 10 geteilt durch 3 genau 3 Rest 1 ergibt.

Die ersten 20 Ausgaben sehen wir folgt aus:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

Versuche das Problem nun auf unterschiedliche Arten in den folgenden Katas (Übungen) zu lösen:

  1. auf Papier
  2. mit einer Methode
  3. ohne Verwendung einer Schleife (rekursiv)
  4. mit Hilfe von nebenläufigen Threads
  5. mit einer anderen IDE
  6. in einer anderen Programmiersprache
  7. als Client-Server Anwendung
  8. mit einer grafischen Oberfläche (GUI)
  9. Objekt-Orientiert: Klassen und Objekte verwenden
  10. objekt-orientiert mit Vererbung
  11. funktional mit map, reduce und lambda-Ausdrücken
  12. als Webanwendung (mit bottle)
  13. in git-repo einchecken
  14. als installierbares Programm
  15. als getestetes Programm (mit unittest und doctests)
  16. mit einem EA-Modul ansteuern
  17. mit Anbindung an eine Datenbank
  18. mit Dokumentation
  19. als Chatbot (z.B. mit sopel https://sopel.chat/)
  20. auf einem Cluster (mit GNU parallel)
  21. in einem UML-Aktivitätsdiagramm
  22. in einem UML-Sequenzdiagramm
  23. in einem UML-Klassendiagramm
  24. Als IOT-Anwendung mit einem Message-Broker (MQTT)
  25. Mit Kommandozeilenparametern
  26. Mit einer Konfigurationsdatei
  27. Als Web-Service mit REST-API
  28. In einer MVC-Architektur
  29. Als Spiel (mit pygame)
  30. In einem docker Container
  31. Mit Fehlerbehandlung
  32. Mit einem neuronalen Netzwerk
  33. Mit logging in ein logfile
  34. Mit einem Profiler
  35. Mit einer geplotteten Visualisierung

Mögliche Lösungen für die Katas befinden sich in einem hier.

Katas im Randori-Prinzip

Ein Coding Dojo ist eine Form der gezielten kollaborativen Übung für Softwerker, bei der wir voneinander lernen und zusammen eine interessante Programmieraufgabe lösen können.

Es arbeiten immer zwei Leute an einem Computer und programmieren zusammen testgetrieben (TDD) und im Pair (Driver + Navigator). Die Zuschauer können via Beamer das Entwickeln verfolgen und den Programmierenden Anregungen und Tipps geben.
Nach ein paar Minuten (Timebox) rotieren wir weiter (Randori Prinzip):
Einer der Programmierenden kehrt ins Publikum zurück, ein weiterer Zuschauer rückt aus dem Publikum nach. So kann jeder zur Lösung beitragen und von möglichst vielen Leuten lernen.

Welches Code Kata wir wählen, also welcher Problemstellung wir uns an diesem Abend widmen, entscheiden wir gemeinsam in der Gruppe.

(Quelle: Softwerkskammer)

  • Practice Python enthält verschiedene Übungen für Anfänger.
  • Weitere Übungen zur OOP mit Python gibt es hier.
  • Project Euler ist eine Sammlung mathematischer Aufgaben und Programmierübungen für unterschiedliche Programmiersprachen. Es gibt viele Lösungen, die in einem Forum gesammelt werden.
  • Wer der englischen Sprache mächtig ist, findet bei RosettaCode eine Vielzahl von Programmieraufgaben inklusive Lösungen in vielen verschiedenen Programmiersprachen.
  • codewars enthält verschiedene Übungen für verschiedene Sprachen und einem Forum, um die Lösungen zu diskutieren.
schule/programmieruebungen.1540988835.txt.gz · Zuletzt geändert: 31.10.2018 13:27 von Marco Bakera