Mittwoch, 8. Oktober 2014
Musterlösung zu Unit-Tests
Folgende Grenzfälle werden getestet:
- 0 Elemente aufnehmen, Anzahl muss gleich bleiben
- 0 Elemente löschen, Anzahl muss gleich bleiben
- negative Anzahl Elemente aufnehmen, Exception
- negative Anzahl Elemente löschen, Exception
- nicht vorhandenes Element löschen, Exception
- 10 Elemente aufnehmen, Anzahl testen
- 10 Elemente aufnehmen, Ergebnis des Iterators testen
Die Artikel (Elemente/Items) werden in der Reihenfolge und der gegebenen Anzahl gespeichert, als
addItems() aufgerufen wurde. Wird ein Element
mit der Anzahl 5 in den Warenkorb aufgenommen, so wird das Element 5 mal
gespeichert.Testklasse:
Die Kommentare wurden für diesen Beitrag weggelassen, da die Klasse ohnedies schon sehr lange ist.
import java.util.Iterator;
import junit.framework.TestCase;
public class ShoppingCartTest extends TestCase {
private ShoppingCart cart;
private ItemCount itemCount;
private Item[] items = { new Item(1), new Item(2), new Item(3) };
protected void setUp() throws Exception {
cart = new MyCart();
itemCount = (ItemCount) cart;
}
protected void tearDown() throws Exception {
}
public void testAddItems0() {
try {
cart.addItems(items[0], 0);
assertEquals("testDeleteItems0: 0 Elemente", 0, cart.itemCount());
} catch (NegativeCountException e) {
fail("testAddItem0: es dürfte keine NegativeCountException"
+ " geworfen werden");
}
}
public void testAddItemNegativ() {
try {
cart.addItems(items[0], -23);
fail("testAddItemNegativ: es müsste eine NegativeCountException"
+ " geworfen werden");
} catch (NegativeCountException e) {
}
}
public void testDeleteItems0() {
try {
cart.addItems(items[0], 1);
cart.deleteItems(items[0], 0);
assertEquals("testDeleteItems0: 1 Element", 1, cart.itemCount());
} catch (NegativeCountException e) {
fail("testDeleteItems0: es dürfte keine NegativeCountException"
+ " geworfen werden");
} catch (NoSuchItemException e) {
fail("testDeleteItems0: es dürfte keine NoSuchItemException"
+ " geworfen werden");
}
}
public void testDeleteItemsNoSuchItem() {
try {
cart.addItems(items[0], 1);
cart.deleteItems(items[1], 1);
fail("testDeleteItemsNoSuchItem: es müsste NoSuchItemException"
+ " geworfen werden");
} catch (NegativeCountException e) {
fail("testDeleteItemsNoSuchItem: es dürfte keine"
+ " NegativeCountException geworfen werden");
} catch (NoSuchItemException e) {
assertEquals("testDeleteItemsNoSuchItem: 1 Element", 1,
cart.itemCount());
}
}
public void testDeleteItemNegativ() {
try {
cart.addItems(items[0], 2);
cart.deleteItems(items[0], -23);
fail("testAddItemNegativ: es müsste eine NegativeCountException"
+ " geworfen werden");
} catch (NegativeCountException e) {
} catch (NoSuchItemException e) {
fail("testAddItemNegativ: es dürfte keine NoSuchItemException"
+ " geworfen werden");
}
}
public void testAddItems10() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[2], 4);
assertEquals("testAddItems10: 10 Elemente", 10, cart.itemCount());
} catch (NegativeCountException e) {
fail("testAddItems10: es dürfte keine NegativeCountException"
+ " geworfen werden");
}
}
public void testAddDeleteItems5() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[2], 4);
cart.deleteItems(items[0], 2);
cart.deleteItems(items[2], 2);
cart.deleteItems(items[1], 1);
assertEquals("testAddDeleteItems5: 5 Elemente", 5, cart.itemCount());
} catch (NegativeCountException e) {
fail("testAddDeleteItems5: es dürfte keine NegativeCountException"
+ " geworfen werden");
} catch (NoSuchItemException e) {
fail("testAddDeleteItems5: es dürfte keine NoSuchItemException"
+ " geworfen werden");
}
}
public void testIterator() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[2], 4);
Iterator<Item> iterator = cart.iterator();
int cntItems = 0;
Item[] stroredItems = new Item[10];
while (iterator.hasNext()) {
stroredItems[cntItems] = iterator.next();
cntItems++;
}
assertEquals("testIterator: 10 Elemente", 10, cntItems);
for (int i = 0; i < 3; i++) {
assertEquals("testIterator: Element sollte gleich sein",
items[0], stroredItems[i]);
System.out.println(stroredItems[i]);
}
for (int i = 3; i < 6; i++) {
assertEquals("testIterator: Element sollte gleich sein",
items[1], stroredItems[i]);
System.out.println(stroredItems[i]);
}
for (int i = 6; i < 10; i++) {
assertEquals("testIterator: Element sollte gleich sein",
items[2], stroredItems[i]);
System.out.println(stroredItems[i]);
}
} catch (NegativeCountException e) {
fail("testIterator: es dürfte keine NegativeCountException"
+ " geworfen werden");
}
}
public void testItemCount() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[0], 1);
cart.addItems(items[2], 4);
cart.addItems(items[0], 2);
assertEquals("testItemCount: Anzahl falsch", 6,
itemCount.itemCount(items[0]));
assertEquals("testItemCount: Anzahl falsch", 3,
itemCount.itemCount(items[1]));
assertEquals("testItemCount: Anzahl falsch", 4,
itemCount.itemCount(items[2]));
} catch (NegativeCountException e) {
fail("testItemCount: es dürfte keine NegativeCountException"
+ " geworfen werden");
} catch (NoSuchItemException e) {
fail("testItemCount: es dürfte keine NoSuchItemException"
+ " geworfen werden");
}
}
public void testItemCountNosuchItem() {
@SuppressWarnings("unused")
int cnt;
try {
cnt = itemCount.itemCount(items[0]);
fail("testItemCountNosuchItem: es müsste eine NoSuchItemException"
+ " geworfen werden");
} catch (NoSuchItemException e) {
}
try {
cart.addItems(items[1], 3);
cnt = itemCount.itemCount(items[0]);
fail("testItemCountNosuchItem: es müsste eine NoSuchItemException"
+ " geworfen werden");
} catch (NegativeCountException e) {
fail("testItemCountNosuchItem: es dürfte keine"
+ " NegativeCountException geworfen werden");
} catch (NoSuchItemException e) {
}
}
}
Implementierung des Interfaces ShoppingCart:
Zusätzlich zur originalen Aufgabenstellung wurde noch folgendes Interface implementiert, damit man einfach die Anzahl eines bestimmten Items bestimmen kann:
public interface ItemCount {
public int itemCount(Item anItem) throws NoSuchItemException;
}
Zur Speicherung der
Items wird einfach eine ArrayList verwendet.
import java.util.ArrayList;
import java.util.Iterator;
public class MyCart implements ShoppingCart, ItemCount {
private ArrayList<Item> items = new ArrayList<Item>();
public void addItems(Item anItem, int quantity)
throws NegativeCountException {
if (quantity < 0) {
throw new NegativeCountException();
}
for (int i = 0; i < quantity; i++) {
items.add(anItem);
}
}
public void deleteItems(Item anItem, int quantity)
throws NegativeCountException, NoSuchItemException {
if (quantity < 0) {
throw new NegativeCountException();
}
for (int i = 0; i < quantity; i++) {
if (!items.remove(anItem))
throw new NoSuchItemException();
}
}
public int itemCount() {
return items.size();
}
public Iterator<Item> iterator() {
return items.iterator();
}
@Override
public int itemCount(Item anItem) throws NoSuchItemException {
int cnt = 0;
if (!items.contains(anItem)) {
throw new NoSuchItemException();
}
for (Item item : items) {
if (item == anItem) {
cnt++;
}
}
return cnt;
}
}
Weiters müssen natürlich die geforderten Exceptions implementiert werden (Kommentare wurden auch hier weggelassen):
public class NegativeCountException extends Exception {
}
public class NoSuchItemException extends Exception {
}
Die Klasse für die Artikel (
Item) wurde einfach durch eine Nummer ergänzt, die beim Konstruktor angegeben werden muss. Für eine realistische Anwendung müsste diese Klasse noch erweitert werden:
public class Item {
private int itemNr = 0;
public Item(int itemNr) {
this.itemNr = itemNr;
}
@Override
public String toString() {
return "Item " + itemNr;
}
}
Labels: Java, Lösung, POS1-3, Testen
Montag, 18. November 2013
Musterlösung Römische Zahlen umwandeln (POS1: 2BHIF)
Mögliche Lösung zu Römische Zahlen umwandeln (POS1: 2BHIF).
Die Klasse könnte folgendermaßen programmiert werden. Das Dictionary enthält die möglichen "Ziffern" (unter Hochkomma, da bestimmte Ziffernkombinationen, wie zum Beispiel "IX", als eine Ziffer gelten). Zur Umrechnung müssen die Werte absteigend sortiert werden, damit die richtige "Ziffer" (z.B. "IX" für 9) verwendet wird.
Bei der Umrechnung in römische Zahlen wird der Reihe nach von der größten zur kleinsten "Ziffer" (daher absteigend sortiert) probiert, ob der Wert enthalten ist. Ist das der Fall, dann wird die "Ziffer" an den String angehängt und der entsprechende Wert von der Zahl abgezogen. Zum Beispiel 1999
1999 M 999 IM 0 ferigoder 392
392 C 292 C 192 C 92 XC 2 I 1 I 0 fertig
Bei der umgekehrten Umrechnung wird der Reihe nach probiert, ob am Beginn der römischen Zahl eine bestimmte "Ziffer" vorkommt. Ist dies der Fall, so wird der entsprechende Wert zum Ergebnis dazugezählt. Mit einem Zähler wird geprüft, dass keine Ziffer mehr als drei mal vorkommt. Zum Beispiel CCCXCII
CCCXCII 100 (C) CCXCII 200 (C) CXCII 300 (C) XCII 390 (XC) II 391 (I) I 392 (I)
Zum Testen wird einfach eine Liste von Zahlen verwendet, die in römische Zahlen und wieder zurück gerechnet werden. Ungültige Zahlen liefern eine Exception, die bei einem entsprechenden Testfall kommen muss:
# test value error
try:
ra = RomanNumber("VIIII")
assert(False)
except ValueError:
pass
Die gesamte Klasse könnte also so aussehen:
#!/usr/bin/env python3
"""
File: RomanNumber.py
Desc: class for roman numbers
Created: 2013-11-18, Harald R. Haberstroh
"""
class RomanNumber:
"""Roman numbers.
Internal representation is always the integer value.
This implementation stores both values (integer and roman).
"""
digits = { "I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000,
"IV":4, "IX":9, "XL":40, "XC":90, "CD":400, "CM":900}
keys = list(digits.items())
keys.sort(key=lambda x: -x[1])
def __init__(self, value):
"""Initialize with value.
If type of value is int, than this is the integer value.
If type of value is str, than this is a roman number, which has
to be converted into the internal int-value"""
if type(value) is str:
self.roman = value
self.intval = self.__toInt(value)
else:
self.intval = value
self.roman = self.__toRoman(value)
def toRoman(self):
"""returns string with roman representation"""
return self.roman
def toInt(self):
"""returns integer value of roman number"""
return self.intval
def add(self, other):
"""add the value of other (RomanNumber) to own (self) value and
return a new RomanNumber object."""
return RomanNumber(self.intval + other.toInt())
def sub(self, other):
"""subtract the value of other (RomanNumber) from own (self) value and
return a new RomanNumber object."""
return RomanNumber(self.intval - other.toInt())
def mul(self, other):
"""multiply the value of other (RomanNumber) with own (self) value and
return a new RomanNumber object."""
return RomanNumber(self.intval * other.toInt())
def div(self, other):
"""divide (integer division) own value by the value of other value and
return a new RomanNumber object."""
return RomanNumber(self.intval // other.toInt())
def __str__(self):
"""returns the same value as toRoman(self)"""
return "%s (%d)" % (self.roman, self.intval)
def __toRoman(self, intval):
romval = ""
for digit, val in self.keys:
while intval >= val:
romval += digit
intval -= val
return romval
def __toInt(self, romval):
roman = romval.upper()
intval = 0
for digit, val in self.keys:
cntDigit = 0 # count same group
while roman.startswith(digit):
intval += val
roman = roman[len(digit):]
cntDigit += 1
if cntDigit >= 4:
raise ValueError()
return intval
if __name__ == '__main__':
zahlen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 21, 32, 43, 48, 49, 54, 65, 76, 87, 98,
99, 100, 201, 302, 403, 491, 499, 504, 605, 706, 807, 908, 999, 1001,
1279, 1331, 1496, 1883, 1949, 1967, 1990, 1999, 2006, 2013]
for f in zahlen:
rn = RomanNumber(f)
# print('%4d: %20s - %4d' % (f, rn.toRoman(), rn.toInt()))
assert(f == rn.toInt())
for i in range(len(zahlen) // 2):
ra = RomanNumber(zahlen[i])
rb = RomanNumber(zahlen[-i])
rc = ra.add(rb)
print(ra, "+", rb, "=", rc)
assert(zahlen[i] + zahlen[-i] == rc.toInt())
rc = rb.sub(ra)
print(rb, "-", ra, "=", rc)
assert(zahlen[-i] - zahlen[i] == rc.toInt())
for i in range(len(zahlen) // 8):
ra = RomanNumber(zahlen[i])
rb = RomanNumber(zahlen[len(zahlen) // 2 - i])
rc = ra.mul(rb)
print(ra, "*", rb, "=", rc)
assert(zahlen[i] * zahlen[len(zahlen) // 2 - i] == rc.toInt())
# test value error
try:
ra = RomanNumber("VIIII")
assert(False)
except ValueError:
pass
print("all tests passed")
Beim romancalc.py wird jeder Schritt mit einem try - except - Block umgeben, um die Fehler- und Sonderfälle zu behandeln.
Eine Spezialität ist der Aufruf des entsprechenden Operators. Hier wird ein Dictionary mit den möglichen Operationen verwendet, wobei der Aufruf als Funktion und nicht als Methode stattfindet (der erste Parameter self enthält ja das Objekt, welches dann explizit mit übergeben wird).
Das gesamte Modul könnte wie folgt aussehen:
#!/usr/bin/env python3
"""
File: romancalc.py
Desc: simple caluculator for roman numbers, using RomanNumber
Created: 2013-11-18, Harald R. Haberstroh
"""
from RomanNumber import RomanNumber
import sys
operators = { "+":RomanNumber.add, "-":RomanNumber.sub,
"*":RomanNumber.mul, "/":RomanNumber.div }
while True:
try:
line = input(">>> ")
except EOFError:
break
try:
a, op, b = line.split()
except ValueError:
print("syntax error", file=sys.stderr)
continue
if a.isdigit():
a = int(a)
if b.isdigit():
b = int(b)
try:
ra = RomanNumber(a)
rb = RomanNumber(b)
except ValueError:
print("invalid roman number", file=sys.stderr)
continue
try:
rc = operators[op](ra, rb)
print(ra, op, rb, "=", rc)
except KeyError:
print("invalid operator '%s'" % (op), file=sys.stderr)
Labels: Aufgabe, Lösung, POS1-2, Python
Mittwoch, 9. Oktober 2013
Musterlösung zu Aufgabe 2 "Denksport mit Python, erste Anwendung von Mercurial" (POS1: 2BHIF)
#!/usr/bin/env python3
"""
File: pythagorean_triple.py
Desc: Ein Programm zur Bestimmung eines pythagoräischen Tripel (a2+b2=c2
für a < b < c), wobei a+b+c == 1000.
Created: 2013-09-23, Harald R. Haberstroh
"""
from sys import argv
from math import sqrt
if __name__ == '__main__':
summe = 1000
if len(argv) == 2:
summe = int(argv[1])
for a in range(1, summe // 3):
for b in range(a + 1, summe // 2):
a2 = a * a
b2 = b * b
c2 = a2 + b2
c = sqrt(c2)
if a < b < c and a + b + c == summe:
print(a, b, int(c))
print(int(a * b * c))
#!/usr/bin/env python3
"""
File: sumdigits2pow1000.py
Desc: calculate the sum of the digits of 2**1000 (exponent can be changed
with commandline argument)
Created: 2013-09-23, Harald R. Haberstroh
"""
from sys import argv
if __name__ == '__main__':
if len(argv) == 2:
exponent = int(argv[1])
else:
exponent = 1000
print(sum(list(map(int, list(str(2 ** exponent))))))
#!/usr/bin/env python3
"""
File: sumdigitsfact.py
Desc: calculate the sum of the digits of 100! (100 can be changed
with commandline argument)
Created: 2013-09-23, Harald R. Haberstroh
"""
from sys import argv
def fact(n):
"""n!"""
f = 1
for i in range(1, n + 1):
f *= i
return f
if __name__ == '__main__':
if len(argv) == 2:
n = int(argv[1])
else:
n = 100
print(sum(list(map(int, list(str(fact(n)))))))
Die Palindrom-Beispiele sind ganz ähnlich und wurden daher in ein Programm gepackt, bei dem man als Parameter auf der Kommandozeile die Anzahl der Stellen angeben kann (4, 6, 8). Zusätzlich kann noch '-l' angegeben werden, um eine Liste der Produkte zu erhalten. Die Ergebnisliste ist nicht ganz vollständig, denn es wird das Ergebnis des Produkts als Schlüssel verwendet. Damit gehen Lösungen wie zum Beispiel 111111 = 143 * 777 = 231 * 481 = 259 * 429 verloren.
#!/usr/bin/env python3
"""
File: palindrome.py
Desc: largest palindrome of product of two n/2-digit numbers with n digits
Created: 2013-09-23, Harald R. Haberstroh
"""
from sys import argv
def checkPalindrom(s):
"""
checks whether string is a palindrome
"""
l = len(s)
for i in range(l // 2):
if s[i] != s[l - i - 1]:
return False
return True
def genPalindrom(n):
"""
build palindrome out of products
"""
# Dictionary only for list of palindromes not for maximum
palindromes = {}
products = []
maxPalindrome = 0
maxPalindromeFactors = ""
for i in range(10**((n - 1) // 2), 10 ** (n // 2)):
for j in range(10**((n - 1) // 2), 10 ** (n // 2)):
product = str(i * j)
if checkPalindrom(product):
if not product in palindromes:
palindromes[product] = str(i) + " * " + str(j) + " = " + product
products.append(product)
if int(product) > maxPalindrome:
maxPalindrome = int(product)
maxPalindromeFactors = str(i) + " * " + str(j) + " = " + product
return maxPalindromeFactors, palindromes
if __name__ == '__main__':
n = 2
if len(argv) > 1:
n = int(argv[1])
maxPalindrome, palindromes = genPalindrom(n)
if "-l" in argv:
lstPalindromes = list(palindromes.values())
lstPalindromes.sort()
for palindrome in lstPalindromes:
print(palindrome)
print("largest palindrome: %s" % maxPalindrome)
Labels: Lösung, POS1-2, Python
Musterlösung zu Wiederholung Python (POS1: 2BHIF)
"""
text_analyzer.py
Task 1: Repeat previous material (1st class)
2012-09-10, Harald R. Haberstroh (hp@htlwrn.ac.at)
"""
def input_sentences():
'''returns al list of sentences/lines'''
lst = []
eof = False
while not eof:
try:
line = input("Satz: ")
lst.append(line)
except EOFError:
eof = True
return lst
def _remove_punctuation(string):
'''helper removes all punctuation marks within string'''
for punctuation in '''"',;.:-''':
string = string.replace(punctuation, " ")
return string
def split_sentences(lst):
'''split a list (lst) of sentences into list of list of words'''
wordlist = []
for sentence in lst:
wordlist.append(_remove_punctuation(sentence).split())
return wordlist
def purge_bad_words(lst):
'''remove all bad words (length less than 2 chars, words
containing non alphabetic chars)
'''
for sublist in lst:
idx = 0
while idx < len(sublist):
if not len(sublist[idx]) >= 2 or not sublist[idx].isalpha():
del(sublist[idx])
else:
idx += 1
return lst
def analyze_words(lst):
'''returns a dictionary of words (with the number of occurrences)
of the list of list of words'''
dict = {}
for sublist in lst:
for word in sublist:
word = word.lower()
if word in dict:
dict[word] += 1
else:
dict[word] = 1
return dict
def analyze_letters(lst):
'''returns a dictionary of letters (with the number of occurrences)
of the list of list of words'''
dict = {}
for sublist in lst:
for word in sublist:
for char in word.lower():
if char in dict:
dict[char] += 1
else:
dict[char] = 1
return dict
def purge_analyzed_letters(dic):
'''remove umlauts'''
for umlaut in "äöüß":
if umlaut in dic:
del(dic[umlaut])
return dic
def _key(tupl):
'''returns 2nd element of tuple for sorting'''
return tupl[1]
def sort_letters(dic):
'''returns a sorted list of tuples of letters, sorted by
number of letters'''
tuples = list(dic.items())
tuples.sort(key=_key, reverse=True)
return tuples
def test_input():
'''returns a fixed list of sentences for testing purposes'''
return ['Maxi und Mini verliefen sich im Wald, aber bald.',
'10 alte Fledermäuse flogen im Wald',
'Hat die alte Meisterhexe...',
"Seid's gewesen. Denn als Geister...",
'Erst hervor der alte Meister.']
if __name__ == '__main__':
#lst = input_sentences()
lst = test_input()
print('split_sentences(lst)')
wordlist = split_sentences(lst)
print(wordlist)
print('\npurge_bad_words(wordlist)')
wordlist = purge_bad_words(wordlist)
print(wordlist)
print('\nanalyze_words(wordlist)')
print(analyze_words(wordlist))
print('\nanalyze_letters(wordlist)')
dic = analyze_letters(wordlist)
print(dic)
print('\npurge_analyzed_letters(dic)')
dic = purge_analyzed_letters(dic)
print(dic)
print('\nsort_letters(dic)')
sorted_letters = sort_letters(dic)
print(sorted_letters)
print('\n\n*** task 9 ***\n')
print('''"abcdef".index("c")''') # ValueError: substring not found
print('''ValueError: substring not found''')
print('''"abcdef".index("g")''') # ValueError: substring not found
print('''ValueError: substring not found''')
print('''"abcdef".index("de")''')
print("abcdef".index("de"))
print('''"c" in "abcdef" ''')
print("c" in "abcdef")
print('''"g" in "abcdef" ''')
print("g" in "abcdef")
print('''"de" in "abcdef" ''')
print("de" in "abcdef")
print('''"abcdef"[2:4]''')
print("abcdef"[2:4])
print('''"abcdef"[2:]''')
print("abcdef"[2:])
print('''"abcdef"[-1]''')
print("abcdef"[-1])
print('''"abcdef"[2:-1]''')
print("abcdef"[2:-1])
print('''[1, 2, 3, 4, 5].index(3)''')
print([1, 2, 3, 4, 5].index(3))
print('''[1, 2, 3, 4, 5].index(9)''') # ValueError: 9 is not in list
print('''ValueError: 9 is not in list''')
print('''[1, 2, 3, 4, 5][5]''') # IndexError: list index out of range
print('''IndexError: list index out of range''')
print('''[1, 2, 3, 4, 5][2:4]''')
print([1, 2, 3, 4, 5][2:4])
print('''[1, 2, 3, 4, 5][-2]''')
print([1, 2, 3, 4, 5][-2])
print('''[1, 2, 3, 4, 5][5:9]''')
print([1, 2, 3, 4, 5][5:9])
print('''[1, 2, 3, 4, 5][4:]''')
print([1, 2, 3, 4, 5][4:])
print('''len("abc") + len(range(3)) + len({1, 2, 3}) + len({1: 2, 2: 3})''')
print(len("abc") + len(range(3)) + len({1, 2, 3}) + len({1: 2, 2: 3}))
Labels: Lösung, POS1-2, Python
Donnerstag, 4. Juli 2013
XML Datei aus einer ZIP-Datei mit Python ändern und wieder zurückschreiben (Hack für Probleme mit K3B und diversen MP3-Playern)
Mit k3b erzeuge ich ein neues Projekt, in dem ich die Songs in der Reihenfolge, die ich haben will hinzufüge. Dann speichere ich das Projekt und lasse die Dateinamen durch das Script in der Projektdatei ändern. Dann lade ich das Projekt und brenne die CD. Die Lieder sind dann in der richtigen Reihenfolge, weil die Namen mit einer Nummer wie hier 001 - Lied.mp3 versehen werden.
#!/usr/bin/env python
"""
change entries so that they are sorted by name used with k3b-data CDs (mp3
CDs).
Procedure:
1. make k3p project and add files.
2. save this project
3. close the project (leave k3b open)
4. run this script: numbermymp3.py your_project_name.k3p
4. load the project again.
5. as you can see, the files ar starting with 3-digit numbers preserving
the original order when adding the files.
2013-07-04, Harald R. Haberstroh
"""
import sys
import codecs
import zipfile
from xml.dom import minidom
def getfiles(zipfilename):
"""get dictionary filename:data with all files in zipfile"""
zf = zipfile.ZipFile(zipfilename)
files = {}
for info in zf.infolist():
files[info.filename] = zf.read(info.filename)
return files
def process(xmlstr):
"""process xml with file entries and change 'name' attribute according
to number of file (starting with 001)."""
xmldoc = minidom.parseString(xmlstr)
names = xmldoc.getElementsByTagName('file')
num = 1
for name in names:
numstr = "%03d" % num
name.attributes['name'].value = numstr + ' - ' + \
name.attributes['name'].value
num += 1
return xmldoc.toprettyxml().encode('utf-8')
def genzipfile(zipfilename, files):
"""generate new zipfile (k3b-file) with dict 'files' which has file name as
key and the content as data"""
zf = zipfile.ZipFile(zipfilename, mode='w')
try:
for name in files:
zf.writestr(name, files[name])
finally:
zf.close()
def main():
"""all to gether now"""
if len(sys.argv) != 2:
print "usage: " + sys.argv[0] + " k3b_project_name.k3b"
print "renames files so that the order is the same as in the project"
sys.exit(1)
fname = sys.argv[1]
files = getfiles(fname)
text = process(files['maindata.xml'])
files['maindata.xml'] = text
genzipfile(fname, files)
if __name__ == '__main__':
main()
Donnerstag, 10. März 2011
Lösungen zu "Übungsbeispiele zu Sequenzen, Schleifen und Funktionen in Python" (POS1: 1B)
return sondern mehrere Ausgänge haben. Um das zu verdeutlichen, beachten Sie folgendes Beispiel:def isint(string):
"""prüft, ob der String eine ganze Zahl ist (Vorzeichen optional,
nur Ziffern).
Prüfe nur Ziffernbereich."""
if len(string) > 0:
if string[0] == '+' or string[0] == '-':
for c in string[1:]:
if c < '0' or c > '9':
return False
else:
for c in string:
if c < '0' or c > '9':
return False
else:
return False
return True
Hier erfolgt ein return False aus den Schleifen über den String string, sobald ein Fehler gefunden wurde. Das vereinfacht den Algorithmus, widerspricht aber der strukturierten Programmierung, die bei Funkionen nur einen Ausgang erlaubt (bei Schleifen gilt das auch, die Schleife verlässt man nur durch die Schleifenbedingung, nicht durch break oder eben return). Beim Debuggen größerer Systeme ist es von Vorteil, wenn man sich darauf verlassen kann, dass jede Funktion nur einen Ausgang hat, denn man braucht dann nur diesen einen beobachten und nicht mehrere.Bei obigem Beispiel müsste man
while-Schleifen verwenden:def isint(string):
"""prüft, ob der String eine ganze Zahl ist (Vorzeichen optional,
nur Ziffern).
Prüfe nur Ziffernbereich."""
ok = True
if len(string) > 0:
if string[0] == '+' or string[0] == '-':
i = 1
while ok and i < len(string):
if string[i] < '0' or string[i] > '9':
ok = False
i += 1
else:
i = 0
while ok and i < len(string):
if string[i] < '0' or string[i] > '9':
ok = False
i += 1
else:
ok = False
return ok
Diese Variante könne man noch "vereinfachen", weil sich die beiden Zweige mit oder ohne Vorzeichen nur im Startwert der Laufvariable i unterscheiden:def isint(string):
"""prüft, ob der String eine ganze Zahl ist (Vorzeichen optional,
nur Ziffern).
Prüfe nur Ziffernbereich."""
ok = True
if len(string) > 0:
if string[0] == '+' or string[0] == '-':
i = 1
else:
i = 0
while ok and i < len(string):
if string[i] < '0' or string[i] > '9':
ok = False
i += 1
else:
ok = False
return ok
Die "nicht strukturierte" Variante ist aber bei weitem schneller entwickelt und durch die automatischen Tests ist auch sichergestellt, dass sie funktioniert.Die Tests verwenden
assert(), um die Ergebnisse mit den erwarteten Ergebnissen zu vergleichen. assert() bricht das Programm auf der Stelle ab, wenn die Bedingung nicht erfüllt ist. Dadurch hat man die Möglichkeit, den Fehler einzugrenzen. Passt die Bedingung, so läuft das Programm einfach weiter."""
author: Haberstroh, Harald
matnr: d09666
file: sequenzenbeispiele.py
desc: Beispiele einfacher Funktionen mit Sequenzen (vgl. Programmierblog)
Einige Funktionen bauen auf den anderen auf.
Zu jeder Funktion (ausgenommen Hilfsfunktion) gibt es eine Testfunktion
die die jeweilige Funktion mit Testwerten prüft.
Die Funktion assert() prüft den Wahrheitswert des Parameters. Ist dieser
True, so läuft das Programm einfach weiter. Ist er jedoch False, wird
das Programm mit einer Fehlermeldung und Zeilennummer abgebrochen.
Man kann dadurch feststellen, welcher Test nicht funktioniert hat.
date: 7.3.2011
class: Lehrer
catnr: 33
"""
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isint(string):
"""prüft, ob der String eine ganze Zahl ist (Vorzeichen optional,
nur Ziffern).
Prüfe nur Ziffernbereich."""
if len(string) > 0:
if string[0] == '+' or string[0] == '-':
for c in string[1:]:
if c < '0' or c > '9':
return False
else:
for c in string:
if c < '0' or c > '9':
return False
else:
return False
return True
def test_isint():
assert(isint("") == False)
assert(isint("a") == False)
assert(isint("1a") == False)
assert(isint("a1") == False)
assert(isint("1+1") == False)
assert(isint("1+") == False)
assert(isint("1") == True)
assert(isint("+1") == True)
assert(isint("-1") == True)
assert(isint("11212") == True)
assert(isint("-11212") == True)
assert(isint("+11212") == True)
print("test_isint() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isintb(string, basis):
"""prüft, ob der String eine ganze Zahl zur Basis basis ist (Vorzeichen
optional, nur Ziffern).
Baue String mit gültigen Zeichen zusammen und prüfe dann, ob jedes
Zeichen in diesem String vorkommt."""
if basis > 1:
gueltig = "" # "Liste" der gültigen Zeichen für geg. Basis
if basis > 10: # Ziffern und Buchstaben (immer groß und klein)
for z in range(10):
gueltig += chr(z + ord('0'))
for z in range(basis - 10):
gueltig += chr(z + ord('a')) # Kleinbuchstabe
gueltig += chr(z + ord('A')) # Großbuchstabe
else: # nur Ziffern
for z in range(basis):
gueltig += chr(z + ord('0'))
if len(string) > 0:
if string[0] == '+' or string[0] == '-': # Vorzeichen
for c in string[1:]:
if c not in gueltig:
return False
else:
for c in string:
if c not in gueltig:
return False
else:
return False
else:
return False
return True # alles OK
def test_isintb():
assert(isintb("", 2) == False)
assert(isintb("a", 2) == False)
assert(isintb("1a", 2) == False)
assert(isintb("a1", 2) == False)
assert(isintb("1+1", 2) == False)
assert(isintb("1+", 2) == False)
assert(isintb("1", 2) == True)
assert(isintb("+1", 2) == True)
assert(isintb("-1", 2) == True)
assert(isintb("11212", 2) == False)
assert(isintb("-11212", 2) == False)
assert(isintb("+11212", 2) == False)
assert(isintb("11212", 3) == True)
assert(isintb("-11212", 3) == True)
assert(isintb("+11212", 3) == True)
assert(isintb("aBCdeF", 16) == True)
assert(isintb("-aBCdeF", 16) == True)
assert(isintb("+aBCdeF", 16) == True)
print("test_isintb() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sumdigits(zahl):
"""Berechnet die Ziffernsumme aus der gegebenen Zahl (int)"""
sum = 0
while zahl != 0:
sum += zahl % 10 # Rest ist immer Einerstelle
zahl = zahl // 10
return sum
def test_sumdigits():
assert(sumdigits(0) == 0)
assert(sumdigits(1) == 1)
assert(sumdigits(7) == 7)
assert(sumdigits(10) == 1)
assert(sumdigits(11) == 2)
assert(sumdigits(123) == 6)
assert(sumdigits(1010) == 2)
print("test_sumdigits() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def wert_der_ziffer(ziffer):
"""liefert den Wert der Ziffer ziffer (0..9, bzw. A, B, C, ...)"""
if ord(ziffer) <= ord("9"):
wert = ord(ziffer) - ord("0")
else:
wert = ord(ziffer) - ord("A") + 10
return wert
def horner(zahl, basis):
"""berechnet Dezimalzahl aus zahl (String) zur Basis basis.
liefert Zahl. Hornerschema!"""
dez = 0
for ziffer in zahl:
dez *= basis
dez += wert_der_ziffer(ziffer)
return dez
def test_horner():
assert(horner("", 10) == 0)
assert(horner("1", 10) == 1)
assert(horner("12", 10) == 12)
assert(horner("123", 10) == 123)
assert(horner("1", 2) == 1)
assert(horner("10", 2) == 2)
assert(horner("11", 2) == 3)
assert(horner("4", 16) == 4)
assert(horner("A", 16) == 10)
assert(horner("10", 16) == 16)
print("test_horner() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isipv4(string):
"""Prüft, ob der gegebene String eine IPv4-Adresse enthält.
IPv4-Adressen sind 4 Zahlen zwischen 0 und 255, die durch einen
Punkt getrennt sind.
Beispiele: 127.0.0.1, 193.170.149.129, 81.200.64.185
Ungültige: 81.2010.64.185, 123.23.12, 127,0,0,1"""
zahl = ""
anzpunkte = 0
anzziffer = 0
for z in string:
if '0' <= z <= '9':
zahl += z
anzziffer += 1
elif z == '.' and anzziffer > 0: # mindestens 1 Ziffer vor Zahl
if not (0 <= horner(zahl, 10) <= 255):
return False
zahl = "" # neu beginnen
anzziffer = 0
anzpunkte += 1
else:
return False
if anzpunkte == 3 and anzziffer > 0: # nach 3. Punkt eine Zahl!
if not (0 <= horner(zahl, 10) <= 255):
return False
return True
else:
return False
def test_isipv4():
assert(isipv4("127.0.0.1"))
assert(isipv4("193.170.149.129"))
assert(isipv4("81.200.64.185"))
assert(not isipv4(""))
assert(not isipv4("81.2010.64.185"))
assert(not isipv4("123.23.12"))
assert(not isipv4("123.23.12."))
assert(not isipv4("123.23.12.3.3"))
assert(not isipv4("123.23.12.3."))
assert(not isipv4("127,0,0,1"))
print("test_isipv4() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def anz_zahlen(string):
"""ermittelt die Anzahl der ganzen Zahlen im String"""
anzahl = 0
in_zahl = False
for zeichen in string:
if zeichen in "0123456789":
if not in_zahl:
anzahl += 1
in_zahl = True
else:
in_zahl = False
return anzahl
def test_anz_zahlen():
string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123"
assert(4 == anz_zahlen(string))
assert(0 == anz_zahlen("keine"))
assert(1 == anz_zahlen("eine Zahl 123"))
assert(2 == anz_zahlen("zwei 23 und 324"))
assert(3 == anz_zahlen("drei 23 34 22"))
assert(4 == anz_zahlen("vier 234 234 234 45"))
assert(5 == anz_zahlen("5 234 234 234 45"))
print("test_anz_zahlen() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sum_zahlen(string):
"""ermittelt die Summe der ganzen Zahlen im String. Eine Zahl
ist eine ununterbrochene Folge von Ziffern.
Beispiel: sum_zahlen("x 34 3 12k33 44 hallo 23") liefert 149"""
summe = 0
zahl = ""
for zeichen in string:
if zeichen in "0123456789":
zahl += zeichen
else:
summe += horner(zahl, 10) # umrechnen und dazuzählen
zahl = "" # neu beginnen
if len(zahl) > 0: # zuletzt war Zahl, daher dazurechnen
summe += horner(zahl, 10)
return summe
def test_sum_zahlen():
string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123"
assert(26460 == sum_zahlen(string))
assert(0 == sum_zahlen("keine"))
assert(123 == sum_zahlen("eine Zahl 123"))
assert(347 == sum_zahlen("zwei 23 und 324"))
assert(79 == sum_zahlen("drei 23 34 22"))
assert(747 == sum_zahlen("vier 234 234 234 45"))
assert(752 == sum_zahlen("5 234 234 234 45"))
print("test_sum_zahlen() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def iskonto(string):
"""Prüft, ob der String eine gültige Kontonummer enthält. Dabei
gelten folgende Regeln:
1. genau 9 Ziffern (es dürfen Leerzeichen dazwischen sein
2. die letzte Ziffer ist eine Prüfziffer und es gilt
Die Kontonummer ist genau 9 Stellen lang und ist dann richtig,
wenn die folgendermaßen gebildete Summe auf Null endet:
Ziffern mit ungeradem Index werden addiert(=Teilsumme1);
Ziffern mit geradem Index werden verdoppelt und das jeweilige
Produkt addiert, wenn es einstellig ist, andernfalls wird die
Quersumme des Produkts addiert(=Teilsumme2);
Summe= teilsumme1 + Teilsumme2
Beispiel:
123456782 1+ 3+ 5+ 7+ 2 = 18 Teilsumme1
2*2+ 4*2+ (1+2)+ (1+6) = 22 Teilsumme2
6*2=12 8*2=16
------
40 Summe mod 10= Null
Beispiele für Kontonummern:
697199107 richtige Kontonummer
723016689 richtige Kontonummer
723016699 falsche Kontonummer
"""
# entferne alle Leerzeichen (sind ja erlaubt)
kontonummer = ""
for c in string:
if '0' <= c <= '9':
kontonummer += c
elif c != ' ':
return False # nur Ziffern und Leerzeichen erlaubt!
if len(kontonummer) != 9:
return False
summe = 0 # alles in einer Summe, aufteilen ist nicht nötig
for i in range(len(kontonummer)):
ziffer = ord(kontonummer[i]) - ord('0')
if (1 + i) % 2 == 1: # ungerade
summe += ziffer
else: # gerade
doppelt = ziffer * 2
if doppelt >= 10: # Zwei Ziffern
summe += doppelt % 10 # Einer
summe += doppelt // 10 # Zehner
else: # immer noch eine Ziffer
summe += doppelt
return summe % 10 == 0 # Summe muss durch 10 teilbar sein
def test_iskonto():
assert(not iskonto(""))
assert(not iskonto("a"))
assert(not iskonto("69719a9107"))
assert(not iskonto("69719917"))
assert(not iskonto("723016699"))
assert(iskonto("723016689"))
assert(iskonto("697199107"))
assert(iskonto("123456782"))
assert(iskonto("12 345 6782"))
print("test_iskonto() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def reverse_s(string):
"""liefert String in umgekehrter Reihenfolge zurück"""
s = ""
for c in string:
s = c + s
return s
def test_reverse_s():
assert("" == reverse_s(""))
assert("a" == reverse_s("a"))
assert("ba" == reverse_s("ab"))
assert("abc" == reverse_s("cba"))
print("test_reverse() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def toupper(string):
"""liefert String in Großbuchstaben zurück"""
s = ""
for c in string:
if 'a' <= c <= 'z':
s += chr(ord(c) - ord('a') + ord('A'))
elif c == 'ä':
s += 'Ä'
elif c == 'ö':
s += 'Ö'
elif c == 'ü':
s += 'Ü'
else:
s += c
return s
def test_toupper():
assert("" == toupper(""))
assert("A" == toupper("a"))
assert("AB" == toupper("ab"))
assert("ÄBC" == toupper("äbc"))
assert("A" == toupper("a"))
assert("AB" == toupper("Ab"))
assert("ÄBC" == toupper("äBc"))
print("test_toupper() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def tolower(string):
"""liefert String in Kleinbuchstaben zurück"""
pass
s = ""
for c in string:
if 'A' <= c <= 'Z':
s += chr(ord(c) - ord('A') + ord('a'))
elif c == 'Ä':
s += 'ä'
elif c == 'Ö':
s += 'ö'
elif c == 'Ü':
s += 'ü'
else:
s += c
return s
def test_tolower():
assert("" == tolower(""))
assert("a" == tolower("A"))
assert("ab" == tolower("AB"))
assert("äbc" == tolower("ÄBC"))
assert("a" == tolower("A"))
assert("ab" == tolower("Ab"))
assert("äbc" == tolower("äBc"))
print("test_tolower() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isupper(string):
"""prüft, ob String nur Großbuchstaben enthält"""
for c in string:
if 'a' <= c <= 'z' or c in "äöü": # ein Kleinbuchstabe
return False
return True
def test_isupper():
assert(isupper(""))
assert(isupper("A"))
assert(isupper("AEÄÖ"))
assert(not isupper("a"))
assert(not isupper("abcö"))
assert(not isupper("AbC"))
print("test_isupper() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def islower(string):
"""prüft, ob String nur Kleinbuchstaben enthält"""
for c in string:
if 'A' <= c <= 'Z' or c in "ÄÖÜ": # ein Großbuchstab
return False
return True
def test_islower():
assert(islower(""))
assert(islower("a"))
assert(islower("aeöä"))
assert(not islower("A"))
assert(not islower("ABCÖ"))
assert(not islower("AbC"))
print("test_islower() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def ispalindrom(string):
"""Prüft, ob der String ein Palindrom ist (von vorne und hinten
gelesen gleich)."""
for i in range(len(string)):
if string[i] != string[-1 - i]:
return False
return True
def test_ispalindrom():
assert(ispalindrom(""))
assert(ispalindrom("a"))
assert(ispalindrom("aa"))
assert(ispalindrom("aba"))
assert(ispalindrom("abba"))
assert(not ispalindrom("ab"))
assert(not ispalindrom("abb"))
assert(not ispalindrom("abab"))
print("test_ispalindrom() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def ispalindrom_l(liste):
"""Prüft, ob die Liste von vorne und hinten gelesen gleich ist."""
return ispalindrom(liste) # sollte äquivalent sein!
def test_ispalindrom_l():
assert(ispalindrom_l([]))
assert(ispalindrom_l([1]))
assert(ispalindrom_l([1, 1]))
assert(ispalindrom_l([1, 2, 1]))
assert(ispalindrom_l([1, 2, 2, 1]))
assert(not ispalindrom_l([1, 2]))
assert(not ispalindrom_l([1, 2, 2]))
assert(not ispalindrom_l([1, 2, 1, 2]))
print("test_ispalindrom_l() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def reverse_l(liste):
"""liefert die Liste in umgekehrter Reihenfolge zurück"""
l = []
for e in liste:
l = [e] + l
return l
def test_reverse_l():
assert([] == reverse_l([]))
assert([1] == reverse_l([1]))
assert([1, 2] == reverse_l([2, 1]))
assert([1, 2, 3] == reverse_l([3, 2, 1]))
print("test_reverse_l() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sum(liste):
"""liefert die Summe aller Zahlen in der Liste"""
summe = 0
for e in liste:
summe += e
return summe
def test_sum():
assert(0 == sum([]))
assert(12 == sum([12]))
assert(12 == sum([4, 8]))
assert(12 == sum([4, 4, 4]))
print("test_sum() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def mittelwert(liste):
"""liefert den Mittelwert (Durchschnitt) aller Zahlen in der Liste"""
if len(liste) > 0:
return sum(liste) / len(liste)
else:
return 0
def test_mittelwert():
assert(0 == mittelwert([]))
assert(1 == mittelwert([1]))
assert(1.5 == mittelwert([1, 2]))
assert(2 == mittelwert([2, 2, 2]))
assert(2 == mittelwert([1, 2, 3]))
print("test_mittelwert() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def rmdups(liste):
"""(ReMove DUPlicates) liefert Liste, aus der alle Vielfachen entfernt
(hintereinander).
Beispiele: [1, 2, 2, 2, 5, 2, 3, 2, 2, 23] -> [1, 2, 5, 2, 3, 2, 23]
[99, 99, 23, 99, 99, 12, 2] -> [99, 23, 99, 12, 2]
[] -> []
[1, 2, 4, 10] -> [1, 2, 4, 10]"""
if len(liste) > 0:
ret = [liste[0]]
for e in liste:
if ret[-1] != e: # letztes Element ungleich?
ret.append(e)
return ret
else:
return liste
def test_rmdups():
assert([1, 2, 5, 2, 3, 2, 23] == rmdups([1, 2, 2, 2, 5, 2, 3, 2, 2, 23]))
assert([99, 23, 99, 12, 2] == rmdups([99, 99, 23, 99, 99, 12, 2]))
assert([] == rmdups([]))
assert([1, 2, 4, 10] == rmdups([1, 2, 4, 10]))
print("test_rmdups() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def isin(item, liste):
"""ist item in liste enthalten?"""
for e in liste:
if item == e:
return True
return False
def rmalldups(liste):
"""(ReMove ALL DUPlicates) liefert Liste, aus der alle Vielfachen
entfernt (müssen nicht hintereinander stehen).
Beispiele: [1, 2, 2, 2, 5, 2, 3, 2, 2, 23] -> [1, 2, 5, 3, 23]
[99, 99, 23, 99, 99, 12, 2] -> [99, 23, 12, 2]
[] -> []
[1, 2, 4, 10] -> [1, 2, 4, 10]"""
if len(liste) > 0:
ret = [liste[0]]
for e in liste:
# if e not in ret: # schon vorhanden?
if not isin(e, ret):
ret.append(e)
return ret
else:
return liste
def test_rmalldups():
assert([] == rmalldups([]))
assert([1, 2, 5, 3, 23] == rmalldups([1, 2, 2, 2, 5, 2, 3, 2, 2, 23]))
assert([99, 23, 12, 2] == rmalldups([99, 99, 23, 99, 99, 12, 2]))
assert([1, 2, 4, 10] == rmalldups([1, 2, 4, 10]))
print("test_rmalldups() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def binsearch(liste, such):
"""liefert den Index von such in der sortierten Liste liste oder -1,
wenn such in liste nicht vorkommt. Es ist die binäre Suche anzuwenden!
"""
first = 0
last = len(liste) - 1
mid = (last - first) // 2 + first
#print(first, mid, last)
while len(liste) > 0 and first <= last:
if such < liste[mid]:
last = mid - 1
elif such > liste[mid]:
first = mid + 1
else:
return mid #index found
mid = (last - first) // 2 + first
#print(first, mid, last)
return -1 # not found
def test_binsearch():
"""static tests"""
assert(binsearch([], 1) == -1)
assert(binsearch([1], 2) == -1)
assert(binsearch([1], 0) == -1)
assert(binsearch([1], 1) == 0)
assert(binsearch([1,3], 0) == -1)
assert(binsearch([1,3], 2) == -1)
assert(binsearch([1,3], 1) == 0)
assert(binsearch([1,3], 3) == 1)
assert(binsearch([1,3], 4) == -1)
assert(binsearch([1,3,5], 2) == -1)
assert(binsearch([1,3,5], 4) == -1)
assert(binsearch([1,3,5], 1) == 0)
assert(binsearch([1,3,5], 3) == 1)
assert(binsearch([1,3,5], 5) == 2)
assert(binsearch([1,3,5], 6) == -1)
assert(binsearch([1,3,5,7], 0) == -1)
assert(binsearch([1,3,5,7], 1) == 0)
assert(binsearch([1,3,5,7], 3) == 1)
assert(binsearch([1,3,5,7], 5) == 2)
assert(binsearch([1,3,5,7], 7) == 3)
assert(binsearch([1,3,5,7], 9) == -1)
assert(binsearch([1,3,5,7], 2) == -1)
assert(binsearch([1,3,5,7], 4) == -1)
assert(binsearch([1,3,5,7], 6) == -1)
import random
for i in range(25):
liste = [random.randint(0, 100) for i in range(100)]
liste.sort()
num = random.randint(0, 100)
if num in liste:
if binsearch(liste, num) < 0:
print(liste)
print("%d should be found in list" % num)
assert(binsearch(liste, num) >= 0)
else:
if binsearch(liste, num) >= 0:
print(liste)
print("%d should not be found in list" % num)
assert(binsearch(liste, num) < 0)
print("test_binsearch() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def sumteilbar(liste, teiler):
"""Berechnet die Summe aller durch teiler teilbaren Zahlen der Liste"""
summe = 0
for e in liste:
if e % teiler == 0:
summe += e
return summe
def test_sumteilbar():
assert(0 == sumteilbar([], 2))
assert(0 == sumteilbar([1], 2))
assert(0 == sumteilbar([1, 3], 2))
assert(0 == sumteilbar([1, 3, 23], 2))
assert(2 == sumteilbar([2], 2))
assert(2 == sumteilbar([1, 2], 2))
assert(2 == sumteilbar([1, 2, 23], 2))
assert(32 == sumteilbar([1, 8, 24], 2))
assert(27 == sumteilbar([3, 8, 24], 3))
print("test_sumteilbar() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def issorted(liste):
"""Prüft, ob die Liste sortiert ist, d.h. ob e1 <= e2 <= e3 <= ... <= en
e1, e2, ... en sind die n Elemente der Liste mit Länge n"""
for i in range(len(liste) - 1):
if liste[i] > liste[i + 1]:
return False
return True
def test_issorted():
assert(issorted([]))
assert(issorted([1]))
assert(issorted([1, 1]))
assert(issorted([1, 3, 3, 4]))
assert(not issorted([1, 0]))
assert(not issorted([1, 2, 1]))
print("test_issorted() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def printlxl(liste1, liste2):
"""gibt eine Multiplikationstabelle der beiden Listen aus.
Zum Beispiel:
a = [1, 2, 4, 5]
b = [3, 2, 2]
printlxl(a, b) gibt dann folgendes aus:
3 2 2
6 4 4
12 8 8
15 10 10
Die erste Liste bestimmt die Anzahl der Zeilen, die zweite die Anzahl
der Spalten. Es wird immer ein Element der ersten Liste mit einem der
zweiten Liste multipliziert.
"""
erg = lxl(liste1, liste2)
for zeile in erg:
for spalte in zeile:
print("%4d" % spalte, end = "")
print()
def test_printlxl():
a = [1, 2, 4, 5]
b = [3, 2, 2]
printlxl(a, b)
print("test_printlxl() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def lxl(liste1, liste2):
"""liefert eine Multiplikationstabelle der beiden Listen (Liste von
Listen).
Zum Beispiel:
a = [1, 2, 4, 5]
b = [3, 2, 2]
lxl(a, b) liefert folgende Liste zurück:
[[3, 2, 2], [6, 4, 4], [12, 8, 8], [15, 10, 10]]
übersichtlich formatiert:
[[3, 2, 2],
[6, 4, 4],
[12, 8, 8],
[15, 10, 10]]
Die erste Liste bestimmt die Anzahl der "Zeilen", die zweite die Anzahl
der "Spalten". Es wird immer ein Element der ersten Liste mit einem der
zweiten Liste multipliziert.
"""
erg = []
if len(liste2) > 0:
for a in liste1:
zeile = []
for b in liste2:
zeile.append(a * b)
erg.append(zeile)
return erg
def test_1x1():
a = [1, 2, 4, 5]
b = [3, 2, 2]
assert([[3, 2, 2], [6, 4, 4], [12, 8, 8], [15, 10, 10]] == lxl(a, b))
assert([] == lxl([], []))
assert([] == lxl([], [1, 2]))
assert([] == lxl([1, 2], []))
print("test_1x1() ok")
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
# Testaufrufe:
test_isint()
test_isintb()
test_sumdigits()
test_horner()
test_isipv4()
test_anz_zahlen()
test_sum_zahlen()
test_iskonto()
test_reverse_s()
test_toupper()
test_tolower()
test_isupper()
test_islower()
test_ispalindrom()
test_ispalindrom_l()
test_reverse_l()
test_sum()
test_mittelwert()
test_rmdups()
test_rmalldups()
test_binsearch()
test_sumteilbar()
test_issorted()
test_printlxl()
test_1x1()Die Funktionen
isupper() und islower() sind eigentlich nicht korrekt, denn liefert z.B. isupper("A4C") True. Man müsste also eher schreiben:def isupper(string):
"""prüft, ob String nur Großbuchstaben enthält"""
for c in string:
if not ('A' <= c <= 'Z' or c in "ÄÖÜ"):
return False
return True
Labels: Lösung, POS1-1, Python
Samstag, 22. Januar 2011
Ermittle die Top-10 der Worte in einem Text (POS1: 2A, 2C)
Aufgabe 1
Schreiben Sie eine Funktionhauf(string), welche die 10 häufigsten Worte im String string ermittelt und als Liste von Tupeln der Art (wort, anzahl) zurück liefert (Länge der Liste ist <= 10). Die Liste muss so sortiert sein, dass das Häufigste Wort ganz am Anfang ist. Haben Worte die selben Häufigkeiten, so haben diese alphabetisch sortiert zu sein.
Aufgabe 2
Schreiben Sie eine Funktion histogramm(liste, weite = 60), welche aus der übergebenen Liste ein Histogramm erzeugt und als String zurück liefert. Eine „Zeile“ soll so aussehen:das 123 ************Wobei für das Wort 14 Zeichen, die Anzahl 3 Zeichen vorgesehen werden müssen. Dahinter ist eine Anzahl Sternchen, die der Anzahl bezogen auf das Maximum (höchste Anzahl in der Liste) und der Weite entspricht (
round(anzahl / max * weite)).
Aufgabe 3
Schreiben Sie eine Funktion main(), welche alle auf der Kommandozeile angegebenen Dateien öffnet und die Gesamthäufigkeiten ermittelt (also hauf() mit dem gesamten gelesenen Text aufruft) und mit den ermittelten Daten das Histogramm ausgibt.Sind keine Dateien angegeben, so ist von stdin zu lesen (bis
EOF).Beispielaufruf mit den Testdaten vom /vorgabe-Verzeichnis:
hp@l111~/workspace/python$ python3 haufdiagramm.py testdaten.txt der 89 ************************************************************ die 61 ***************************************** und 43 ***************************** Histogramm 40 *************************** in 28 ******************* für 17 *********** ist 17 *********** den 16 *********** das 15 ********** ein 14 *********
Mögliche Lösung
Ich werde die einzelnen Funktionen erklären:import sysDieser Import wird für die Kommandozeilenargumente benötigt.
Folgende Funktion ermittelt die Wort-Häufigkeiten, sortiert das Ergebnis nach Häufigkeit und liefert die ersten 10 Elemente.
def hauf(string):
"""ermittelt die 10 häufigsten Worte in 'string' und liefert Liste mit
Tupel (wort, anzahl)"""
dict = {}
for wort in string.split():
split() ohne Parameter zerlegt einen String in eine Liste von "Worten", wobei ein "Wort" eine Folge von Zeichen ohne Leerzeichen, Tabulator und Zeilenumbruch ist. Mit anderen Worten Leerzeichen, Tabulatoren und Zeilenumbrüche sind die Trenner. wort = wort.rstrip('.,;?!")') # Satzzeichen entfernen
wort = wort.lstrip('"(') # Hochkomma und Klammer dürfen vorne stehen
lstrip() und rstrip() entfernen alle Zeichen in Klammer llinks bzw. rechts. In unserem Fall alle Satzzeichen, die unmittelbar vor einem Wort bzw. nach einem Wort stehen dürfen.Die beiden Zeilen könnte man natürlich auch zusammenfassen zu:
wort = wort.rstrip('.,;?!")').lstrip('"(').Die folgende erste Zeile prüft, ob der String auch tatsächlich ein Wort ist (nur Buchstaben).
if wort.isalpha():
if wort in dict:
dict[wort] += 1
else:
dict[wort] = 1
Obige 4 letzte Zeilen prüfen zunächst, ob das Wort bereits im Dictionary enthalten ist. Wenn ja, dann wird die gespeicherte Anzahl erhöht, wenn nein, dann wird unter diesem Wort eine 1 gespeichert.l = list(dict.items())Erzeugt eine Liste mit Tupeln
(wort, anzahl) aus dem Dictionary.l.sort(key=lambda x: (-x[1], x[0]))
sort() sortiert eine Liste nach der natürlichen Reihenfolge. Mit dem Parameter key kann eine Funktion übergeben werden, anhand deren Returnwert sortiert werden soll. Die Funktion wird jeweils mit einem Listenelement aufgerufen. Man könnte also eine Funktion schreiben, die jeweils das zweite Element des Tupels (die Liste besteht in diesem Fall ja aus Tupeln der Art (wort, anzahl)) zurückliefert. Da absteigend sortiert werden soll, muss entweder der Wert mit -1 multipliziert werden (-[x1]) oder man muss beim Sortieren sort(reverse=True) aufrufen. Den Namen dieser Funktion übergibt man dann per key=sortfunktion.Diese Funktion könnte so aussehen:
def sortierfunktion(x):return (-x[1], x[0])lambda x: definiert eine anonyme Funktion (Funktion ohne Namen) mit dem Parameter x, die gleich an Ort und Stelle definiert und übergeben werden kann. l = l[0:10]
return l
Die letzten beiden Zeilen schneiden die ersten 10 Elemente der Liste aus und liefern sie zurück.Das könnte man auch nur mit einer Anweisung machen:
return l[:10].def stars(num, max, width):
"""liefert String mit so vielen Sternen, wie num / max * width"""
return "*" * round(num / max * width)
Dazu braucht man nicht allzu viel sagen.Die folgende Funktion erzeugt das in Aufgabe 2 geforderte Histogramm.
Um einen passenden Maßstab für die geforderte Weite
weite=60 zu finden, wird das Maximum der Werte ermittelt. Das muss natürlich das zweite Element des ersten Tupels der Liste sein, wenn überhaupt Tupel in der Liste sind.def histogramm(liste, weite=60):
"""erzeugt Histogramm und liefert es zurück"""
if len(liste) > 0:
max = liste[0][1]
ret = ""
for wort, anzahl in liste:
Diese Schleife geht jedes Tupel der Liste durch, wobei die Tupel gleich in wort und anzahl "ausgepackt" wird.ret += "%-14s%3d %s\n" % (wort, anzahl, stars(anzahl, max, weite))Hier wird jede Zeile an den String
ret angehängt, wobei Stringformatierung angewendet wird.return ret
Die folgenden beiden Funktionen dient nur zum Testen mit fixen Strings und liefert einen String mit vorgegebenen Anzahlen von Worten.
def teststr():
"""liefert Testeingabe"""
s = "Häufigkeit " * 50 + "das " * 123 + "die, " * 100 + "Haus " * 40
s += "Maus " * 38 + "Koffer " * 34 + "Kilogramm " * 22 + "Punkt " * 18
s += "Genau " * 16 + "Zehn " * 10
s += "nichts " * 5 + "23 " * 50 + "ziemlich " * 3
return s
def test():
"""Testen..."""
liste = hauf(teststr())
print(histogramm(liste, 12.3))
Diese Funktion prüft, ob überhaupt Kommandozeilenargumente vorhanden sind. Gibt es welche, so werden alle Argumente als Dateien zum Lesen geöffnet und mit
read() komplett gelesen und an den String eingabe angehängt.Gibt es keine Dateinamen auf der Kommandozeile, so wird mittels
eingabe = sys.stdin.read() von der Standardeingabe gelesen.Die letzte Zeile ruft die beiden Hauptfunktionen auf und gibt das Ergebnis aus.
Es fehlt allerdings noch die Überprüfung, ob eine Datei überhaupt existiert bzw. geöffnet werden kann. Diesen Teil möge der Leser selber ergänzen.
def main():
"""öffnet Datei oder liest von stdin"""
if len(sys.argv) > 1:
eingabe = ""
for arg in sys.argv[1:]:
f = open(arg)
eingabe += " " + f.read()
f.close()
else:
eingabe = sys.stdin.read()
print(histogramm(hauf(eingabe)))
Die folgenden Zeilen dienen zum Aufrufen der Funktion
main() (bzw. test() zum Testen), sofern dieses Script als Programm aufgerufen wurde.if __name__ == '__main__':
# test()
main()
Vollständiges Programm (ohne Header)
import sys
def hauf(string):
"""ermittelt die 10 häufigsten Worte in 'string' und liefert Liste mit
Tupel (wort, anzahl)"""
dict = {}
for wort in string.split():
wort = wort.rstrip('.,;?!")') # Satzzeichen entfernen
wort = wort.lstrip('"(') # Hochkomma und Klammer dürfen vorne stehen
if wort.isalpha():
if wort in dict:
dict[wort] += 1
else:
dict[wort] = 1
l = list(dict.items())
l.sort(key=lambda x: (-x[1], x[0]))
l = l[0:10]
return l
def stars(num, max, width):
"""liefert String mit so vielen Sternen, wie num / max * width"""
return "*" * round(num / max * width)
def histogramm(liste, weite=60):
"""erzeugt Histogramm und liefert es zurück"""
if len(liste) > 0:
max = liste[0][1]
ret = ""
for wort, anzahl in liste:
ret += "%-14s%3d %s\n" % (wort, anzahl, stars(anzahl, max, weite))
return ret
def teststr():
"""liefert Testeingabe"""
s = "Häufigkeit " * 50 + "das " * 123 + "die, " * 100 + "Haus " * 40
s += "Maus " * 38 + "Koffer " * 34 + "Kilogramm " * 22 + "Punkt " * 18
s += "Genau " * 16 + "Zehn " * 10
s += "nichts " * 5 + "23 " * 50 + "ziemlich " * 3
return s
def test():
"""Testen..."""
liste = hauf(teststr())
print(histogramm(liste, 12.3))
def main():
"""öffnet Datei oder liest von stdin"""
if len(sys.argv) > 1:
eingabe = ""
for arg in sys.argv[1:]:
f = open(arg)
eingabe += " " + f.read()
f.close()
else:
eingabe = sys.stdin.read()
print(histogramm(hauf(eingabe)))
if __name__ == '__main__':
# test()
main()
Labels: Aufgabe, Lösung, POS1-2, Python
Freitag, 14. Januar 2011
Ganze Zahlen zählen (Schleife, Sequenzen, Funktionen POS1: 1BHIF)
Beispiel:
Eingabe:
das ist eine Zahl 123 und noch eine 1 und noch zwei 3213x23123Ausgabe:
4 Zahlen gefunden.Das Programm soll richtige Sätze ausgeben, also "Keine Zahlen gefunden.", wenn in der Eingabe keine Zahlen sind oder "Eine Zahl gefunden.", wenn eine Zahl in der Eingabe war. Ab 4 soll dann die Zahl ausgegeben werden, z.B. "6 Zahlen gefunden."
Mögliche Lösung:
"""
author: Haberstroh, Harald
matnr: d09666
file: anzzahlen.py
desc: Zähle ganze Zahlen
Beispiel:
das ist eine Zahl 123 und noch eine 1 und noch zwei 3213x23123
Ausgabe:
4 Zahlen gefunden
date: 14.1.2011
class: Lehrer
catnr: 33
"""
#---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
def anz_zahlen(string):
"""ermittelt die Anzahl der ganzen Zahlen im String"""
anzahl = 0
in_zahl = False
for zeichen in string:
if zeichen in "0123456789":
if not in_zahl:
anzahl += 1
in_zahl = True
else:
in_zahl = False
return anzahl
def ausgabe(anzahl):
"""gibt deutschen Satz aus mit Anzahl"""
if anzahl == 0:
print("Keine Zahl gefunden.")
elif anzahl == 1:
print("Eine Zahl gefunden.")
elif anzahl == 2:
print("Zwei Zahlen gefunden.")
elif anzahl == 3:
print("Drei Zahlen gefunden.")
else:
print(anzahl, "Zahlen gefunden.")
def main():
"""EVA Eingave Verarbeitung Ausgabe - das Hauptprogramm"""
string = input("> ")
anzahl = anz_zahlen(string)
ausgabe(anzahl)
def test():
"""Testen von anz_zahlen() und ausgabe()"""
string = "das ist eine Zahl 123 und noch eine 1 und noch eine 3213x23123"
anzahl = anz_zahlen(string)
ausgabe(anzahl)
ausgabe(anz_zahlen("keine"))
ausgabe(anz_zahlen("eine Zahl 123"))
ausgabe(anz_zahlen("zwei 23 und 324"))
ausgabe(anz_zahlen("drei 23 34 22"))
ausgabe(anz_zahlen("vier 234 234 234 45"))
ausgabe(anz_zahlen("5 234 234 234 45"))
if __name__ == '__main__':
main()
# test()
Beachten Sie, dass ich hier eine eigene Funktion test() gemacht habe, um viele Testfälle immer wieder leicht probieren zu können. Statt main() muss dann nur test() aufgerufen werden.Das Programm wäre auch ohne die Funktion
test() fertig und korrekt. test() half nur bei der Entwicklung bei der Fehlersuche.Labels: Aufgabe, Lösung, POS1-1, Python
Freitag, 3. Dezember 2010
Musterlösung zu Übungsbeispiele für Python vom 1.12.2010 (POS1: 1BHIF)
Zwei Seiten müssen immer länger als die dritte sein. Man muss dies für alle Möglichkeiten prüfen, denn z.B.
a = 3, b = 4, c = 1
Da stimmt zwar a + b > c (7 > 1) und b + c > a (4 > 3), jedoch nicht a + c > b (4 == 4)!
Bei der Lösung wird eine Schleife verwendet.
def ist_dreieck(a, b, c):
"""liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
ist"""
i = 3
while i > 0:
if a + b <= c:
return False # kein Dreieck
a, b, c = b, c, a
i = i - 1
return True
Man könnte das Problem natürlich auch durch logische Verknüpfung der Prüfungen lösen: def ist_dreieck(a, b, c):
"""liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
ist"""
if a + b > c and b + c > a and c + a > b:
ret = True
else:
ret = False
return ret
Oder gleich so: def ist_dreieck(a, b, c):
"""liefert True, wenn durch a, b und c ein gültiges Dreieck definiert
ist"""
return a + b > c and b + c > a and c + a > b
Bei der zweiten Aufgabe soll geprüft werden, ob durch zwei Seiten und einem Winkel ein Quadrat gegeben ist. Die beiden Seiten müssen gleich lang sein (und größer 0) und der Winkel 90°: def ist_quadrat(a, b, w):
"""liefert True, wenn durch a und b sowie dem Winkel w ein
Quadrat definiert ist"""
quadrat = False
if a > 0:
if a == b:
if w == 90:
quadrat = True
# else entfällt, da die Variable quadrat schon mit False vorbelegt ist.
return quadrat
Oder wieder kürzer mit logischer Verknüpfung: def ist_quadrat(a, b, w):
"""liefert True, wenn durch a und b sowie dem Winkel w ein
Quadrat definiert ist"""
return a == b and w == 90 and a > 0
Die Schaltjahrprüfung könnte so erfolgen: def ist_schaltjahr(jahr):
"""liefert True, wenn das gegebene Jahr ein Schaltjahr ist.
Seit Ende 1582 gilt der Gregorianische Kalender, bei dem folgende Regel
für die Schaltjahrbestimmung anzuwenden sind:
In allen Jahren, deren Jahreszahl durch vier teilbar ist, ist der
29. Februar ein Schalttag und damit ist dieses Jahr ein Schaltjahr.
Eine Ausnahme bilden allerdings die vollen Jahrhundertjahre 1700,
1800, 1900 usw., auch Säkularjahre genannt. Hiervon erhalten nur
diejenigen einen Schalttag, deren Jahreszahl durch 400 teilbar ist.
Jedes vierte Säkularjahr ist somit ein Schaltjahr.
Für alle Jahre <= 1582 liefert die Funktion False, weil da das
Schaltjahr nicht definiert ist, sonst gilt obige Regel."""
if jahr <= 1582:
schaltjahr = False
elif jahr % 400 == 0:
schaltjahr = True
elif jahr % 100 == 0:
schaltjahr = False
elif jahr % 4 == 0:
schaltjahr = True
else:
schaltjahr = False
return schaltjahr
Jahre bis 1582 können keine Schaltjahre sein, da der Gregorianische Kalender erst im Jahr 1582 definiert wurde. Zum Test der Schaltjahrprüfung noch ein paar Worte, aber zunächst die Testfunktion, die ein paar Jahreszahlen prüft, von denen man weiß, dass sie kein Schaltjahr sind sowie Zahlen, bei denen bekannt ist, dass sie Schaltjahre sind: def test_ist_schaltjahr():
for jahr in (1000, 1580, 1581, 1582, 1900, 1999, 2003):
assert not ist_schaltjahr(jahr)
for jahr in (1996, 2000, 2004):
assert ist_schaltjahr(jahr)
print("ist_schaltjahr ok")
Die Anweisung assert ist für Programmierer und dient zum Prüfen der Bedingung, die gleich dahinter folgt, gedacht. Zum Beispiel: assert 3 < 4Die Bedingung ist wahr, daher läuft das Programm weiter. Ist die Bedingung hingegen falsch, so wird das Programm mit einer Fehlermeldung abgebrochen:
>>> assert 3 > 4 Traceback (most recent call last): File "Zusätzlich kann ein Text als Fehlermeldung angegeben werden:", line 1, in assert 3 > 4 AssertionError
>>> assert 3 > 4, "3 ist nicht größer als 4" Traceback (most recent call last): File "Angewendet auf obige Testfunktion bedeutet das, dass immer, wenn", line 1, in assert 3 > 4, "3 ist nicht größer als 4" AssertionError: 3 ist nicht größer als 4
assert not ist_schaltjahr(jahr) die Funktion ist_schaltjahr(jahr) den Wert assert ist_schaltjahr(jahr) steht, True geleifert werden muss, damit das Programm nicht abgebrochen wird. Der nächste Punkt ist die for jahr in (1000, 1580, 1581, 1582, 1900, 1999, 2003):-Zeile. Die Variable jahr bekommt der Reihe nach die Werte 1000, 1580, 1581, 1582, 1900, 1999, 2003 und der eingerückte Code-Block (die eine Zeile) wird ausgeführt. Das ist die for-Schleife, welche im Buch im Kapitel 7 auch erklärt wird. Die Funktion test_ist_schaltjahr() prüft also zunächst ein paar Jahre, die kein Schaltjahr sind und ein paar Schaltjahre. Die Fibonaccizahlen können wie folgt ermittelt werden: def fib(n):
"""liefert die Fibonaccizahl zu n. Die Zahlen sind wie definiert:
fib(0) -> 0
fib(1) -> 1
fib(2) -> 1
fib(3) -> 2
fib(4) -> 3
fib(5) -> 5
fib(6) -> 8
...
fib(10) -> 55
...
fib(15) -> 610"""
f = 0
a = 0
b = 1
i = 0
while i < n:
f = a + b
b, a = a, f
i += 1
return f
Für n = 0 und n = 1 sind die (Anfangs-)Werte vordefiniert. fib(0) = 0 und fib(1) = 1. Danach gilt die Regel, dass die n. Fibonaccizahl die Summe der beiden Vorgänger ist, also fib(n - 1) + fib(n - 2) (Siehe dazu auch Wikipedia: Fibonacci-Folge). Die Variable f hat immer den Wert der aktuellen Fibonaccizahl und ist daher mit 0 initialisiert. Die Variable a und b haben immer den Wert der beiden Vorgänger. Sie können das leicht sehen, wenn Sie print(...)-Anweisungen einfügen und sich dadurch den Ablauf der Berechnung anzeigen lassen: def fib(n):
"""liefert die Fibonaccizahl zu n."""
f = 0
a = 0
b = 1
i = 0
while i < n:
f = a + b
print(i, ": f =", f, "a =", a, "b =", b) # Testausgabe
b, a = a, f
i += 1
return f
print(fib(10))
..gibt dann folgendes aus: 0 : f = 1 a = 0 b = 1 1 : f = 1 a = 1 b = 0 2 : f = 2 a = 1 b = 1 3 : f = 3 a = 2 b = 1 4 : f = 5 a = 3 b = 2 5 : f = 8 a = 5 b = 3 6 : f = 13 a = 8 b = 5 7 : f = 21 a = 13 b = 8 8 : f = 34 a = 21 b = 13 9 : f = 55 a = 34 b = 21 55Die Ausgabe einer Tabelle mithilfe der Funktion
fib() ist einfach (oder doch etwas kompliziert, weil die eckigen Klammern dazukommen): def fibtab(n):
"""erzeugt eine Tabelle der Fibonaccizahlen bis inclusive n.
z.B. gibt fibtab(10) folgendes aus:
[0, 1, 1, 2, 3, 5, 8]
oder fibtab(100):
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Hinweis:
verwenden Sie als Zeilenumbruch ", " beim print, also
print(wert, end=', ')
außer natürlich beim letzten Wert, hier ist "]" gefordert.
"""
i = 0
print("[", end = "")
f = fib(i)
while f <= n:
print(f, end = "")
i += 1
f = fib(i)
if f > n:
print("]")
else:
print(", ", end = "")
Wir müssen sicherstellen, dass zunächst "[" ohne Zeilenumbruch ausgegeben wird. Die Funktion print(...) hat einen optionalen Parameter end, der angibt, was zum Schluss ausgegeben werden soll. Standardmäßig ist das "\n", was einen Zeilenumbruch bewirkt. Setzt man den Wert end = "", so wird ein Leerstring, also nichts, ausgegeben. In der Schleife muss man noch prüfen, ob man das Ende erreicht hat und in diesem Fall "]" (mit Zeilenumbruch) ausgibt. Im Normalfall wird ein Komma ohne Zeilenumbruch ausgegeben (letzte Zeile). Beachten Sie, dass der Parameter n hier die Grenze der Fibonaccizahl angibt und nicht die wievielte (wie bei fib(n)). Die Lösung zum Beispiel, die Summe der Vielfachen von 3 und 5 kleiner als ein Maximum: def sum_3_5(max):
"""
bilde Summe der Vielfachen von 3 und 5 kleiner als max.
Beispielsweise liefert sum_3_5(10) 23, weil
die Vielfachen von 3 < 10 sind
3 + 6 + 9 = 18
die Vielfachen von 5 < 10 sind
5
18 + 5 = 23
sum_3_5(20) liefert 78, weil
3+ 6+9+ 12+15+18=63
5+ 10+ =15 (15 ist in obiger Liste schon enthalten!)
sum_3_5(25) liefert 143, weil
3+ 6+9+ 12+ 18+ 21+24=93 (Vielfache von 5 stehen darunter)
5+ 10+ 15+ 20 =50
sum_3_5(100) liefert 2318 (ohne Beweis)
"""
summe = 0
i = 0
while i < max:
if i % 5 == 0:
summe += i
elif i % 3 == 0:
summe += i
i += 1
return summe
Die Laufvariable i wird immer dann zur summe dazugezählt, wenn sie durch 5 teilbar ist oder wenn sie durch 3 teilbar ist. Der Operator % berechnet den Rest der Division. Ist der Rest 0, so ist die erste durch die zweite Zahl teilbar. Das Beispiel zum finden des nächstkleineren bzw. gleichen Quadrats kann so mit einer Probiermethode gelöst werden: def minquad(zahl):
"""finde die nächstkleinere oder gleichgroße ganze Zahl, die eine
Quadratzahl ist. Beispiele:
minquad(16) -> 16 (weil 4 * 4 = 16 <= 16)
minquad(24) -> 24 (weil 4 * 4 = 16 <= 14)
minquad(25) -> 25 (weil 5 * 5 = 25 <= 25)
minquad(26) -> 25 (weil 5 * 5 = 25 <= 26)
"""
i = 0
mq = 0
while i ** 2 <= zahl:
mq = i ** 2
i += 1
return mq
i ** 2 bedeutet i2. Man könnte natürlich auch i * i schreiben. Diese Funktion prüft einfach sukzessive alle Quadrate, bis eines gefunden wurde, das größer als die gegebene Zahl ist. Der Wert davor (die Variable mq) ist natürlich das Ergebnis, weil das der größte Wert war, für den die Bedingung gilt. Es geht natürlich schneller und einfacher, wenn man sich eine Formel überlegt: from math import sqrt
from math import floor
def minquad(zahl):
"""finde die nächstkleinere oder gleichgroße ganze Zahl, die eine
Quadratzahl ist. Beispiele:
minquad(16) -> 16 (weil 4 * 4 = 16 <= 16)
minquad(24) -> 16 (weil 4 * 4 = 16 <= 24)
minquad(25) -> 25 (weil 5 * 5 = 25 <= 25)
minquad(26) -> 25 (weil 5 * 5 = 25 <= 26)
"""
return int(floor(sqrt(zahl))) ** 2
Die Funktion floor(x) liefert die nächstkleinere ganze Zahl zu x (bei positiven Zahlen schneidet dir Funktion die Nachkommastellen der übergebenen Zahl ab). Z.B: >>> from math import floor >>> floor(3.14) 3 >>> floor(3) 3 >>> floor(-3.14) -4Wenn man die nächstkleinere ganze Zahl der Wurzel quadriert, hat man das gewünschte Ergebnis. Die Turtle-Funktion zum Dreieckzeichnen könnte wie folgt aussehen und braucht nicht weiter erklärt werden:
def dreieck(a, w):
"""zeichnet ein gleichseitiges Dreieck der Seitenlänge a, gedreht um
den Winkel w. w = 0 bedeutet, dass die eine Seite horizional ist. w = 90
bedeutet, dass das Dreieck nach LINKS um 90° gedreht ist, d.h. eine Seite
ist vertikal.
Das Dreieck soll rechts neben des angegebenen Punktes gezeichnet werden.
"""
# nehme an Turtle sieht nach oben (wie auch beim Starten)
right(90 - w)
pendown()
for i in range(3):
forward(a)
left(120)
penup()
left(90 - w)
Um ein Dreieck an eine bestimmte Position zu setzen, kann zusätzlich die Funktion setpos(x, y), welche die Turtle an die Postion x,y setzt, verwendet werden: def dreieck_an_pos(a, w, x, y):
"""zeichnet ein Dreieck mit Hilfe der Funktion dreieck(a, w) an der
Position x, y."""
penup()
setpos(x, y)
dreieck(a, w)
Abgesehen von den Turtle-Funktionen können Sie die Funktionen direkt auf der Website http://codepad.org testen. Dort können Sie auch andere Programmiersprachen probieren. Die Python-Version ist leider nicht aktuell, daher könnte es sein, dass einiges doch nicht direkt so funktioniert. Diese einfachen Beispiele funktionieren aber.Hier ist zu
minquad(zahl) zu sehen:Labels: Lösung, POS1-1, Python
Donnerstag, 2. Dezember 2010
Datum in C selbst gebastelt
Verwendung:
Ohne Parameter gibt es einfach das aktuelle Monat mit Markierung
< 2> für den heutigen Tag und : 8: als Markierung für österreichische Feiertage. Danach wird die Liste der Feiertage ausgegeben.$ ./cal
Dezember 2010
Montag 6 13 20 27
Dienstag 7 14 21 28
Mittwoch 1 : 8: 15 22 29
Donnerstag < 2> 9 16 23 30
Freitag 3 10 17 :24::31:
Samstag 4 11 18 :25:
Sonntag : 5::12::19::26:
5.12. 2. Advent
8.12. Maria Empfängnis
12.12. 3. Advent
19.12. 4. Advent
24.12. Heiligabend
25.12. Christtag
26.12. Stefanitag
31.12. Silvester :-)
Here comes the Source...
/*
* File: cal.c
*
* Zweck: Kalenderprogramm
* ...für ein gegebenes Monat.
* mit/ohne argc/argv
*
* Autor: Harald Haberstroh
*
* Algorithmus:
*
* History: 2002-09-29
* 2003-10-15, Feiertage + Argumente von main()
* 2004-11-05, Liste der Feiertage
*/
/*--------------------------- includes ------------------------------*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
/*--------------------------- defines -------------------------------*/
#define WOCHENTAG 3 /* Wochentag des 1.1.1582 */
#define MONTAG 0
#define DIENSTAG 1
#define MITTWOCH 2
#define DONNERSTAG 3
#define FREITAG 4
#define SAMSTAG 5
#define SONNTAG 6
/*--------------------------- typedefs ------------------------------*/
/*--------------------------- globals -------------------------------*/
enum {
KEIN = 0,
NEUJAHR,
HL3KOENIGE,
ASCHERMITTWOCH,
PALMSONNTAG,
KARFREITAG,
OSTERSONNTAG,
OSTERMONTAG,
STAATSFEIERTAG,
MUTTERTAG,
PFINGSTSONNTAG,
PFINGSTMONTAG,
DREIFALTIGKEITSSONNTAG,
FRONLEICHNAM,
MARIAHIMMELFAHRT,
NATIONALFEIERTAG,
REFORMATIONSTAG,
ALLERHEILIGEN,
ALLERSEELEN,
MARIAEMPFAENGNIS,
ADVENT1,
ADVENT2,
ADVENT3,
ADVENT4,
HEILIGABEND,
CHRISTIANI,
STEFANI,
SILVESTER
};
/*-------------------------- prototypes -----------------------------*/
void printFeiertage(int jahr, int monat);
int tagemonat( int jahr, int monat );
int sonntag( int jahr, int monat, int tag );
void tag2datum( int tagzahl, int *jahr, int *monat, int *tag );
void ostern( int jahr, int *monat, int *tag );
int feiertag(int jahr, int monat, int tag);
int anzProMonat(int jahr, int monat);
void printcal(int start, int anz, int heute, int monat, int jahr);
int schaltjahr( int Jahr );
int Anzahl_Tage( int Jahr, int Monat, int Tag );
/*----------------------------- main --------------------------------*/
int main( int argc, char *argv[] )
{
int tage, tag, monat, jahr, start;
struct tm *zeit;
time_t sec;
if (argc == 2 && strcmp(argv[1], "-i") == 0)
{ /* interaktiv */
printf("Jahr> ");scanf("%d", &jahr);
printf("Monat> ");scanf("%d", &monat);
printf("Tag (0 für kein bestimmter)> ");scanf("%d", &tag);
if (tag == 0)
{
tag = 1;
if (1 <= monat && monat <= 12 &&
1582 < jahr && jahr < 3000)
{
tage = Anzahl_Tage( jahr, monat, 1);
start = (tage + WOCHENTAG) % 7;
printcal(start, anzProMonat(jahr, monat), 0, monat, jahr);
return 0;
}
else
{
fprintf(stderr, "Monat zwischen 1 und 12 und Jahr zwischen "
"1583 und 2999\n");
return 2;
}
}
if (1 <= monat && monat <= 12 &&
1582 < jahr && jahr < 3000 &&
1 <= tag && tag <= anzProMonat(jahr,monat))
{
tage = Anzahl_Tage( jahr, monat, 1);
start = (tage + WOCHENTAG) % 7;
printcal(start, anzProMonat(jahr, monat), tag, monat, jahr);
return 0;
}
else
{
fprintf(stderr, "Monat zwischen 1 und 12 und Jahr zwischen "
"1583 und 2999\n"
"[Tag zwischen 1 und Anzahl für dieses Monat]\n");
return 2;
}
}
else if (argc == 3) /* Monat, Jahr */
{
monat = atoi(argv[1]);
jahr = atoi(argv[2]);
tag = 1;
if (1 <= monat && monat <= 12 &&
1582 < jahr && jahr < 3000)
{
tage = Anzahl_Tage( jahr, monat, 1);
start = (tage + WOCHENTAG) % 7;
printcal(start, anzProMonat(jahr, monat), 0, monat, jahr);
return 0;
}
else
{
fprintf(stderr, "Monat zwischen 1 und 12 und Jahr zwischen "
"1583 und 2999\n");
return 2;
}
}
else if (argc == 4) /* ganzes Datum */
{
monat = atoi(argv[2]);
jahr = atoi(argv[3]);
tag = atoi(argv[1]);
if (1 <= monat && monat <= 12 &&
1582 < jahr && jahr < 3000 &&
1 <= tag && tag <= anzProMonat(jahr,monat))
{
tage = Anzahl_Tage( jahr, monat, 1);
start = (tage + WOCHENTAG) % 7;
printcal(start, anzProMonat(jahr, monat), tag, monat, jahr);
return 0;
}
else
{
fprintf(stderr, "Monat zwischen 1 und 12 und Jahr zwischen "
"1583 und 2999\n"
"[Tag zwischen 1 und Anzahl für dieses Monat]\n");
return 2;
}
}
else if (argc == 1) /* aktuelles Monat */
{
time(&sec);
zeit = localtime(&sec);
tag = zeit->tm_mday;
monat = zeit->tm_mon + 1;
jahr = zeit->tm_year + 1900;
tage = Anzahl_Tage( jahr, monat, 1);
start = (tage + WOCHENTAG) % 7;
printcal(start, anzProMonat(jahr, monat), tag, monat, jahr);
return 0;
}
else
{
fprintf(stderr, "Aufruf:\n%s [[tag] monat jahr]\n", argv[0]);
return 1;
}
}
/*-------------------------- functions ------------------------------*/
/** Kalender ausgeben
* start ... Wochentag des 1. dieses Monats
* anz ... Anzahl der Tage dieses Monats
* heute ... Datum des heutigen Tages, 0, falls in einem anderen Monat
* monat ... Monat (1..12)
* jahr
*/
void printcal(int start, int anz, int heute, int monat, int jahr)
{
char *tage[] = { "Montag", "Dienstag", "Mittwoch", "Donnerstag",
"Freitag", "Samstag", "Sonntag" };
char *monate[] = { "Jänner", "Februar", "März", "April",
"Mai", "Juni", "Juli", "August",
"September", "Oktober", "November", "Dezember" };
int i;
int tag;
printf("%s %d\n\n", monate[monat-1], jahr);
for (i = 0; i < 7; i++)
{
printf("%10s ", tage[i]);
for (tag = i + 1 - start; tag < anz + 7 + start; tag += 7)
if (tag == heute && feiertag(jahr, monat, tag)
&& tag >= 1 && tag <= anz)
printf("[%2d]", tag);
else if (tag == heute && tag >= 1 && tag <= anz)
printf("<%2d>", tag);
else if (feiertag(jahr, monat, tag) && tag >= 1 && tag <= anz)
printf(":%2d:", tag);
else if (tag >= 1 && tag <= anz)
printf("%3d ", tag);
else
printf(" ");
printf("\n");
}
printf("\n");
printFeiertage(jahr, monat);
}
/*
* Function schaltjahr
*
* Zweck: Liefert 1, wenn angegebenes Jahr ein Schaltjahr ist
*
* Algorithmus:
* ab 1582 gilt folgende Regel für Schaltjahre:
* Ist die Jahreszahl durch 400 teilbar oder
* ist die Jahreszahl durch 4 teilbar aber nicht durch 100
* dann ist das Jahr ein Schaltjahr
*
* Parameter:
* IN: Jahr
* OUT:
*
* Return-Wert: 1 ... Schaltjahr
* 0 ... sonst
*/
int schaltjahr( int Jahr )
{
if ( Jahr % 400 == 0 )
return 1;
else if ( Jahr % 100 == 0 )
return 0;
else if ( Jahr % 4 == 0 )
return 1;
else
return 0;
}
int anzProMonat(int jahr, int monat)
{
switch(monat)
{
case 2:
return 28 + schaltjahr(jahr);
break;
case 4:
case 6:
case 9:
case 11:
return 30;
break;
default:
return 31;
}
}
/*
* Function Anzahl_Tage
*
* Zweck: Bestimmt die Anzahl der Tage ab 1.1.1582
*
* Algorithmus:
* Tag + Anzahl Tage für Monate + Anzahl Tage für Jahre
*
* Parameter:
* IN: Jahr, Monat, Tag
* OUT:
*
* Return-Wert: Anzahl der Tage ab 1.1.1582
*/
int Anzahl_Tage( int Jahr, int Monat, int Tag )
{
int j;
int m;
int tage = Tag; /* Monatstag */
/*
* Tage für Jahre berechnen
*/
for ( j = 1582; j < Jahr; j++ )
tage += 365 + schaltjahr( j );
/*
* Tage für Monate berechnen
*/
for ( m = 1; m < Monat; m++ )
switch( m )
{
case 2:
tage += 28 + schaltjahr( Jahr );
break;
case 4:
case 6:
case 9:
case 11:
tage += 30;
break;
default:
tage += 31;
}
return( tage );
}
/** Bestimmt Feiertag.
* @param jahr
* @param monat
* @param tag
* @return Nummer des Feiertags, 0 sonst
*/
int feiertag(int jahr, int monat, int tag)
{
int tagzahl, j, m, t;
ostern(jahr, &m, &t);
tagzahl = Anzahl_Tage(jahr, m, t);
if (monat == m && tag == t) /* Ostern */
return OSTERSONNTAG;
tag2datum(tagzahl + 1, &j, &m, &t);
if (monat == m && tag == t) /* Ostern */
return OSTERMONTAG;
tag2datum(tagzahl - 46, &j, &m, &t);
if (monat == m && tag == t) /* Aschermittwoch */
return ASCHERMITTWOCH;
tag2datum(tagzahl - 7, &j, &m, &t);
if (monat == m && tag == t) /* Palmsonntag */
return PALMSONNTAG;
tag2datum(tagzahl - 2, &j, &m, &t);
if (monat == m && tag == t) /* Karfreitag */
return KARFREITAG;
tag2datum(tagzahl + 49, &j, &m, &t);
if (monat == m && tag == t) /* Pfingstsonntag */
return PFINGSTSONNTAG;
tag2datum(tagzahl + 50, &j, &m, &t);
if (monat == m && tag == t) /* Pfingstmontag */
return PFINGSTMONTAG;
tag2datum(tagzahl + 56, &j, &m, &t);
if (monat == m && tag == t) /* Dreifaltigkeitssonntag */
return DREIFALTIGKEITSSONNTAG;
tag2datum(tagzahl + 60, &j, &m, &t);
if (monat == m && tag == t) /* Fronleichnam */
return FRONLEICHNAM;
if (monat == 1 && tag == 1) /* Neujahr */
return NEUJAHR;
if (monat == 1 && tag == 6) /* Heilige 3 Könige */
return HL3KOENIGE;
if (monat == 5 && tag == 1) /* Staatsfeiertag */
return STAATSFEIERTAG;
tag2datum(sonntag(jahr, 5, 13), &j, &m, &t);
if (monat == 5 && tag == t) /* Muttertag FIXME */
return MUTTERTAG;
if (monat == 8 && tag == 15) /* Mariahimmelfahrt */
return MARIAHIMMELFAHRT;
if (monat == 10 && tag == 26) /* Nationalfeiertag */
return NATIONALFEIERTAG;
if (monat == 10 && tag == 31) /* Reformationstag */
return REFORMATIONSTAG;
if (monat == 11 && tag == 1) /* Allerheiligen */
return ALLERHEILIGEN;
if (monat == 11 && tag == 2) /* Allersselen */
return ALLERSEELEN;
if (monat == 11)
{
if (sonntag(jahr, 12, 24) == Anzahl_Tage(jahr, 12, 24))
tagzahl = sonntag(jahr, 12, 24) - 21;
else
tagzahl = sonntag(jahr, 12, 24) - 28;
tag2datum(tagzahl, &j, &m, &t);
if (tag == t && m == 11) /* 1. Advent */
return ADVENT1;
}
if (monat == 12)
{
if (tag == 8) /* Maria Emfängnis */
return MARIAEMPFAENGNIS;
if (sonntag(jahr, 12, 24) == Anzahl_Tage(jahr, 12, 24))
tagzahl = sonntag(jahr, 12, 24) - 21;
else
tagzahl = sonntag(jahr, 12, 24) - 28;
tag2datum(tagzahl, &j, &m, &t);
if (tag == t && m == 12) /* 1. Advent */
return ADVENT1;
tag2datum(tagzahl+7, &j, &m, &t);
if (tag == t) /* 2. Advent */
return ADVENT2;
tag2datum(tagzahl+14, &j, &m, &t);
if (tag == t) /* 3. Advent */
return ADVENT3;
tag2datum(tagzahl+21, &j, &m, &t);
if (tag == t) /* 4. Advent */
return ADVENT4;
if (tag == 24) /* Hl. Abend */
return HEILIGABEND;
if (tag == 25) /* Christiani */
return CHRISTIANI;
if (tag == 26) /* Stefanitag */
return STEFANI;
if (tag == 31) /* Silvester :-) */
return SILVESTER;
}
return KEIN; /* Kein Feiertag */
}
void ostern( int jahr, int *monat, int *tag )
{
int a = jahr % 19;
int b = jahr / 100;
int c = jahr % 100;
int d = b / 4;
int e = b % 4;
int f = ( b + 8 ) / 25;
int g = ( b - f + 1 ) / 3;
int h = ( 19 * a + b - d - g + 15 ) % 30;
int i = c / 4;
int k = c % 4;
int l = ( 32 + 2 * e + 2 * i -h -k ) % 7;
int m = ( a + 11 * h + 22 * l ) / 451;
int p = ( h + l - 7 * m + 114 ) % 31;
*monat = ( h + l - 7 * m + 114 ) / 31;
*tag = p + 1;
}
void tag2datum( int tagzahl, int *jahr, int *monat, int *tag )
{
/*
* Jahr berechnen
*/
*jahr = 1582;
while ( tagzahl > 365 + schaltjahr( *jahr ) )
{
tagzahl -= 365 + schaltjahr( *jahr );
(*jahr)++;
}
/*
* Monat
*/
for ( *monat = 1; tagzahl > tagemonat( *jahr, *monat ); (*monat)++ )
tagzahl -= tagemonat( *jahr, *monat );
/*
* Tag
*/
*tag = tagzahl;
}
int sonntag( int jahr, int monat, int tag )
{
int tagzahl = Anzahl_Tage( jahr, monat, tag );
int wt = ( DONNERSTAG + tagzahl ) % 7;
if ( wt == SONNTAG ) /* bereits Sonntag */
return tagzahl;
else
return tagzahl + ( SONNTAG - wt );
}
int tagemonat( int jahr, int monat )
{
switch( monat )
{
case 2:
return 28 + schaltjahr( jahr );
break;
case 4:
case 6:
case 9:
case 11:
return 30;
break;
default:
return 31;
}
}
/** gib eine Liste der Feiertage aus.
* @param jahr IN
* @param monat OUT
*/
void printFeiertage(int jahr, int monat)
{
int i;
char *bez = "";
for (i = 1; i <= tagemonat(jahr, monat); i++)
{
bez = "";
switch (feiertag(jahr, monat, i))
{
case NEUJAHR:
bez = "Neujahr";
break;
case HL3KOENIGE:
bez = "Heilige Dreikönige";
break;
case ASCHERMITTWOCH:
bez = "Aschermittwoch";
break;
case PALMSONNTAG:
bez = "Palmsonntag";
break;
case KARFREITAG:
bez = "Karfreitag";
break;
case OSTERSONNTAG:
bez = "Ostersonntag";
break;
case OSTERMONTAG:
bez = "Ostermontag";
break;
case STAATSFEIERTAG:
bez = "Staatsfeiertag";
break;
case MUTTERTAG:
bez = "Muttertag";
break;
case PFINGSTSONNTAG:
bez = "Pfingstsonntag";
break;
case PFINGSTMONTAG:
bez = "Pfingstmontag";
break;
case DREIFALTIGKEITSSONNTAG:
bez = "Dreifaltigkeitssonntag";
break;
case FRONLEICHNAM:
bez = "Fronleichnam";
break;
case MARIAHIMMELFAHRT:
bez = "Maria Himmelfahrt";
break;
case NATIONALFEIERTAG:
bez = "Nationalfeiertag";
break;
case REFORMATIONSTAG:
bez = "Reformationstag";
break;
case ALLERHEILIGEN:
bez = "Allerheiligen";
break;
case ALLERSEELEN:
bez = "Allerseelen";
break;
case MARIAEMPFAENGNIS:
bez = "Maria Empfängnis";
break;
case ADVENT1:
bez = "1. Advent";
break;
case ADVENT2:
bez = "2. Advent";
break;
case ADVENT3:
bez = "3. Advent";
break;
case ADVENT4:
bez = "4. Advent";
break;
case HEILIGABEND:
bez = "Heiligabend";
break;
case CHRISTIANI:
bez = "Christtag";
break;
case STEFANI:
bez = "Stefanitag";
break;
case SILVESTER:
bez = "Silvester :-)";
break;
}
if (strlen(bez) > 0)
printf("%2d.%d. %s\n", i, monat, bez);
}
}
Abonnieren Posts [Atom]

