Battle of the Languages
Java 16 vs Python 3.9
Michael Inden
Freiberuflicher Consultant und Trainer
Speaker Intro
• Michael Inden, Jahrgang 1971
• Diplom-Informatiker, C.v.O. Uni Oldenburg
• ~8 ¼ Jahre SSE bei Heidelberger Druckmaschinen AG in Kiel
• ~6 ¾ Jahre TPL, SA bei IVU Traffic Technologies AG in Aachen
• ~4 ¼ Jahre LSA / Trainer bei Zühlke Engineering AG in Zürich
• ~3 Jahre TL / CTO bei Direct Mail Informatics / ASMIQ in Zürich
• Freiberuflicher Consultant, Trainer und Konferenz-Speaker
• Autor und Gutachter beim dpunkt.verlag
E-Mail: michael.inden@hotmail.ch
Blog: https://jaxenter.de/author/minden
https://www.wearedevelopers.com/magazine/java-records
Kurse: Bitte sprecht mich an!
Agenda
Workshop Contents
• PART 1: Einführung
• PART 2: Programmier-Puzzles
• Primzahlen und das Sieb des Eratosthenes
• Vokale raten
• Wohlgeformte Klammern
• Flood Fill (sogar mit Muster)
• Quick Sort (endlich verstehen)
• PART 3: Fazit
PART 1:
Einführung
Einführung
• Als Java-Entwickler fühlt man sich oft pudelwohl in seinem Universum.
• ABER: Python wird immer populärer ...
• In dieser Session wollen wir Java und Python miteinander vergleichen.
• Dazu kurzweilige und unterhaltsame kleine Programmier-Challenges
• Zudem sehen wir, wie sich JUnit und Pytest beim Formulieren lesbarer
Tests schlagen.
Zunächst ein Blick zurück
• Java ist letztes Jahr 25 geworden
• Lange Historie von 1995 bis 2020: Vom Newcomer zum etablierten Allzwecktool
• Viele interessante und wichtige Entwicklungen, wie Generics, Lambdas,
Streams u.v.m.
https://www.tiobe.com/tiobe-index/
Nach 25 Jahren:
Wo geht die Reise hin
und wie sieht es aktuell
mit der Konkurrenz aus?
Zunächst ein Blick zurück
https://www.tiobe.com/tiobe-index/
Popularitätstrends der Top 10 Programmiersprachen
https://www.tiobe.com/tiobe-index/
Vergleich
• Wer nutzt Python?
• Wer nutzt Java?
https://trio.dev/blog/python-vs-java
Syntax im Kurzüberblick
Syntax Quick Refresher
Java Python
Variablen jshell> int age = 50
age ==> 50
jshell> long durationInMs = 2745
durationInMs ==> 2745
jshell> String message = "Hello JAX"
message ==> "Hello JAX"
>>> age = 50
>>> durationInMs = 2745
>>> message = "Hello JAX"
String-Add jshell> "The answer is " + 42 +
" but " + false
$9 ==> "The answer is 42 but false"
>>> "The answer is " + str(42) +
" but " + str(False)
'The answer is 42 but False'
Ausgaben jshell> System.out.println(age + " "
+ durationInMs + " " + message)
50 2745 Hello JAX
>>> print(age, durationInMs, message)
50 2745 Hello JAX
Syntax Quick Refresher
Java Python
for-Schleife jshell> for (int i = 0; i < 10; i++)
...> System.out.println("i: " + i);
>>> for i in range(0, 10):
... print("i: ", i)
Blöcke if (a > b) {
System.out.println("a > b")
}
if a > b:
print("a > b")
Logik Ops && || ! and or not
Conditional Op condition ? alt1 : alt2 alt1 if condition else alt2
Miniprogramm public class SimpleExample {
public static void main(String[] args)
{
System.out.println("7*2=" + (7*2);
}
}
def main():
print("7*2", 7*2)
if __name__== "__main__":
main()
Syntax Quick Refresher
Java Python
Listen List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++)
{
numbers.add(i);
}
System.out.println(numbers.get(7))
7
>>> numbers = []
>>> for i in range(10):
>>> numbers.append(i)
>>> numbers[7]
7
Listen II List<Integer> numbers = List.of(0,1,2,3,4) numbers = [0,1,2,3,4]
Listen III -/- even = [x for x in range(10)
if x % 2 == 0]
[0, 2, 4, 6, 8]
Syntax Quick Refresher
Java Python
Miniklasse class TwoMembers
{
public int val1;
public String val2;
TwoMembers(int val1, String val2)
{
this.val1 = val1;
this.val2 = val2;
}
}
class TwoMembers:
def __init__(self, val1,
val2):
self.val1 = val1
self.val2 = val2
Tupel jshell> record Tuple(int val1, int val2,
...> int val3, int val4)
...> {}
jshell> new Tuple(7, 2, 7, 1).val3()
$5 ==> 7
>>> tuple = (7, 2, 7, 1)
>>> tuple[2]
7
PART 2:
Programmier-Puzzles
Primzahlen
und das Sieb des Eratosthenes
Aufgabenstellung
Schreiben Sie eine Methode / Funktion calcPrimesUpTo() zur Berechnung
aller Primzahlen bis zu einem vorgegebenen Wert. Zur Erinnerung: Eine
Primzahl ist eine natürliche Zahl, die größer als 1 und ausschließlich durch sich
selbst und durch 1 teilbar ist.
Lösungsstrategie / Algorithmus
Sieb des Eratosthenes => Primzahlen bis zu einem Maximalwert bestimmen:
1. Initial werden alle Zahlen von zwei bis zu dem Maximalwert aufgeschrieben, etwa:
2. Schrittweise diejenigen Zahlen gestrichen, die keine Primzahlen sein können.
1. Die kleinste unmarkierte Zahl, hier die 2, entspricht der ersten Primzahl. Nun streicht man alle
Vielfachen davon, also im Beispiel 4, 6, 8, 10, 12, 14:
2. Weiter geht es mit der Zahl 3. Das ist die zweite Primzahl. Nun werden wieder die Vielfachen
gestrichen, nachfolgend 6, 9, 12, 15:
def calc_primes_up_to(max_value):
is_potentially_prime = [True for _ in range(1, max_value + 2)]
for number in range(2, int(max_value / 2) + 1):
if is_potentially_prime[number]:
erase_multiples_of_current(is_potentially_prime, number)
return build_primes_list(is_potentially_prime)
public static List<Integer> calcPrimesUpTo(final int maxValue)
{
final boolean[] isPotentiallyPrime = new boolean[maxValue + 1];
Arrays.fill(isPotentiallyPrime, true);
for (int i = 2; i <= maxValue / 2; i++)
if (isPotentiallyPrime[i])
eraseMultiplesOfCurrent(isPotentiallyPrime, i);
return buildPrimesList(isPotentiallyPrime);
}
def erase_multiples_of_current(values, number):
for n in range(number + number, 
len(values), number):
values[n] = False
def build_primes_list(is_potentially_prime):
return [number for number in range(2,
len(is_potentially_prime))
if is_potentially_prime[number]]
void eraseMultiplesOfCurrent(boolean[]
isPotentiallyPrime, int i)
{
for (int n = i + i;
n < isPotentiallyPrime.length; n = n + i)
isPotentiallyPrime[n] = false;
}
List<Integer> buildPrimesList(boolean[]
isPotentiallyPrime)
{
List<Integer> primes = new ArrayList<>();
for (int i = 2;
i < isPotentiallyPrime.length; i++)
{
if (isPotentiallyPrime[i])
primes.add(i);
}
return primes;
}
def input_and_expected():
return [(2, [2]),
(3, [2, 3]),
(10, [2, 3, 5, 7]),
(15, [2, 3, 5, 7, 11, 13]),
(25, [2, 3, 5, 7, 11, 13, 17, 19, 23])]
@pytest.mark.parametrize("n, expected",
input_and_expected())
def test_calc_primes_up_to(n, expected):
assert calc_primes_up_to(n) == expected
@ParameterizedTest(name = "calcPrimes({0}) = {1}")
@MethodSource("argumentProvider")
void testCalcPrimesUpTo(int n, List<Integer> expected)
{
List<Integer> result = calcPrimesUpTo(n);
assertEquals(expected, result);
}
static Stream<Arguments> argumentProvider()
{
return Stream.of(Arguments.of(2, List.of(2)),
Arguments.of(3, List.of(2, 3)),
Arguments.of(10, List.of(2, 3, 5, 7)),
Arguments.of(15, List.of(2, 3, 5, 7,
11, 13)),
Arguments.of(25, List.of(2, 3, 5, 7,
11, 13, 17,
19, 23)));
}
DEMO
Vokale raten
H.rzl.ch w.llk.mm.n z.r B.ttl.-S.ss..n
D-r R--s-f-hr-r -mpf--hlt J-v-
F-t d-rch d-- Pyth-n Ch-ll-ng-
Aufgabenstellung
Erstelle ein Ratespiel ähnlich zu »Glücksrad«: Dabei geht es um das Erraten
von Wörtern, Sätzen oder Redewendungen, in denen Vokale fehlen:
H.rzl.ch w.llk.mm.n z.r B.ttl.-S.ss..n
Schreibe eine Methode / Funktion translateVowel(), die in einem Text alle
Vokale durch ein Zeichen bzw. eine Zeichenfolge ersetzt.*
*Neben dem Ratequiz kann man so auch Wortähnlichkeiten basierend auf den Konsonanten ermitteln.
def translate_vowel(text, replacement):
translated = ""
for letter in text:
if is_vowel(letter):
translated += replacement
else:
translated += letter
return translated
def is_vowel(letter):
return letter in "AÄEIOÖUüaäeioöuü"
String translateVowel(String input,
String replacement)
{
String inputUpper = input.toUpperCase();
String result = "";
for (int i = 0; i < inputUpper.length(); i++)
{
char current = inputUpper.charAt(i);
if (isVowel(current))
result += replacement;
else
result += current;
}
return result;
}
boolean isVowel(char current)
{
return "AEIOUÄÖÜ".contains("" +
Character.toUpperCase(current));
}
DEMO
Wohlgeformte Klammern
Aufgabenstellung
Schreibe eine Methode / Funktion checkBraces(), die prüft, ob die als String
gegebene Folge von runden Klammern jeweils passende (sauber geschachtelte)
Klammerpaare enthält.
Lösungsstrategie / Algorithmus
• 1. Idee: Alle möglichen Kombinationen auszuprobieren => SCHLECHT
• 2. Idee: Zähle die Anzahl öffnender Klammern und vergleiche diese mit der
Anzahl schließender Klammern
• Detail: Reihenfolge: Es darf keine schließende Klammer vor öffnender
Klammer kommen!
• Algorithmus: Durchlaufe den String von vorne nach hinten. Ist das
aktuelle Zeichen eine öffnende Klammer, so wird der Zähler für öffnende
Klammer um eins erhöht. Ist es eine schließende Klammer, so reduziere
den Zähler um den Wert eins. Ist dieser kleiner 0, wurde eine schließende
Klammer ohne zugehörige öffnende Klammer gefunden. Zum Schluss
muss die Anzahl gleich 0 sein, damit es einer sauberen Klammerung
entspricht.
def check_braces(input):
opening_count = 0
for ch in input:
if ch == "(":
opening_count += 1
elif ch == ")":
opening_count -= 1
if opening_count < 0:
return False
return opening_count == 0
boolean checkBraces(final String input)
{
int openingCount = 0;
for (char ch : input.toCharArray())
{
if (ch == '(')
{
openingCount++;
}
else if (ch == ')')
{
openingCount--;
if (openingCount < 0)
return false;
}
}
return openingCount == 0;
}
@pytest.mark.parametrize("input, expected, hint",
[("(())", True, "ok"),
("()()", True, "ok"),
("(()))((())", False, "nicht sauber geschachtelt"),
("(()", False, "keine passende Klammerung"),
(")()", False, "startet mit schliessender Klammer")])
def test_check_braces(input, expected, hint):
assert check_braces(input) == expected
@ParameterizedTest(name="checkBraces(''{0}'') -- Hinweis: {2}" )
@CsvSource({ "(()), true, ok",
"()(), true, ok",
"(()))((()), false, nicht sauber geschachtelt",
"((), false, keine passende Klammerung",
")(), false, startet mit schliessender Klammer" })
void checkBraces(String input, boolean expected, String hint)
{
boolean result = Ex09_SimpleBracesChecker.checkBraces(input);
assertEquals(expected, result);
}
DEMO
Flood Fill
(sogar mit Muster)
Aufgabenstellung
Schreibe eine Methode / Funktion floodFill(), die in einem Array alle freien
Felder mit einem bestimmten Wert befüllt.
## ##
# ######## #
# #
#o #
# ######## #
## ##
## ##
# ######## #
#********#
#********#
# ######## #
## ##
## o ##
# ######## #
# #
# #
# ######## #
## ##
##***********##
#**########***#
**# #***
**# #***
#**########***#
##***********##
void floodFill(char[][] values, int x, int y)
{
if (x < 0 || y < 0 ||
y >= values.length ||
x >= values[y].length)
return;
if (values[y][x] == ' ')
{
values[y][x] = '*';
floodFill(values, x, y - 1);
floodFill(values, x + 1, y);
floodFill(values, x, y + 1);
floodFill(values, x - 1, y);
}
}
def flood_fill(values2dim, x, y):
max_y, max_x = get_dimension(values2dim)
if x < 0 or y < 0 or 
x >= max_x or y >= max_y:
return
if values2dim[y][x] == ' ':
values2dim[y][x] = '*'
flood_fill(values2dim, x, y - 1)
flood_fill(values2dim, x + 1, y)
flood_fill(values2dim, x, y + 1)
flood_fill(values2dim, x - 1, y)
def get_dimension(values2dim):
if isinstance(values2dim, list):
return (len(values2dim), len(values2dim[0]))
if isinstance(values2dim, np.ndarray):
return values2dim.shape
raise ValueError("unsupported type", type(values2dim))
Was ist denn nun
mit dem Muster?
Aufgabenstellung
Erweitern wir also die Implementierung so, dass nun eine Fläche auch mit
Muster gefüllt werden kann!
##..|..|..|..|..|..|..|..#
#*-#################--*-##
.|# ##|..|..|..|###
-*# ##*--*--*--*-##
#|.################|..|..#
##--*--*--*--*--*--*--*-##
###.|..|..|..|..|..|..|###
##--*--*--*--*--*--*--*-##
#|..|..|..|..|..|..|..|..#
## o #
# ################# ##
# ## ###
# ## ##
# ################ #
## ##
### ###
## ##
# #
void floodFill(char[][] values, int x,
int y, char[][] pattern)
{
if (x < 0 || y < 0 ||
y >= values.length ||
x >= values[y].length)
return;
if (values[y][x] == ' ')
{
values[y][x] = findFillChar(x, y, pattern);
floodFill(values, x, y – 1, pattern);
floodFill(values, x + 1, y, pattern);
floodFill(values, x, y + 1, pattern);
floodFill(values, x - 1, y, pattern);
}
}
def flood_fill(values2dim, x, y, pattern):
max_y, max_x = get_dimension(values2dim)
if x < 0 or y < 0 or 
x >= max_x or y >= max_y:
return
if values2dim[y][x] == ' ':
values2dim[y][x] = find_fill_char(y, x,
pattern)
flood_fill(values2dim, x, y - 1, pattern)
flood_fill(values2dim, x + 1, y, pattern)
flood_fill(values2dim, x, y + 1, pattern)
flood_fill(values2dim, x - 1, y, pattern)
char findFillChar(int x, int y,
char[][] pattern)
{
final int maxY = pattern.length;
final int maxX = pattern[0].length;
return pattern[y % maxY][x % maxX];
}
def find_fill_char(y, x, pattern):
max_y, max_x = get_dimension(pattern)
return pattern[y % max_y][x % max_x]
DEMO
Quick Sort
Aufgabenstellung
Implementiere eine Sortierung von Zahlen mithilfe des Quick Sort
Verfahrens.
Lösungsstrategie / Algorithmus
• Quick Sort basiert auf einem Divide-and-Conquer-Ansatz
• Zerteilt den zu sortierende Datenbestand in immer kleinere Teile.
• Spezielles Element (Pivot) legt die Unterteilung fest.
• Alle Elemente des Teilbereichs mit Wert kleiner oder gleich werden links bzw. die
größeren werden rechts vom Pivot anordnet.
• Rekursive Wiederholung bis die Teilbereiche nur noch einelementig sind.
static List<Integer> quickSort(final List<Integer> values)
{
if (values.size() <= 1)
return values;
Integer pivot = values.get(0);
var belowOrEquals = values.stream().skip(1).filter(cur -> cur <= pivot).toList();
var aboves = values.stream().skip(1).filter(cur -> cur > pivot).toList();
var sortedLowersPart = quickSort(belowOrEquals);
var sortedUppersPart = quickSort(aboves);
final List<Integer> result = new ArrayList<>();
result.addAll(sortedLowersPart);
result.add(pivot);
result.addAll(sortedUppersPart);
return result;
}
def quick_sort(values):
if len(values) <= 1:
return values
pivot = values[0]
below_or_equals = [value for value in values[1:] if value <= pivot]
aboves = [value for value in values[1:] if value > pivot]
sorted_lowers_part = quick_sort(below_or_equals)
sorted_uppers_part = quick_sort(aboves)
return sorted_lowers_part + [pivot] + sorted_uppers_part
Geht es noch
kompakter?
def quick_sort_short(values):
if len(values) <= 1:
return values
return quick_sort_short([val for val in values[1:] if val <= values[0]]) + 
[values[0]] + 
quick_sort_short([val for val in values[1:] if val > values[0]])
@ParameterizedTest(name = "{0} should be sorted to {1}")
@MethodSource("createInputAndExpected")
void testQuickSort(int[] values, int[] expected)
{
var sortedValues = Ex06_Quicksort.quickSort(values);
assertArrayEquals(expected, sortedValues);
}
private static Stream<Arguments> createInputAndExpected()
{
return Stream.of(Arguments.of(new int[] { 5, 2, 7, 1, 4, 3, 6, 8 },
new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }),
Arguments.of(new int[] { 5, 2, 7, 9, 6, 3, 1, 4, 8 },
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }),
Arguments.of(new int[] { 5, 2, 7, 9, 6, 3, 1, 4, 2, 3, 8 },
new int[] { 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9 }));
}
@pytest.mark.parametrize("values, expected",
[([5, 2, 7, 1, 4, 3, 6, 8],
[1, 2, 3, 4, 5, 6, 7, 8]),
([5, 2, 7, 9, 6, 3, 1, 4, 8],
[1, 2, 3, 4, 5, 6, 7, 8, 9]),
[[5, 2, 7, 9, 6, 3, 1, 4, 2, 3, 8],
[1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9]]])
def test_quick_sort_inplace(values, expected):
sorted_values = quick_sort(values)
assert sorted_values == expected
DEMO
PART 3:
Fazit
Fazit
Java Python
faster easier
a bit verbose short and concise
reliable prone to careless mistakes
Vergleich Java - Python
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
5
PERFORMANCE
LERNKURVE
LESBARKEIT
ELEGANZ
POPULARITÄT
ZUKUNFTSTREND
TOOLING
ÖKOSYSTEM
Questions?
Hilfe
Thank You

