Seite 1 von 2

<type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 08:36
von mutetella
Hallo,

es funktioniert, nur: Ist das ok oder kann das Probleme machen?

Code: Alles auswählen

In [21]: 1 + True
Out[21]: 2
Es geht mir darum, dass ich einen Wert (days) um 1 erhöhen möchte, wenn eine Funktion (is_leap) 'True' zurückgibt, etwas in der Art:

Code: Alles auswählen

days += is_leap(date)
Gruß
mutetella

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 08:40
von numerix
mutetella hat geschrieben:Ist das ok oder kann das Probleme machen?
Ist ok, macht keine Probleme.
Im Einzelfall sollte man lediglich überlegen, inwieweit es die Lesbarkeit des Codes verschlechtert.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 08:44
von mutetella
numerix hat geschrieben:... überlegen, inwieweit es die Lesbarkeit des Codes verschlechtert.
Also würdest Du eher

Code: Alles auswählen

if is_leap(year):
    days += 1
verwenden?

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 08:59
von numerix
mutetella hat geschrieben:
numerix hat geschrieben:... überlegen, inwieweit es die Lesbarkeit des Codes verschlechtert.
Also würdest Du eher

Code: Alles auswählen

if is_leap(year):
    days += 1
verwenden?
Nö, weil ich ein Freund der Kürze bin ... :)
Mein Hinweis bezog sich eher auf Ausdrücke, die komplexer sind und deren Lesbarkeit man dann ggf. durch solche Elemente verschlechtert. Das Inkrementieren mit einem Wahrheitswert als einzelne Anweisung sollte keine Lesbarkeitsprobleme verursachen.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 09:10
von gkuhl
@mutetella: Wofür brauchst du das denn? Sollte es um Schaltjahre gehen, ist das 'datetime'-Modul sicherlich einen Blick wert.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 09:18
von mutetella
@gkuhl:
Leider bietet das datetime-Modul keine Funktion, über die ich Schaltjahre abfragen kann. Das calendar-Modul hat eine isleap(), und die liefert entweder True oder False. Von daher meine Frage.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 09:28
von gkuhl
Ich fragte, weil es so klingt, als versuchst du den Tag des Jahres zu bestimmen. Was man wie folgt lösen kann:

Code: Alles auswählen

In [2]: from datetime import datetime as DateTime

In [3]: DateTime.today().strftime('%j')
Out[3]: '293'
Grüße
Gerrit

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Mittwoch 20. Oktober 2010, 09:34
von mutetella
@gkuhl:
Ne, mir geht es um Sprünge vom 29. Februar um 1 Jahr vor oder zurück bzw. das Ermitteln des jeweils letzten Tages im Monat. Und dafür muss ich wissen, ob das Zieldatum ein Schaltjahr ist oder nicht.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 11:38
von Leonidas
Also ich persönlich finds schon hässlich True als Shortcut für ``1`` zu mißbrauchen.

Das hat zwar dann eher was von Happy cat is happy, aber wenigstens wundert man sich nicht was der Autor da machen wollte:

Code: Alles auswählen

1 + 1 if is_leap(year) else 0

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 13:47
von Panke
mutetella hat geschrieben:@gkuhl:
Ne, mir geht es um Sprünge vom 29. Februar um 1 Jahr vor oder zurück bzw. das Ermitteln des jeweils letzten Tages im Monat. Und dafür muss ich wissen, ob das Zieldatum ein Schaltjahr ist oder nicht.
Nimm den ersten Tag des Folgemonats und ziehe davon einen Tag ab. datetime macht den Rest.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 17:04
von mutetella
Panke hat geschrieben:Nimm den ersten Tag des Folgemonats und ziehe davon einen Tag ab.
Das wäre dann also

Code: Alles auswählen

