Seite 1 von 1

Werktage zählen

Verfasst: Sonntag 14. Januar 2007, 23:21
von gummibaerchen
Hi,

so hier mal mein erster Code zum vorzeigen.

Da ich einen wissen wollte, wie oft ich hier noch zu Schule gehen darf, habe ich gerade mal einen Werktagszähler geschrieben.

Da meine Idee nicht so ganz aufgegangen ist, ist der Algorithmus aus einem PHP Programm, und ich habe nach Python "übersetzt".

Ein paar Kommentare fehlen noch, damit man den Code besser versteht.
Aber wenigstens es funktioniert erstmal.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Workday Counter
Counts the workdays between two given days
"""

import datetime

def workday_count(start, end):
    workdays = 5

    start_weekday = start.weekday()
    end_weekday = end.weekday()

    start_week = start.strftime("%W")
    end_week = end.strftime("%W")

    if end_weekday > workdays:
        end_weekday = workdays

    if end_weekday > start_weekday:
        leftday = end_weekday - start_weekday
    else:
        leftday = start_weekday - end_weekday

    diff_in_weeks = int(end_week) - int(start_week)
    weeks_in_days = diff_in_weeks * workdays

    totaldays = weeks_in_days + leftday + 1

    return totaldays

if __name__ == '__main__':
    start = datetime.date(2007, 1, 1)
    end = datetime.date(2007, 1, 15)
    difference = workday_count(start, end)
    print "There are %s workdays between %s and %s" % (difference, start, end)
Bin gerne für Anmerkungen aller Art offen ;)

Code ist GPL, falls den jemand verwenden möchte.

Gruß,
gummibaerchen

Verfasst: Sonntag 14. Januar 2007, 23:35
von gummibaerchen
Hmm, zu früh gefreut.

Irgendwie hat das Ding einen größeren Fehler:

Code: Alles auswählen

timm@timm-desktop:~$ python workday_counter.py 
There are 25 workdays between 2007-01-15 and 2007-02-16
timm@timm-desktop:~$ python workday_counter.py 
There are 28 workdays between 2007-01-14 and 2007-02-16
Es funktioniert nur richtig, wenn der Start ein Montag ist, naja, da muss ich dann nochmal nachbessern.

Achso, hier mal meine "Quelle": http://www.phpfreaks.com/quickcode/coun ... nd/621.php

Verfasst: Montag 15. Januar 2007, 09:58
von gerold
Hi gummibaerchen!

Dieser Code sollte funktionieren. Allerdings wird die Ausführung linear langsamer, je mehr Tage zwischen dem Beginn- und Enddatum liegen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
"""
Workdays counter
"""

import datetime

WORKDAYS = (
    0, # Monday
    1, # Tuesday
    2, # Wednesday
    3, # Thursday
    4, # Friday
)

HOLIDAYS = (
    #MM-DD
    "01-01", # Neujahrstag
    "12-25", # Christtag
    #...
)


def count_workdays(begin_date, end_date):
    """
    Zaehlt die Werktage, inklusiv Beginn- und Enddatum.
    """
    
    diff = end_date - begin_date
    workday_count = 0
    for i in xrange(diff.days + 1):
        actual_day = begin_date + datetime.timedelta(days = i)
        actual_iso_day = actual_day.isoformat()
        if (
            (actual_iso_day[-5:] not in HOLIDAYS) and
            (actual_day.weekday() in WORKDAYS)
        ):
            workday_count += 1
    
    return workday_count


def main():
    
    # Testen
    begin_date = datetime.date.today()
    end_date = datetime.date.today() + datetime.timedelta(days = 10)
    diff = count_workdays(begin_date, end_date)
    
    print "There are %s workdays between %s and %s" % (diff, begin_date, end_date)


if __name__ == "__main__":
    main()
mfg
Gerold
:-)

Verfasst: Montag 15. Januar 2007, 17:51
von gummibaerchen
Hi Gerold,

gucke mir deinen Code gleich mal an. Hier was ich in der Schule geschrieben, und gerade mal digitalisiert habe.

Funktionierte bei mir mit allen Test-Daten.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Workday Counter
Counts the workdays between two given dates
"""

import datetime

def workday_count(start, end):
    workdays = 5

    start_weekday = start.weekday()
    end_weekday = end.weekday()

    # Workdays in the first week
    if start_weekday < workdays:
        days_left_in_start_week = workdays - start_weekday
    else:
        days_left_in_start_week = 0

    # Workdays left in the last week
    if end_weekday < workdays:
        days_left_in_last_week = end_weekday + 1
    else:
        days_left_in_last_week = 5

    # Weeknumbers of start and end week
    start_week = start.strftime("%W")
    end_week = end.strftime("%W")

    # Difference between the weeks
    week_diff = int(end_week) - int(start_week)

    # Final Calculation
    work_days = (week_diff - 1) * 5 + days_left_in_start_week + days_left_in_last_week
    return work_days


if __name__ == '__main__':
    start = datetime.date(2007, 2, 16)

    end = datetime.date(2007, 2, 18)
    difference = workday_count(start, end)
    print "There are %s workdays between %s and %s" % (difference, start, end)
Natürlich auch wieder GPL falls jemand Interesse hat.

Nachträge:
1) Was ich bei mir noch verbessern muss ist Support für verschiedene Jahre.
2) Gerold, deins funktioniert auch fein. Das mit den Feiertage ist eine gute Sache.
3) Außerdem werde ich das wohl so machen, dass das Datum erst sortiert wird (höheres Datum als Ende), oder vllt mache ich auch einfach Gebrauch von der Betragsfunktion.

Verfasst: Mittwoch 17. Januar 2007, 14:59
von Costi
Code ist GPL, falls den jemand verwenden möchte.
wie geeeeht das ?


danke

Verfasst: Mittwoch 17. Januar 2007, 17:32
von Leonidas
Costi hat geschrieben:
Code ist GPL, falls den jemand verwenden möchte.
wie geeeeht das ?
Ganz einfach, am Ende der GPL steht sogar wie:
GPL2 hat geschrieben: How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

One line to give the program's name and a brief idea of what it does.
Copyright (C) <year> <name of author>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice