Ein Beispiel für nicht-ASCII-Ziffern? Wie wär's mit 698:
Code: Alles auswählen
In [25]: ds = list(filter(str.isdigit, (chr(i) for i in range(0x110000))))
In [26]: len(ds)
Out[26]: 708
Code: Alles auswählen
In [25]: ds = list(filter(str.isdigit, (chr(i) for i in range(0x110000))))
In [26]: len(ds)
Out[26]: 708
Code: Alles auswählen
int("۵۷")
Code: Alles auswählen
In [59]: def f(x):
...: try:
...: int(x)
...: return True
...: except:
...: return False
...:
In [60]: ds2 = [x for x in ds if not f(x)]
In [61]: len(ds2)
Out[61]: 128
Das ist korrekt.__blackjack__ hat geschrieben: ↑Mittwoch 26. September 2018, 22:09 @codemode89: Ganze 50% wiederholter Code in jeder der drei Funktionen ist keine Code-Duplizierung für Dich?
Code: Alles auswählen
i=0
while i <10
i+=1
return i
Code: Alles auswählen
def is_valid_number(number_string):
return not re.fullmatch('\d+', number_string, re.A) is None
Code: Alles auswählen
private static boolean isValidNumber(String validationObject) {
return validationObject.matches("[0-9]+");
}
private static int askForAge(String prompt) {
String consoleInput;
do {
System.out.println(prompt);
consoleInput = SCANNER.nextLine();
}while(!isValidNumber(consoleInput));
return Integer.parseInt(consoleInput);
}
Code: Alles auswählen
def frage_nach_zahl(type="Zahl"):
while True:
eingabe_von_console = input('Bitte {} eingeben: '.format(type))
try:
return int(eingabe_von_console)
except ValueError:
pass # keine Zahl eingegeben
Code: Alles auswählen
i=0
while i <10
i+=1
return i
Code: Alles auswählen
for i in range(10):
pass
return i
Code: Alles auswählen
return 9
Ähm das war nur ein Beispiel wie eine Standard while schleife definiert ist.
Code: Alles auswählen
condition
while(!condition)
do something
Clean Code ist schön älter ja, aber es behandelt etliche zeitlose Konzepte unabhängig von jeglicher Programmiersprache.codemode89 hat geschrieben: ↑Donnerstag 27. September 2018, 08:30 Ich verstehe deinen Standpunkt ja, es wird ja auch teilweise in Python Fachliteratur so angeraten mit dem while true , aber ich sehe es halt anders.
i muss schon initialisiert werden für die condition, das ist exakt das was ich bei meiner Funktion auch gemacht habe.
Wie machst du es denn das er nur 0-9 als Input akzeptiert?Sirius3 hat geschrieben: ↑Donnerstag 27. September 2018, 09:16 @codemode89: das Patternmatching ist entweder nicht ausreichend oder schränkt zu sehr ein. Ausnahmen mit try-Block sind ja gerade dazu da, bei Falscheingaben entsprechend reagieren zu können. Das Pattern zu verstehen ist um einiges komplizierter, als der fast schon literarische Text: "versuche: wandle Text in Zahl. Falls das nicht klappt, sage, 'das war keine Zahl' ".
Code: Alles auswählen
while true
try
if
continue
catch
continue
finally
Code: Alles auswählen
do
while(condition)
Das dachte ich auch malcodemode89 hat geschrieben: ↑Mittwoch 26. September 2018, 17:58 Und als weiterer Tipp nutze Englische Namen. Du wirst auf lange Sicht eh nicht ums englische drum herum kommen.
Code: Alles auswählen
from goto import with_goto
@with_goto
def f():
i = 0
label .loop_start
if i >= 9: goto .loop_end
i += 1; goto .loop_start
label .loop_end
return i
Und wirklich aufgebläht finde ich das hier auch in Java nicht:EAFP
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.
[…]
LBYL
Look before you leap. This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.
Code: Alles auswählen
private static int askPositiveInteger(String prompt) {
while (true) {
try {
return Integer.parseUnsignedInt(askString(prompt));
} catch (NumberFormatException e) {
System.out.println("Bitte eine positive ganze Zahl eingeben!");
}
}
}
War wie jetzt zum dritten mal gesagt nur ein Beispiel um den Aufbau__blackjack__ hat geschrieben: ↑Donnerstag 27. September 2018, 10:54 Diese Schleife ist so auch kein Standardkonstrukt, wie ja bereits gesagt wurde. Auch in vielen anderen Programmiersprachen würde man hier standardmässig eine ``for``-Schleife verwenden. Ansonsten könnte man ja
Code: Alles auswählen
condition
while (!condition)
do something
Code: Alles auswählen
private static int askPositiveInteger(String prompt) {
while (true) {
try {
return Integer.parseUnsignedInt(askString(prompt));
} catch (NumberFormatException e) {
System.out.println("Bitte eine positive ganze Zahl eingeben!");
}
}
}
Code: Alles auswählen
private static int askPositiveInteger(String prompt) {
while (true) {
try {
int number = Integer.parseUnsignedInt(askString(prompt));
if(number>30 && number<100)
return number;
} catch (NumberFormatException e) {
System.out.println("Bitte eine positive ganze Zahl eingeben!");
}
}
}
Hast du zu 100% recht.__blackjack__ hat geschrieben: ↑Donnerstag 27. September 2018, 10:54 Zum `is_valid_number()` fällt auf das da ``not`` gefolgt von einem recht langem Ausdruck und dann ein ``is None`` steht. Das kann man sehr leicht übersehen und sollte deshalb besser als ``[…] is not None`` geschrieben werden. Oder man lässt das einfach komplett weg, denn ein `Match`-Objekt ist ja immer ”wahr” und `None` ist immer ”unwahr” in boole'schen Kontexten.
Darauf gehe ich nicht weiter ein mehr als 2 mal zu bestätigen das ihr Recht habt, das es nicht der pythonic way ist kann ich auch nicht tun ^^__blackjack__ hat geschrieben: ↑Donnerstag 27. September 2018, 10:54 Das ist eben idiomatisches Python. Dazu mal zwei Einträge aus dem Glossar der Python-Dokumentation:
EAFP
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.
[…]
LBYL
Look before you leap. This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.
Das bezog sich auf deine drei Input-Methoden, die alle bis auf Text & Praedikat das gleiche machen. Und in einer Sprache, in der Funktionen Mitbuerger erster Klass sind, ist beides problemlos loesbar ohne sich so viel zu wiederholen. Und die while-Schleife ist nun schon mehrfach nicht wegen DRY, sondern unidiomatischem Python-Code angesprochen worden. Auch anderswo stehen augenscheinlich Waende rum.codemode89 hat geschrieben: ↑Donnerstag 27. September 2018, 11:47
DRY Prinzip verletzt in dem ich eine Variable initialisiere? Ich denke nicht.
Nochmal DRY Prinzip nachlesen und verstehen was da der ausschlaggebende Punkt ist.
siehe mein letzten Post
und return type.
Jede get_input Methode hat eine eigene condition sowie ein anderen return value das einzige was sie sich teilen ist das in jeder eine while schleife läuft
Code: Alles auswählen
condition = [code und daten die die bedingung ausmachen]
while (!condition)
do something
condition = [code und daten die die bedingung ausmachen]
Code: Alles auswählen
private static int askAge(int lowerLimit, int upperLimit) {
if (lowerLimit > upperLimit) {
throw new IllegalArgumentException("lower limit must not be greater than upper limit");
}
while (true) {
try {
final var result = Integer.parseInt(askTrimmedNonEmptyString("Alter eingeben: "));
if (lowerLimit <= result && result <= upperLimit) {
return result;
}
System.out.printf(
"Bitte eine Zahl zwischen %d und %d (inklusive) eingeben!",
lowerLimit, upperLimit);
} catch (NumberFormatException e) {
System.out.println("Bitte eine ganze Zahl eingeben!");
}
}
}
Code: Alles auswählen
def ask_until_correct(message, errormessage, conversion):
while True:
try:
return conversion(input(message))
except ValueError:
print(errormessage)
def alterspraedikat(value):
alter = int(value)
if 1 <= alter <= 120:
return alter
raise ValueError
def namenspraedikat(value):
if not len(value):
raise ValueError
return value
def ja_nein_frage(value):
try:
return dict(j=True, y=True, n=False)[value.lower()[0]]
except (IndexError, KeyError):
raise ValueError
def main():
alter = ask_until_correct(
"Bitte Alter angeben: ",
"Falsche Eingabe, Alter zwischen 1 und 120",
alterspraedikat,
)
name = ask_until_correct(
"Bitte Namen angeben: ",
"Falsche Eingabe. Ein Name kann nicht leer sein",
namenspraedikat,
)
raucher = ask_until_correct(
"Sind Sie Raucher?",
"Bitte mit Ja/ja/yes/j/y oder Nein/nein/no/n antworten",
ja_nein_frage,
)
print("hallo", name, "im Alter von", alter)
print("Rauchen ist ungesund" if raucher else "Nichtraucher haben bessere Zaehne")
if __name__ == '__main__':
main()
Nein es war beides mal eine Zuweisung mittels eines trivialen Aufrufs der Input Methode und das do somethin wird durch diese Zuweisung ersetzt nicht erweitert.__blackjack__ hat geschrieben: ↑Donnerstag 27. September 2018, 12:58 @codemode89: Der Aufbau war in deinem praktischen Beispiel
Und das in den eckigen Klammern stand da zweimal identisch im Code und war nicht nur ein trivialer AufrufCode: Alles auswählen
condition = [code und daten die die bedingung ausmachen] while (!condition) do something condition = [code und daten die die bedingung ausmachen]
Code: Alles auswählen
def nochmal():
eingabe_von_console = input('Nochmal y oder n : ').lower()
while eingabe_von_console != "y" and eingabe_von_console != "n":
eingabe_von_console = input('Nochmal y oder n : ').lower()
return eingabe_von_console == "y"
Nein deine Methode macht 2 Sachen und die sollen nun beide voneinander getrennt werden.__blackjack__ hat geschrieben: ↑Donnerstag 27. September 2018, 12:58 `askPositiveInteger()` macht genau eine Sache: Den Benutzer solange nach einer Eingabe fragen bis der eine positive, ganze Zahl eingegeben hat. Das ist auf dieser Abstraktionsebene ein Schritt. Ansonsten würde dieses Argument ja gegen jede Methode sprechen die mehr als eine Operation beinhaltet und `main()`-Methoden komplett verboten machen, denn die machen ja *alles*!
Eine Methode die eine ganze Zahl mit Unter- und Obergrenze abfragt, würde in der Tat so ähnlich aussehen. Ungefähr so:Was ich da jetzt extrahieren soll ist mir allerdings nicht klar‽ Und warum?Code: Alles auswählen
private static int askAge(int lowerLimit, int upperLimit) { if (lowerLimit > upperLimit) { throw new IllegalArgumentException("lower limit must not be greater than upper limit"); } while (true) { try { final var result = Integer.parseInt(askTrimmedNonEmptyString("Alter eingeben: ")); if (lowerLimit <= result && result <= upperLimit) { return result; } System.out.printf( "Bitte eine Zahl zwischen %d und %d (inklusive) eingeben!", lowerLimit, upperLimit); } catch (NumberFormatException e) { System.out.println("Bitte eine ganze Zahl eingeben!"); } } }
Code: Alles auswählen
import java.util.Optional;
import java.util.Scanner;
import java.util.function.Function;
final class Main {
private static final Scanner SCANNER = new Scanner(System.in);
private Main() {}
private static <T> T askUntilCorrect(String message, String errorMessage,
Function<String, Optional<T>> converter) {
while (true) {
System.out.print(message);
final var result = converter.apply(SCANNER.nextLine());
if (result.isPresent()) {
return result.get();
}
System.out.println(errorMessage);
}
}
private static Optional<Integer> convertAge(String value) {
try {
final var age = Integer.parseInt(value);
return 1 <= age && age <= 120 ? Optional.of(age) : Optional.empty();
} catch (NumberFormatException e) {
return Optional.empty();
}
}
private static Optional<String> convertName(String value) {
return (value.isEmpty()) ? Optional.empty() : Optional.of(value);
}
private static Optional<Boolean> convertYesNo(String value) {
if (value.isEmpty()) {
return Optional.empty();
} else {
switch (value.toLowerCase().charAt(0)) {
case 'y':
case 'j': return Optional.of(true);
case 'n': return Optional.of(false);
default: return Optional.empty();
}
}
}
public static void main(String... args) {
final var age = askUntilCorrect("Bitte Alter angeben: ",
"Falsche Eingabe, Alter zwischen 1 und 120", Main::convertAge);
final var name = askUntilCorrect("Bitte Namen angeben: ",
"Falsche Eingabe. Ein Name kann nicht leer sein.", Main::convertName);
final var doesSmoke = askUntilCorrect("Sind sie Raucher? ",
"Bitte mit Ja/ja/yes/j/y oder Nein/nein/no/n antworten", Main::convertYesNo);
System.out.printf("Hallo %s im Alter von %d.\n", name, age);
System.out.println((doesSmoke) ? "Rauchen ist ungesund." : "Nichtraucher haben bessere Zähne.");
}
}
Code: Alles auswählen
private tailrec fun <T> askUntilCorrect(message: String, errorMessage: String,
convert: (s: String) -> T?): T {
print(message)
val result = convert(readLine() ?: error("Can't read from stdin"))
return if (result == null) {
println(errorMessage)
askUntilCorrect(message, errorMessage, convert)
} else result
}
fun main(args: Array<String>) {
val age = run {
val minAge = 1
val maxAge = 120
askUntilCorrect(
"Bitte Alter angeben: ",
"Falsche Eingabe, Alter zwischen $minAge und $maxAge."
) { string -> string.toIntOrNull()?.takeIf { it in minAge..maxAge } }
}
val name = askUntilCorrect(
"Bitte Namen angeben: ",
"Falsche Eingabe. Ein Name kann nicht leer sein."
) { it.trim().takeUnless(String::isEmpty) }
val doesSmoke = askUntilCorrect(
"Sind sie Raucher? ",
"Bitte mit Ja/ja/yes/j/y oder Nein/nein/no/n antworten"
) {
when (it.getOrNull(0)?.toLowerCase()) {
'y', 'j' -> true
'n' -> false
else -> null
}
}
println("Hallo $name im Alter von $age.")
println(if (doesSmoke) "Rauchen ist ungesund." else "Nichtraucher haben bessere Zähne.")
}