date.replace(day=1, month=(date.month + 1)
date -= timedelta(1)
Ist 'ne funktionierende Lösung. Gefällt mir aber nicht.

Code: Alles auswählen

day = [31, 28 + is_leap(date.year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][date.month - 1]
date.replace(day=day)
Gefällt mir besser.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 17:17
von EyDu
Du findest eine per Hand erstellte Liste einfacher als eine gut lesbare und intuitive Lösung? Gut, noch einfacher ist natürlich eine fertige Lösung (welche man übrigens in weniger als 10 Sekunden mit einer Suche nach "days in month" findet) ;-)

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 20:48
von snafu
mutetella hat geschrieben:Also würdest Du eher

Code: Alles auswählen

if is_leap(year):
    days += 1
verwenden?
Ich würde es wohl tun.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 21:07
von mutetella
EyDu hat geschrieben:Du findest eine per Hand erstellte Liste einfacher als eine gut lesbare und intuitive Lösung?
Dann erklär' mir doch mal bitte, was calendar.monthrange() anderes macht, als aus einer "per Hand" erstellten Liste die jeweilige Anzahl der Tage pro Monat herauszupicken....


calendar.monthrange():

Code: Alles auswählen

# Constants for months referenced later
January = 1
February = 2

# Number of days per month (except for February in leap years)
mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def monthrange(year, month):
    """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
       year, month."""
    if not 1 <= month <= 12:
        raise IllegalMonthError(month)
    day1 = weekday(year, month, 1)
    ndays = mdays[month] + (month == February and isleap(year))
    return day1, ndays

def isleap(year):
    """Return 1 for leap years, 0 for non-leap years."""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
Wobei monthrange() auch mit True/False "rechnet", also True als 1 "missbraucht". Der docstring aus isleap() ist da nicht ganz ehrlich.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 21:11
von lunar
@Leonidas: Ich wundere mich durchaus, was Du bei dieser Variante machen wolltest, liefert sie doch mithin nicht das erwartete Ergebnis. Die Addition wird nämlich vor dem bedingten Ausdruck ausgewertet, so dass der Ausdruck im Gesamten entweder 2 oder 0 ergibt, aber nicht 1.

Folglich halte ich diese Variante für die unglücklichste, bietet sie doch ganz offensichtlich Anlass zu reichlich subtilen Fehlern. Die beiden anderen Varianten sind meines Erachtens völlig gleichwertig, schließlich ist die Verwandtschaft zwischen Ganzzahlen und Wahrheitswerten eine dokumentierte Eigenschaft der Sprache, und sollte mithin bekannt sein.

@mutetella: Man hat Dir aber schon erklärt, dass es der Sinn der Bibliothek in ihrer Verwendung liegt und nicht darin, die Implementierung derselbe in den eigenen Quelltext zu kopieren?! Verzeih mir den Spott, doch ich finde es ziemlich merkwürdig, eine eigene Implementierung mit dem Verweis darauf zu verteidigen, dass die Bibliothek es exakt genauso macht. Das führt nämlich unmittelbar zur Frage, warum Du auf der erneuten Erfindung des Rades in exakt derselben Form bestehst ...

Im Übrigen ist der Docstring von "isleap()" vollauf ehrlich, da "True" und "False" echte Ganzzahlen sind, und zwar im Wert von 1 bzw. 0. Das ist dokumentiert, und lässt sich mit einem einfachen "isinstance(True, int)" auch selbst herausfinden.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 21:25
von mutetella
lunar hat geschrieben:..., die Implementierung derselbe in den eigenen Quelltext zu kopieren?! Verzeih mir den Spott, doch ich finde es ziemlich merkwürdig, eine eigene Implementierung mit dem Verweis darauf zu verteidigen, dass die Bibliothek es exakt genauso macht.
Wenngleich es wohl keine Rolle spielt, muss ich mich hier doch verteidigen. Dass calendar.monthrange() in derselben Weise wie ich vorgeht, habe ich gerade vor 15 Minuten entdeckt, als ich aufgrund von EyDu's Beitrag zu meiner Schande überhaupt erst erfuhr, dass es diese Funktion gibt. Von kopieren kann also keine Rede sein. Vielmehr fühle ich mich dadurch, dass die Autoren des calendar-Moduls in diesem Punkt genauso verfahren, bestätigt.
Du hast natürlich damit Recht, dass eine bereits vorhandene Bibliothek auch verwendet werden will. Allerdings versuche ich bei der Lösung eines so kleinen Problems wie der Ermittlung der Tagesanzahl eines Monats, eigene Funktionen zu verwenden. Darüber mag man geteilter Ansicht sein, ich ziehe das einem

Code: Alles auswählen

from calendar import monthrange
vor.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 21:39
von DasIch
Hoffentlich gehört zu der eigenen Funktion auch die entsprechende Dokumentation und Tests...

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Donnerstag 21. Oktober 2010, 21:41
von lunar
@mutetella: Das war ironisch gemeint, ich habe nicht behauptet, dass Du kopiert hättest. Ich habe mich nur über Deine Art der Verteidigung gewundert ...

Ansonsten kannst Du in Deinem eigenen Programm nach Deinem Belieben verfahren, doch wirst Du wohl hier nicht viele Anhänger für diese Einstellung gewinnen können. Ich persönlich würde die Verwendung einer eigenen Implementierung gegenüber einer Bibliothek immer kritisieren, sofern nicht Gründe gegen die Bibliothek selbst sprechen.

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Freitag 22. Oktober 2010, 00:23
von Leonidas
lunar hat geschrieben:@Leonidas: Ich wundere mich durchaus, was Du bei dieser Variante machen wolltest, liefert sie doch mithin nicht das erwartete Ergebnis. Die Addition wird nämlich vor dem bedingten Ausdruck ausgewertet, so dass der Ausdruck im Gesamten entweder 2 oder 0 ergibt, aber nicht 1.
Uhm, ja, Klammern eben...

Re: <type 'int'> mit <type 'bool'> addieren?

Verfasst: Freitag 22. Oktober 2010, 06:35
von mutetella
lunar hat geschrieben:Ansonsten kannst Du in Deinem eigenen Programm nach Deinem Belieben verfahren, ...
Da hab' ich mich gestern vielleicht etwas zu absolut ausgedrückt. Es fehlt mir bei weitem die Erfahrung, aufgrund derer ich sagen könnte, es so oder anderst zu machen. In diesem konkreten Fall habe ich mich einfach sehr darüber gefreut, endlich einmal etwas in einer Art und Weise gelöst zu haben, mit der offensichtlich auch Profis das Problem angegangen sind. Und soetwas lässt man sich natürlich nicht gleich wieder nehmen... :) calendar.monthrange() nicht zu importieren war also nicht eine Entscheidung besseren Wissens, sondern schlichtweg purer Stolz auf meinen [ironie]genialen Einfall, die jeweilige Tagesanzahl eines Monats zu ermitteln.[/ironie]
lunar hat geschrieben:Ich persönlich würde die Verwendung einer eigenen Implementierung gegenüber einer Bibliothek immer kritisieren, ...
Wenn Freude und Stolz verflogen sind, werde ich also isleap() und monthrange() importieren. Bleibt für mich nur die Frage nach dem warum? Schießt man nicht mit Kanonen auf Spatzen, wenn man wegen 5 oder 6 Zeilen Programmcode auf eine externe Bibliothek zugreift? Bei einer built-in Funktion ist das ja überhaupt kein Thema, aber extra importieren?