Battle of the Languages: Java und Python im Wettstreit beim Lösen von Programmier-Challenges

  • 1.
    Battle of theLanguages Java 16 vs Python 3.9 Michael Inden Freiberuflicher Consultant und Trainer
  • 2.
    Speaker Intro • MichaelInden, Jahrgang 1971 • Diplom-Informatiker, C.v.O. Uni Oldenburg • ~8 ¼ Jahre SSE bei Heidelberger Druckmaschinen AG in Kiel • ~6 ¾ Jahre TPL, SA bei IVU Traffic Technologies AG in Aachen • ~4 ¼ Jahre LSA / Trainer bei Zühlke Engineering AG in Zürich • ~3 Jahre TL / CTO bei Direct Mail Informatics / ASMIQ in Zürich • Freiberuflicher Consultant, Trainer und Konferenz-Speaker • Autor und Gutachter beim dpunkt.verlag E-Mail: michael.inden@hotmail.ch Blog: https://jaxenter.de/author/minden https://www.wearedevelopers.com/magazine/java-records Kurse: Bitte sprecht mich an!
  • 3.
  • 4.
    Workshop Contents • PART1: Einführung • PART 2: Programmier-Puzzles • Primzahlen und das Sieb des Eratosthenes • Vokale raten • Wohlgeformte Klammern • Flood Fill (sogar mit Muster) • Quick Sort (endlich verstehen) • PART 3: Fazit
  • 5.
  • 6.
    Einführung • Als Java-Entwicklerfühlt man sich oft pudelwohl in seinem Universum. • ABER: Python wird immer populärer ... • In dieser Session wollen wir Java und Python miteinander vergleichen. • Dazu kurzweilige und unterhaltsame kleine Programmier-Challenges • Zudem sehen wir, wie sich JUnit und Pytest beim Formulieren lesbarer Tests schlagen.
  • 7.
    Zunächst ein Blickzurück • Java ist letztes Jahr 25 geworden • Lange Historie von 1995 bis 2020: Vom Newcomer zum etablierten Allzwecktool • Viele interessante und wichtige Entwicklungen, wie Generics, Lambdas, Streams u.v.m. https://www.tiobe.com/tiobe-index/
  • 8.
    Nach 25 Jahren: Wogeht die Reise hin und wie sieht es aktuell mit der Konkurrenz aus?
  • 9.
    Zunächst ein Blickzurück https://www.tiobe.com/tiobe-index/
  • 10.
    Popularitätstrends der Top10 Programmiersprachen https://www.tiobe.com/tiobe-index/
  • 11.
    Vergleich • Wer nutztPython? • Wer nutzt Java? https://trio.dev/blog/python-vs-java
  • 12.
  • 13.
    Syntax Quick Refresher JavaPython Variablen jshell> int age = 50 age ==> 50 jshell> long durationInMs = 2745 durationInMs ==> 2745 jshell> String message = "Hello JAX" message ==> "Hello JAX" >>> age = 50 >>> durationInMs = 2745 >>> message = "Hello JAX" String-Add jshell> "The answer is " + 42 + " but " + false $9 ==> "The answer is 42 but false" >>> "The answer is " + str(42) + " but " + str(False) 'The answer is 42 but False' Ausgaben jshell> System.out.println(age + " " + durationInMs + " " + message) 50 2745 Hello JAX >>> print(age, durationInMs, message) 50 2745 Hello JAX
  • 14.
    Syntax Quick Refresher JavaPython for-Schleife jshell> for (int i = 0; i < 10; i++) ...> System.out.println("i: " + i); >>> for i in range(0, 10): ... print("i: ", i) Blöcke if (a > b) { System.out.println("a > b") } if a > b: print("a > b") Logik Ops && || ! and or not Conditional Op condition ? alt1 : alt2 alt1 if condition else alt2 Miniprogramm public class SimpleExample { public static void main(String[] args) { System.out.println("7*2=" + (7*2); } } def main(): print("7*2", 7*2) if __name__== "__main__": main()
  • 15.
    Syntax Quick Refresher JavaPython Listen List<Integer> numbers = new ArrayList<>(); for (int i = 0; i < 10; i++) { numbers.add(i); } System.out.println(numbers.get(7)) 7 >>> numbers = [] >>> for i in range(10): >>> numbers.append(i) >>> numbers[7] 7 Listen II List<Integer> numbers = List.of(0,1,2,3,4) numbers = [0,1,2,3,4] Listen III -/- even = [x for x in range(10) if x % 2 == 0] [0, 2, 4, 6, 8]
  • 16.
    Syntax Quick Refresher JavaPython Miniklasse class TwoMembers { public int val1; public String val2; TwoMembers(int val1, String val2) { this.val1 = val1; this.val2 = val2; } } class TwoMembers: def __init__(self, val1, val2): self.val1 = val1 self.val2 = val2 Tupel jshell> record Tuple(int val1, int val2, ...> int val3, int val4) ...> {} jshell> new Tuple(7, 2, 7, 1).val3() $5 ==> 7 >>> tuple = (7, 2, 7, 1) >>> tuple[2] 7
  • 17.
  • 18.
    Primzahlen und das Siebdes Eratosthenes
  • 19.
    Aufgabenstellung Schreiben Sie eineMethode / Funktion calcPrimesUpTo() zur Berechnung aller Primzahlen bis zu einem vorgegebenen Wert. Zur Erinnerung: Eine Primzahl ist eine natürliche Zahl, die größer als 1 und ausschließlich durch sich selbst und durch 1 teilbar ist.
  • 20.
    Lösungsstrategie / Algorithmus Siebdes Eratosthenes => Primzahlen bis zu einem Maximalwert bestimmen: 1. Initial werden alle Zahlen von zwei bis zu dem Maximalwert aufgeschrieben, etwa: 2. Schrittweise diejenigen Zahlen gestrichen, die keine Primzahlen sein können. 1. Die kleinste unmarkierte Zahl, hier die 2, entspricht der ersten Primzahl. Nun streicht man alle Vielfachen davon, also im Beispiel 4, 6, 8, 10, 12, 14: 2. Weiter geht es mit der Zahl 3. Das ist die zweite Primzahl. Nun werden wieder die Vielfachen gestrichen, nachfolgend 6, 9, 12, 15:
  • 21.
    def calc_primes_up_to(max_value): is_potentially_prime =[True for _ in range(1, max_value + 2)] for number in range(2, int(max_value / 2) + 1): if is_potentially_prime[number]: erase_multiples_of_current(is_potentially_prime, number) return build_primes_list(is_potentially_prime) public static List<Integer> calcPrimesUpTo(final int maxValue) { final boolean[] isPotentiallyPrime = new boolean[maxValue + 1]; Arrays.fill(isPotentiallyPrime, true); for (int i = 2; i <= maxValue / 2; i++) if (isPotentiallyPrime[i]) eraseMultiplesOfCurrent(isPotentiallyPrime, i); return buildPrimesList(isPotentiallyPrime); }
  • 22.
    def erase_multiples_of_current(values, number): forn in range(number + number, len(values), number): values[n] = False def build_primes_list(is_potentially_prime): return [number for number in range(2, len(is_potentially_prime)) if is_potentially_prime[number]] void eraseMultiplesOfCurrent(boolean[] isPotentiallyPrime, int i) { for (int n = i + i; n < isPotentiallyPrime.length; n = n + i) isPotentiallyPrime[n] = false; } List<Integer> buildPrimesList(boolean[] isPotentiallyPrime) { List<Integer> primes = new ArrayList<>(); for (int i = 2; i < isPotentiallyPrime.length; i++) { if (isPotentiallyPrime[i]) primes.add(i); } return primes; }
  • 23.
    def input_and_expected(): return [(2,[2]), (3, [2, 3]), (10, [2, 3, 5, 7]), (15, [2, 3, 5, 7, 11, 13]), (25, [2, 3, 5, 7, 11, 13, 17, 19, 23])] @pytest.mark.parametrize("n, expected", input_and_expected()) def test_calc_primes_up_to(n, expected): assert calc_primes_up_to(n) == expected @ParameterizedTest(name = "calcPrimes({0}) = {1}") @MethodSource("argumentProvider") void testCalcPrimesUpTo(int n, List<Integer> expected) { List<Integer> result = calcPrimesUpTo(n); assertEquals(expected, result); } static Stream<Arguments> argumentProvider() { return Stream.of(Arguments.of(2, List.of(2)), Arguments.of(3, List.of(2, 3)), Arguments.of(10, List.of(2, 3, 5, 7)), Arguments.of(15, List.of(2, 3, 5, 7, 11, 13)), Arguments.of(25, List.of(2, 3, 5, 7, 11, 13, 17, 19, 23))); }
  • 24.
  • 25.
    Vokale raten H.rzl.ch w.llk.mm.nz.r B.ttl.-S.ss..n D-r R--s-f-hr-r -mpf--hlt J-v- F-t d-rch d-- Pyth-n Ch-ll-ng-
  • 26.
    Aufgabenstellung Erstelle ein Ratespielähnlich zu »Glücksrad«: Dabei geht es um das Erraten von Wörtern, Sätzen oder Redewendungen, in denen Vokale fehlen: H.rzl.ch w.llk.mm.n z.r B.ttl.-S.ss..n Schreibe eine Methode / Funktion translateVowel(), die in einem Text alle Vokale durch ein Zeichen bzw. eine Zeichenfolge ersetzt.* *Neben dem Ratequiz kann man so auch Wortähnlichkeiten basierend auf den Konsonanten ermitteln.
  • 27.
    def translate_vowel(text, replacement): translated= "" for letter in text: if is_vowel(letter): translated += replacement else: translated += letter return translated def is_vowel(letter): return letter in "AÄEIOÖUüaäeioöuü" String translateVowel(String input, String replacement) { String inputUpper = input.toUpperCase(); String result = ""; for (int i = 0; i < inputUpper.length(); i++) { char current = inputUpper.charAt(i); if (isVowel(current)) result += replacement; else result += current; } return result; } boolean isVowel(char current) { return "AEIOUÄÖÜ".contains("" + Character.toUpperCase(current)); }
  • 28.
  • 29.
  • 30.
    Aufgabenstellung Schreibe eine Methode/ Funktion checkBraces(), die prüft, ob die als String gegebene Folge von runden Klammern jeweils passende (sauber geschachtelte) Klammerpaare enthält.
  • 31.
    Lösungsstrategie / Algorithmus •1. Idee: Alle möglichen Kombinationen auszuprobieren => SCHLECHT • 2. Idee: Zähle die Anzahl öffnender Klammern und vergleiche diese mit der Anzahl schließender Klammern • Detail: Reihenfolge: Es darf keine schließende Klammer vor öffnender Klammer kommen! • Algorithmus: Durchlaufe den String von vorne nach hinten. Ist das aktuelle Zeichen eine öffnende Klammer, so wird der Zähler für öffnende Klammer um eins erhöht. Ist es eine schließende Klammer, so reduziere den Zähler um den Wert eins. Ist dieser kleiner 0, wurde eine schließende Klammer ohne zugehörige öffnende Klammer gefunden. Zum Schluss muss die Anzahl gleich 0 sein, damit es einer sauberen Klammerung entspricht.
  • 32.
    def check_braces(input): opening_count =0 for ch in input: if ch == "(": opening_count += 1 elif ch == ")": opening_count -= 1 if opening_count < 0: return False return opening_count == 0 boolean checkBraces(final String input) { int openingCount = 0; for (char ch : input.toCharArray()) { if (ch == '(') { openingCount++; } else if (ch == ')') { openingCount--; if (openingCount < 0) return false; } } return openingCount == 0; }
  • 33.
    @pytest.mark.parametrize("input, expected, hint", [("(())",True, "ok"), ("()()", True, "ok"), ("(()))((())", False, "nicht sauber geschachtelt"), ("(()", False, "keine passende Klammerung"), (")()", False, "startet mit schliessender Klammer")]) def test_check_braces(input, expected, hint): assert check_braces(input) == expected @ParameterizedTest(name="checkBraces(''{0}'') -- Hinweis: {2}" ) @CsvSource({ "(()), true, ok", "()(), true, ok", "(()))((()), false, nicht sauber geschachtelt", "((), false, keine passende Klammerung", ")(), false, startet mit schliessender Klammer" }) void checkBraces(String input, boolean expected, String hint) { boolean result = Ex09_SimpleBracesChecker.checkBraces(input); assertEquals(expected, result); }
  • 34.
  • 35.
  • 36.
    Aufgabenstellung Schreibe eine Methode/ Funktion floodFill(), die in einem Array alle freien Felder mit einem bestimmten Wert befüllt. ## ## # ######## # # # #o # # ######## # ## ## ## ## # ######## # #********# #********# # ######## # ## ## ## o ## # ######## # # # # # # ######## # ## ## ##***********## #**########***# **# #*** **# #*** #**########***# ##***********##
  • 37.
    void floodFill(char[][] values,int x, int y) { if (x < 0 || y < 0 || y >= values.length || x >= values[y].length) return; if (values[y][x] == ' ') { values[y][x] = '*'; floodFill(values, x, y - 1); floodFill(values, x + 1, y); floodFill(values, x, y + 1); floodFill(values, x - 1, y); } } def flood_fill(values2dim, x, y): max_y, max_x = get_dimension(values2dim) if x < 0 or y < 0 or x >= max_x or y >= max_y: return if values2dim[y][x] == ' ': values2dim[y][x] = '*' flood_fill(values2dim, x, y - 1) flood_fill(values2dim, x + 1, y) flood_fill(values2dim, x, y + 1) flood_fill(values2dim, x - 1, y) def get_dimension(values2dim): if isinstance(values2dim, list): return (len(values2dim), len(values2dim[0])) if isinstance(values2dim, np.ndarray): return values2dim.shape raise ValueError("unsupported type", type(values2dim))
  • 38.
    Was ist dennnun mit dem Muster?
  • 39.
    Aufgabenstellung Erweitern wir alsodie Implementierung so, dass nun eine Fläche auch mit Muster gefüllt werden kann! ##..|..|..|..|..|..|..|..# #*-#################--*-## .|# ##|..|..|..|### -*# ##*--*--*--*-## #|.################|..|..# ##--*--*--*--*--*--*--*-## ###.|..|..|..|..|..|..|### ##--*--*--*--*--*--*--*-## #|..|..|..|..|..|..|..|..# ## o # # ################# ## # ## ### # ## ## # ################ # ## ## ### ### ## ## # #
  • 40.
    void floodFill(char[][] values,int x, int y, char[][] pattern) { if (x < 0 || y < 0 || y >= values.length || x >= values[y].length) return; if (values[y][x] == ' ') { values[y][x] = findFillChar(x, y, pattern); floodFill(values, x, y – 1, pattern); floodFill(values, x + 1, y, pattern); floodFill(values, x, y + 1, pattern); floodFill(values, x - 1, y, pattern); } } def flood_fill(values2dim, x, y, pattern): max_y, max_x = get_dimension(values2dim) if x < 0 or y < 0 or x >= max_x or y >= max_y: return if values2dim[y][x] == ' ': values2dim[y][x] = find_fill_char(y, x, pattern) flood_fill(values2dim, x, y - 1, pattern) flood_fill(values2dim, x + 1, y, pattern) flood_fill(values2dim, x, y + 1, pattern) flood_fill(values2dim, x - 1, y, pattern)
  • 41.
    char findFillChar(int x,int y, char[][] pattern) { final int maxY = pattern.length; final int maxX = pattern[0].length; return pattern[y % maxY][x % maxX]; } def find_fill_char(y, x, pattern): max_y, max_x = get_dimension(pattern) return pattern[y % max_y][x % max_x]
  • 42.
  • 43.
  • 44.
    Aufgabenstellung Implementiere eine Sortierungvon Zahlen mithilfe des Quick Sort Verfahrens.
  • 45.
    Lösungsstrategie / Algorithmus •Quick Sort basiert auf einem Divide-and-Conquer-Ansatz • Zerteilt den zu sortierende Datenbestand in immer kleinere Teile. • Spezielles Element (Pivot) legt die Unterteilung fest. • Alle Elemente des Teilbereichs mit Wert kleiner oder gleich werden links bzw. die größeren werden rechts vom Pivot anordnet. • Rekursive Wiederholung bis die Teilbereiche nur noch einelementig sind.
  • 46.
    static List<Integer> quickSort(finalList<Integer> values) { if (values.size() <= 1) return values; Integer pivot = values.get(0); var belowOrEquals = values.stream().skip(1).filter(cur -> cur <= pivot).toList(); var aboves = values.stream().skip(1).filter(cur -> cur > pivot).toList(); var sortedLowersPart = quickSort(belowOrEquals); var sortedUppersPart = quickSort(aboves); final List<Integer> result = new ArrayList<>(); result.addAll(sortedLowersPart); result.add(pivot); result.addAll(sortedUppersPart); return result; }
  • 47.
    def quick_sort(values): if len(values)<= 1: return values pivot = values[0] below_or_equals = [value for value in values[1:] if value <= pivot] aboves = [value for value in values[1:] if value > pivot] sorted_lowers_part = quick_sort(below_or_equals) sorted_uppers_part = quick_sort(aboves) return sorted_lowers_part + [pivot] + sorted_uppers_part
  • 48.
  • 49.
    def quick_sort_short(values): if len(values)<= 1: return values return quick_sort_short([val for val in values[1:] if val <= values[0]]) + [values[0]] + quick_sort_short([val for val in values[1:] if val > values[0]])
  • 50.
    @ParameterizedTest(name = "{0}should be sorted to {1}") @MethodSource("createInputAndExpected") void testQuickSort(int[] values, int[] expected) { var sortedValues = Ex06_Quicksort.quickSort(values); assertArrayEquals(expected, sortedValues); } private static Stream<Arguments> createInputAndExpected() { return Stream.of(Arguments.of(new int[] { 5, 2, 7, 1, 4, 3, 6, 8 }, new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }), Arguments.of(new int[] { 5, 2, 7, 9, 6, 3, 1, 4, 8 }, new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }), Arguments.of(new int[] { 5, 2, 7, 9, 6, 3, 1, 4, 2, 3, 8 }, new int[] { 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9 })); }
  • 51.
    @pytest.mark.parametrize("values, expected", [([5, 2,7, 1, 4, 3, 6, 8], [1, 2, 3, 4, 5, 6, 7, 8]), ([5, 2, 7, 9, 6, 3, 1, 4, 8], [1, 2, 3, 4, 5, 6, 7, 8, 9]), [[5, 2, 7, 9, 6, 3, 1, 4, 2, 3, 8], [1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9]]]) def test_quick_sort_inplace(values, expected): sorted_values = quick_sort(values) assert sorted_values == expected
  • 52.
  • 53.
  • 54.
    Fazit Java Python faster easier abit verbose short and concise reliable prone to careless mistakes
  • 55.
    Vergleich Java -Python 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 PERFORMANCE LERNKURVE LESBARKEIT ELEGANZ POPULARITÄT ZUKUNFTSTREND TOOLING ÖKOSYSTEM
  • 56.
  • 57.
  • 58.