Hallo!
Eine Funktion nested_sum soll die Elemente vom Typ integer, die in einer verschachtelten Liste sind (nested list) zusammen-/aufaddieren.
Ich möchte eine Exeption vom Typ TypeError werfen (und fangen?), wenn das zu untersuchende Einzelelement kein Integer ist und wenn die Einzelelemente nicht in einer verschachtelten Liste (nested list) sind. Bitte ein komplettes Beispiel, aus dem hervorgeht, WIE DER EXEPTION ÜBERHAUPT DER ERWARTETE TYP MITGETEILT WIRD.
Ich habe das gegoogelt, finde aber nur try- und catch-Blöcke, ohne dass ich wüsste, wie man der Exeption denn nun sagt: Hier muss eine Liste sein, sonst wirf, hier muss ein integer sein, sonst wirf.
Strawk
Bitte ein komplettes Beispiel für die TypeError-Exeption
@Strawk: Das sagt man der Exception gar nicht. Eine Ausnahme prüft nichts, das musst Du selbst tun. Oder Du machst etwas ohne zu prüfen und das löst eine Ausnahme aus die Du behandeln kannst. Komplettes Beispiel um eine `TypeError`-Ausnahme auszulösen:
Komplettes Beispiel um eine `TypeError`-Ausnahme zu behandeln:
Der letzte Kommentar ist wirklich wichtig! Wenn man da nichts sinnvolles macht, dann sollte man es ganz bleiben lassen, denn das ist dann in dem Fall die sinnvollere Alternative.
Statt mit einer Suchmaschine solche Grundlagen zu suchen, macht es vielleicht mehr Sinn ein zusammenhängendes Tutorial für die Grundlagen zu verwenden. In der Python-Dokumentation befindet sich eins. Das hat auch ein Kapitel zu Ausnahmen und Ausnahmebehandlung.
Falls das eine Hausaufgabe ist, wird eventuell tatsächlich verlangt, das Du auf ganze Zahlen und Listen testest. Das verhindert allerdings, dass man auch andere addierbare Typen und Sequenzen verwendet. Eine generischere Lösung würde einfach versuchen die Objekte als iterier- und addierbar zu behandeln und entsprechend auf Ausnahmen reagieren. Also zum Beispiel die Iteration versuchen, und wenn das nicht geht, das Objekt als addierbar behandeln. Solltest Du auf Typen testen müssen, brauchst Du noch `isinstance()`. Oder `functools.singledispatch()` oder den Backport davon für Python 2.
Code: Alles auswählen
raise TypeError('was immer als text sinn macht')
Code: Alles auswählen
try:
# irgendwas das einen TypeError auslösen kann
except TypeError as error:
# Hier *sinnvoll* (das ist *ganz* wichtig!) auf die Ausnahme reagieren
Statt mit einer Suchmaschine solche Grundlagen zu suchen, macht es vielleicht mehr Sinn ein zusammenhängendes Tutorial für die Grundlagen zu verwenden. In der Python-Dokumentation befindet sich eins. Das hat auch ein Kapitel zu Ausnahmen und Ausnahmebehandlung.
Falls das eine Hausaufgabe ist, wird eventuell tatsächlich verlangt, das Du auf ganze Zahlen und Listen testest. Das verhindert allerdings, dass man auch andere addierbare Typen und Sequenzen verwendet. Eine generischere Lösung würde einfach versuchen die Objekte als iterier- und addierbar zu behandeln und entsprechend auf Ausnahmen reagieren. Also zum Beispiel die Iteration versuchen, und wenn das nicht geht, das Objekt als addierbar behandeln. Solltest Du auf Typen testen müssen, brauchst Du noch `isinstance()`. Oder `functools.singledispatch()` oder den Backport davon für Python 2.
Der Exception wird nichts mitgeteilt. Die wird geworfen. WARUM sie geworfen wird liegt in deiner Hand. ZB weil du mit "isinstace(item, list)" geprueft hast, ob etwas eine Liste ist. Oder mit "isinstance(item, (int, long))" eine Ganzzahl.
- Strawk
- User
- Beiträge: 227
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Ich kann dem die zu verwendende Syntax nicht entnehmen. Ist da irgendwo ein "if" drin, muss das irgendwo ein "if" rein? Bitte ausführlicher, genauer. Danke! Wenn ich der Variable "l" einen Einzelwert zuweise, dann muss die Exeption ausgelöst werden, denn laut Aufgabe, MUSS es eine Liste sein. Dennoch löst l = 'willi' keine/n TypError aus, denn das ist eine legale Zuweisung. WO WIRD DER EXEPTION BEIGEBRACHT/MITGETEILT, was zulässig ist und was nicht?
Ich programmiere erfolglos, also bin ich nicht.
- Strawk
- User
- Beiträge: 227
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Bitte den betreffenden Codeschnipsel hier komplett wiedergeben, inklusive
try
except
raise
catch
Wo kommt was hin und wo steht der If-Zweig? (Hier Beispiel nur Liste oder keine Liste)
Danke! :K
try
except
raise
catch
Wo kommt was hin und wo steht der If-Zweig? (Hier Beispiel nur Liste oder keine Liste)
Danke! :K
Ich programmiere erfolglos, also bin ich nicht.
@Strawk: Ich denke das ist *Deine* Aufgabe. Auch ``if`` ist Thema im Tutorial in der Python-Dokumentation.
- Strawk
- User
- Beiträge: 227
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Ich versuche mich seit 2009 in VBA und seit 2011 in PHP (zugegeben mit mäßigem Erfolg) und weiß, wie "if" funktioniert. Was ich nicht weiß und gern von euch wüsste: Wie und wo (rein von der Syntax/Befehlsabfolge her) wird definiert, DASS die Exception DANN geworfen werden soll.
Denn: Wenn y = 0 ist, wird x/y scheitern. l = 'willi' scheitert aber nicht; ich muss das Scheitern selber implementieren.
*verzweifel*
Denn: Wenn y = 0 ist, wird x/y scheitern. l = 'willi' scheitert aber nicht; ich muss das Scheitern selber implementieren.
*verzweifel*
Ich programmiere erfolglos, also bin ich nicht.
@Strawk: Du weisst alles was man braucht. Wie ``if`` funktioniert, wie man eine Ausnahme auslöst, und welche Funktion man zum Testen auf Typen benutzt. Bis auf das ``if`` haben wir alles gezeigt was man braucht.
Edit: So sähe es übrigens mit `singledispatch()` aus:
Edit: So sähe es übrigens mit `singledispatch()` aus:
Code: Alles auswählen
from __future__ import absolute_import, division, print_function
try:
from functools import singledispatch
except ImportError:
from singledispatch import singledispatch
@singledispatch
def nested_sum(item):
raise TypeError('unexpected value of type {0.__name__}'.format(type(item)))
def identity(item):
return item
nested_sum.register(int, identity)
try:
nested_sum.register(long, identity)
except NameError:
pass # Python >2 has no `long` type anymore.
@nested_sum.register(list)
def _(items):
return sum(nested_sum(item) for item in items)
def main():
print(nested_sum(42))
print(nested_sum([1, 2, [4711, 23], 42]))
print(nested_sum(1000000000000000000000000000000000000))
print(nested_sum(None))
if __name__ == '__main__':
main()
Genau. Wenn y = 0 ist, dann hast Du Glück. Die Ausnahme wirft sich von alleine. Manuell wird eine mit 'raise' geworfen. Nun mußt Du nur noch testen, wann das erforderlich sein soll, z.B. bei I = 'willi'. Eine klassische, häufig vorkommende Situation.Strawk hat geschrieben:Denn: Wenn y = 0 ist, wird x/y scheitern. l = 'willi' scheitert aber nicht; ich muss das Scheitern selber implementieren.
- Strawk
- User
- Beiträge: 227
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Code: Alles auswählen
def nested_sum(l):
try:
if not isinstance(l, list):
raise TypeError
except TypeError:
print 'no list'
i = 0
for e in l:
try:
if not isinstance(e, list):
raise TypeError
except TypeError:
print 'no list'
i1 = 0
for e1 in e:
try:
if not isinstance(e1, int):
raise TypeError
except TypeError:
print 'no integer'
i1 += e1
i += i1
return i
l = [['willi',2,2],[3,3,3],[4,4,4]]
print nested_sum(l)
Zuletzt geändert von Anonymous am Montag 15. Mai 2017, 22:26, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Ich programmiere erfolglos, also bin ich nicht.
Ausnahmen auszulösen um sie dann sofort abzufangen ist sinnlos. Dann kannst du doch gleich ein print in den if Block packen.
Und auch wenn das jetzt kein schöner Code ist - eigentlich sollte es klappen. Was passiert denn?
Und auch wenn das jetzt kein schöner Code ist - eigentlich sollte es klappen. Was passiert denn?
- Strawk
- User
- Beiträge: 227
- Registriert: Mittwoch 15. Februar 2017, 11:42
- Wohnort: Aachen
- Kontaktdaten:
Hallo!
Ich bekam nicht meine eigenen Fehlermeldungen, sondern Sachen wie: "int is not iterable".
Hier eine hoffentlich bessere Version. Hat das Sinn, was ich gestrickt habe?
Grüße
Strawk
Code: Alles auswählen
def nested_sum(l):
try:
if not isinstance(l, list):
raise TypeError
except TypeError:
return 'no list'
i = 0
for e in l:
try:
if not isinstance(e, list):
raise TypeError
except TypeError:
return 'no list'
i1 = 0
for e1 in e:
try:
if not isinstance(e1, int):
raise TypeError
except TypeError:
return 'no integer'
i1 += e1
i += i1
return i
l = [[2,2,2],[3,3,3],7]
print nested_sum(l)
l = [['willi',2,2],[3,3,3],[4,4,4]]
print nested_sum(l)
l = [[2,2,2],[3,3,3],[4,4,4]]
print nested_sum(l)
l = 'willi'
print nested_sum(l)
Hier eine hoffentlich bessere Version. Hat das Sinn, was ich gestrickt habe?
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
@Strawk: Na das Problem ist wie schon gesagt das Du die Ausnahmen die Du auslöst auch gleich wieder ”behandelst” und zwar in dem Du eine Ausgabe mit `print()` machst, und dann der Code aber weitergeht als wenn die Ausnahme gar nicht da gewesen wäre.
Du willst doch eigentlich prüfen ob es sich um eine Liste handelt, und dann damit etwas bestimmtes machen, oder ob es sich um eine ganze Zahl handelt, und damit dann etwas bestimmtes machen, oder ob es weder Liste noch Zahl war, und *nur dann* einen `TypeError` auslösen. Den Liste und Zahl sind ja keine Fehler.
Ausserdem gehe ich mal ganz stark davon aus, das „nested list“ jede beliebige mögliche Verschachtelung meint, also beispielsweise auch ``[1, 2, [3, [4, 5]], 6, [[7]]]``. Und nicht nur etwas ”Zweidimensionales” wo nur auf der zweiten Ebene die Zahlen und nur Zahlen stehen.
Du willst doch eigentlich prüfen ob es sich um eine Liste handelt, und dann damit etwas bestimmtes machen, oder ob es sich um eine ganze Zahl handelt, und damit dann etwas bestimmtes machen, oder ob es weder Liste noch Zahl war, und *nur dann* einen `TypeError` auslösen. Den Liste und Zahl sind ja keine Fehler.
Ausserdem gehe ich mal ganz stark davon aus, das „nested list“ jede beliebige mögliche Verschachtelung meint, also beispielsweise auch ``[1, 2, [3, [4, 5]], 6, [[7]]]``. Und nicht nur etwas ”Zweidimensionales” wo nur auf der zweiten Ebene die Zahlen und nur Zahlen stehen.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Das Werfen ist einfach. Du machst einfach etwas, das nicht mit etwas Anderem als mit einer Integer geht, etwa:Strawk hat geschrieben:Ich möchte eine Exeption vom Typ TypeError werfen (und fangen?)
Code: Alles auswählen
a = 3.5 # das ist keine Integer
a & 1 # und das geht dann nicht und wirft eine Exception
- Fangen, eine Fehlermeldung ausgeben und weitermachen
- Fangen, dazu noch eine Fehlermeldung ausgeben und abbrechen
Fall 1: Fangen, eine Fehlermeldung ausgeben und weitermachen
Code: Alles auswählen
a = 3.5
try:
a & 1
except TypeError:
print("Warum war das keine Integer, aber egal, ich mache weiter")
Code: Alles auswählen
a = 3.5
try:
a & 1
except TypeError:
print("Wieder keine Integer, ich gebe es jetzt endlich auf")
raise
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
@Strawk: ich habe noch etwas vergessen. True und False zählen auch als Integer. Das solltre man auch noch abfangen:
Und genauso geht dann natürlich auch:
Code: Alles auswählen
a = True
if istype(a,bool):
a = 3.5
a & 1
Code: Alles auswählen
if not isinstance(l, list):
3.5 & 1
- noisefloor
- User
- Beiträge: 3843
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Alfons Mittelmeyer
Gruß, noisefloor
@Alfons Mittelmeyer
Du musst ein anderes Python benutzen als alle anderen hier im Forum. Du musst. Kann gar nicht anders. Und streite da am besten erst gar nicht ab, dass macht's nur schlimmer.True und False zählen auch als Integer
Gruß, noisefloor
@noisefloor: Nee, das stimmt schon:
Da Vererbung eine „ist-ein(e)“-Beziehung ist, braucht man das aber nicht extra testen, denn `bool`-Werte *sind* `int`-Werte, also ist es okay das auch `True` und `False` addiert werden können, denn es sind ja (auch) ganze Zahlen.
Code: Alles auswählen
In [1]: isinstance(True, int)
Out[1]: True
In [2]: isinstance(False, int)
Out[2]: True
In [3]: issubclass(bool, int)
Out[3]: True
In [4]: True + True
Out[4]: 2
In [5]: 42 / False
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-5-5e0a6f844f47> in <module>()
----> 1 42 / False
ZeroDivisionError: integer division or modulo by zero
In [6]: -True
Out[6]: -1
- noisefloor
- User
- Beiträge: 3843
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
aha, ok. Wieder was gelernt. Mein Gedankengang war, dass bool ein eigener Datentyp ist. Bis zum subclassing hatte ich nicht gedacht.
@Alfons Mittelmeyer: wir nutzen doch das gleiche Python, sorry.
Gruß, noisefloor
aha, ok. Wieder was gelernt. Mein Gedankengang war, dass bool ein eigener Datentyp ist. Bis zum subclassing hatte ich nicht gedacht.
@Alfons Mittelmeyer: wir nutzen doch das gleiche Python, sorry.
Gruß, noisefloor