SlideShare ist ein Scribd-Unternehmen logo
1 von 58
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

Scalaz introduction for Java programmers
Scalaz introduction for Java programmersScalaz introduction for Java programmers
Scalaz introduction for Java programmersBernhard Huemer
 
C# Workshop - Threading
C# Workshop - ThreadingC# Workshop - Threading
C# Workshop - ThreadingQiong Wu
 
Übungsaufgaben
ÜbungsaufgabenÜbungsaufgaben
Übungsaufgabenmaikinger
 
T2 s4 javascriptfuerfortgeschrittene
T2 s4 javascriptfuerfortgeschritteneT2 s4 javascriptfuerfortgeschrittene
T2 s4 javascriptfuerfortgeschrittenedominion
 
Übungsaufgaben SS2010
Übungsaufgaben SS2010Übungsaufgaben SS2010
Übungsaufgaben SS2010maikinger
 
Parallele Softwareentwicklung mit .NET 4.0
Parallele Softwareentwicklung mit .NET 4.0Parallele Softwareentwicklung mit .NET 4.0
Parallele Softwareentwicklung mit .NET 4.0Qiong Wu
 
Java Script Ist Anders
Java Script Ist AndersJava Script Ist Anders
Java Script Ist Andersjlink
 
Reguläre Ausdrucke (PCRE)
Reguläre Ausdrucke (PCRE)Reguläre Ausdrucke (PCRE)
Reguläre Ausdrucke (PCRE)Dominik Siebel
 
Java Streams und Lambdas
Java Streams und LambdasJava Streams und Lambdas
Java Streams und LambdasNane Kratzke
 
Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)Sven Efftinge
 
Was geht mit Java 17?
Was geht mit Java 17?Was geht mit Java 17?
Was geht mit Java 17?gedoplan
 
Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003
Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003
Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003Brigitte Jellinek
 

Was ist angesagt? (19)

Scalaz introduction for Java programmers
Scalaz introduction for Java programmersScalaz introduction for Java programmers
Scalaz introduction for Java programmers
 
C# Workshop - Threading
C# Workshop - ThreadingC# Workshop - Threading
C# Workshop - Threading
 
Pyparsing
PyparsingPyparsing
Pyparsing
 
Übungsaufgaben
ÜbungsaufgabenÜbungsaufgaben
Übungsaufgaben
 
T2 s4 javascriptfuerfortgeschrittene
T2 s4 javascriptfuerfortgeschritteneT2 s4 javascriptfuerfortgeschrittene
T2 s4 javascriptfuerfortgeschrittene
 
Übungsaufgaben SS2010
Übungsaufgaben SS2010Übungsaufgaben SS2010
Übungsaufgaben SS2010
 
Do while
Do whileDo while
Do while
 
Parallele Softwareentwicklung mit .NET 4.0
Parallele Softwareentwicklung mit .NET 4.0Parallele Softwareentwicklung mit .NET 4.0
Parallele Softwareentwicklung mit .NET 4.0
 
WiSe 2013 | Programmierpraktikum C++ - 01_Basics
WiSe 2013 | Programmierpraktikum C++ - 01_BasicsWiSe 2013 | Programmierpraktikum C++ - 01_Basics
WiSe 2013 | Programmierpraktikum C++ - 01_Basics
 
Java Script Ist Anders
Java Script Ist AndersJava Script Ist Anders
Java Script Ist Anders
 
Reguläre Ausdrucke (PCRE)
Reguläre Ausdrucke (PCRE)Reguläre Ausdrucke (PCRE)
Reguläre Ausdrucke (PCRE)
 
Java Streams und Lambdas
Java Streams und LambdasJava Streams und Lambdas
Java Streams und Lambdas
 
Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)Vermisste Sprachfeatures in Java (german)
Vermisste Sprachfeatures in Java (german)
 
Java threading
Java threadingJava threading
Java threading
 
Tutorium 4
Tutorium 4Tutorium 4
Tutorium 4
 
Was geht mit Java 17?
Was geht mit Java 17?Was geht mit Java 17?
Was geht mit Java 17?
 
Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1
 
Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003
Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003
Perl - die Taschenkettensäge unter den Programmiersprachen - Vortrag 2003
 
BIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen I
BIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen IBIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen I
BIT I WiSe 2014 | Basisinformationstechnologie I - 08: Programmiersprachen I
 

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

Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)GEEKcon
 
Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"
Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"
Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"DevDay Dresden
 
Python crash-kurs
Python crash-kursPython crash-kurs
Python crash-kursklausbremer
 
nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins
nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins
nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins Christian Kauhaus
 
Skalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoSkalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoFrank Müller
 
Einführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit JavaEinführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit JavaMarcel Rehfeld
 
Coffee Backone Introduction
Coffee Backone IntroductionCoffee Backone Introduction
Coffee Backone IntroductionTino Isnich
 
Bei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareBei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareSAP SE
 
Warum Python?
Warum Python?Warum Python?
Warum Python?tharwan
 
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgenSEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgenDr. Herwig Henseler
 
Komponententests und Testabdeckung
Komponententests und TestabdeckungKomponententests und Testabdeckung
Komponententests und TestabdeckungChristian Baranowski
 
Vorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, MapsVorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, MapsMichael Zilske
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeFrank Müller
 

Ähnlich wie Battle of the Languages: Java und Python im Wettstreit beim Lösen von Programmier-Challenges (20)

Ruby, Ruby, Ruby!
Ruby, Ruby, Ruby!Ruby, Ruby, Ruby!
Ruby, Ruby, Ruby!
 
Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)Differenzial Analyse in der Praxis (Florian Walther)
Differenzial Analyse in der Praxis (Florian Walther)
 
Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"
Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"
Dev Day 2019: Mirko Zeibig – "Hallo " <> "Elixir"
 
Python crash-kurs
Python crash-kursPython crash-kurs
Python crash-kurs
 
nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins
nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins
nagiosplugin - eine Python-Biblioth­ek für Monitoring-Plug­ins
 
Typescript
TypescriptTypescript
Typescript
 
Skalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoSkalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google Go
 
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
Microbenchmarks - Wer nicht weiß, was er misst misst MistMicrobenchmarks - Wer nicht weiß, was er misst misst Mist
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
 
Einführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit JavaEinführung in Scala im Vergleich mit Java
Einführung in Scala im Vergleich mit Java
 
Software-Tests automatisch erzeugen: Frische Ansätze für Forschung, Praxis un...
Software-Tests automatisch erzeugen: Frische Ansätze für Forschung, Praxis un...Software-Tests automatisch erzeugen: Frische Ansätze für Forschung, Praxis un...
Software-Tests automatisch erzeugen: Frische Ansätze für Forschung, Praxis un...
 
Python
PythonPython
Python
 
Coffee Backone Introduction
Coffee Backone IntroductionCoffee Backone Introduction
Coffee Backone Introduction
 
Bei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der BanensoftwareBei uns testen lauter Affen - Das Ende der Banensoftware
Bei uns testen lauter Affen - Das Ende der Banensoftware
 
Warum Python?
Warum Python?Warum Python?
Warum Python?
 
C++11 und c++14
C++11 und c++14C++11 und c++14
C++11 und c++14
 
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgenSEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
SEROM 2018 - 11/14/17/20 - C++ gestern heute und morgen
 
Explain explain
Explain explainExplain explain
Explain explain
 
Komponententests und Testabdeckung
Komponententests und TestabdeckungKomponententests und Testabdeckung
Komponententests und Testabdeckung
 
Vorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, MapsVorlesung 7: Laufzeit, Maps
Vorlesung 7: Laufzeit, Maps
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare Systeme
 

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

  • 1. Battle of the Languages Java 16 vs Python 3.9 Michael Inden Freiberuflicher Consultant und Trainer
  • 2. 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!
  • 4. 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
  • 6. 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.
  • 7. 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/
  • 8. Nach 25 Jahren: Wo geht die Reise hin und wie sieht es aktuell mit der Konkurrenz aus?
  • 9. Zunächst ein Blick zurück https://www.tiobe.com/tiobe-index/
  • 10. Popularitätstrends der Top 10 Programmiersprachen https://www.tiobe.com/tiobe-index/
  • 11. Vergleich • Wer nutzt Python? • Wer nutzt Java? https://trio.dev/blog/python-vs-java
  • 13. 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
  • 14. 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()
  • 15. 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]
  • 16. 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
  • 18. Primzahlen und das Sieb des Eratosthenes
  • 19. 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.
  • 20. 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:
  • 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): 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; }
  • 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. DEMO
  • 25. 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-
  • 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. DEMO
  • 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. DEMO
  • 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 denn nun mit dem Muster?
  • 39. Aufgabenstellung Erweitern wir also die 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. DEMO
  • 44. Aufgabenstellung Implementiere eine Sortierung von 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(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; }
  • 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
  • 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. DEMO
  • 54. Fazit Java Python faster easier a bit 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
  • 57. Hilfe