TL;DR: Cały rdzeń programu to metoda, która sprawdza czy zostały naruszone przepisy. Z grubsza ją napisałem i pomimo, że nie mam pewności czy działa w stu procentach oraz będąc świadomym, że kod, który się za tym kryje trzeba trochę przepisać, postanowiłem się nim podzielić.

Konkurs zbliża się wielkimi krokami do końca i bardzo chciałem jeszcze przed zakończeniem skończyć wersję beta.

Kod więc znów zaznał chaosu, parę razy została zmieniona koncepcja a ja o tym, żadnego posta nie napisałem. Dlatego zanim znów wszystko pozmieniam oto co mam na ten moment.

Sporo zmian

Jak na razie wprowadziłem kilka nowych reguł, które program sprawdza. Zróbmy tak, że zanim poprawię je, usystematyzuje i w stu procentach sprawdzę najpierw się nimi podzielę.

Jeszcze zanim do tego przejdziemy wspomnę tylko, że ostatecznie stanęło na tym, że będzie jednak jedna lista zawierająca wszystkie wpisy z ostatnich 28 dni (choć to ograniczenie jeszcze nie zostało wprowadzone).

Dzięki temu całe sprawdzanie pod kątem zgodności z przepisami odbywa się w jednej metodzie infringements() za pomocą jednej pętli for.

Pisałem już o tym, że przepisy dotyczące pracy kierowcy zawodowego są mega zagmatwane i sporo móżdżenia wymagało ode mnie, żeby przetłumaczyć je komputerowi. Zresztą nie wszystko mi się jeszcze udało zrobić.

Oto najważniejsze przepisy:

Czas jazdy:

  • Nie więcej niż 9 godzin dziennie lecz dwukrotnie w tygodniu może być przedłużone do 10 godzin.
  • Maksymalnie 56 godzin w tygodniu.
  • Maksymalnie 90 godzin w okresie dwutygodniowym.

Przerwy i odpoczynek:

  • conajmniej 45 minut przerwy po nie więcej niż 4,5 godziny jazdy (może być podzielona na dwie przerwy z czego pierwsza nie mniej niż 15 minut a druga nie mniej niż 30 minut)
  • conajmniej 45 minut przerwy po nie więcej niż 6 godzinach jazdy i pracy (też może być podzielona jak powyżej)
  • conajmniej 11 godzin dziennie co może być skrócone do conajmniej 9 godzin trzy razy pomiędzy dwoma tygodniowymi odpoczynkami (11 godzinna przerwa może być podzielona na dwie przerwy z czego pierwsza musi trwać nie mniej niż 3 godziny a druga nie mniej niż 9 godzin. Wtedy przerwa ta nie jest traktowana jako skrócona)
  • conajmniej 45 godzin tygodniowo co może być skrócone do 24 godzin co drugi tydzień
  • przerwa tygodniowa musi być rozpoczęta nie później niż po szóstym 24 godzinnym okresie.

Jest dobrze

Zakładając, że ta metoda z grubsza działa to z tych wszystkich przepisów na razie nie mam (więc jest całkiem git!) dzielenia dziennej przerwy na 3h i 9h oraz tego, że przerwa tygodniowa może być skrócona co drugi tydzień. O ile ten pierwszy problem chyba wiem jak rozwiązać o tyle z drugim na razie nie mogę sobie poradzić.

Wolne to nie skrócona przerwa

Wszystko przez to, że przecież możesz pracować co drugi dzień i wtedy masz co drugi dzień przerwę 24h. Nie znaczy to jednak, że złamałeś przepisy.

Próbowałem rozwiązać to na różne sposoby i jak na razie bez pozytywnych rezultatów. No, ale tak jak pisałem na samym wstępie. Dzielę się tym co mam na ten moment.

Kod tej metody na razie wygląda tak:

class Data:
(...)
    def infringements(self):

        driving_time = 0  # can't be more than 4,5h before break
        working_time = 0  # it's time of work or driving and can't be more than 6h
        daily_driving_time = 36000  # 10h
        count = {'exceeded_daily_driving': 0, 'reduced_daily_rest': 0}
        daily_total_time = 54000  # 15h
        weekly_total_time = 518400  # 6x24h
        weekly_driving_time = 201600  # 56h

        fortnight_driving_time = 324000  # 90h
        fortnight = False

        reduced_weekly_rest = False
        first_break = False
        second_break = False
        daily_infringements_list = []
        for x in self.records:
            daily_total_time -= x.get_value()
            weekly_total_time -= x.get_value()

            # driving
            if x.get_mode() == 'D':
                driving_time += x.get_value()
                daily_driving_time -= x.get_value()
                if daily_driving_time < 3600:  # less than 1h so more than 9h driving
                    count['exceeded_daily_driving'] += 1
                weekly_driving_time -= x.get_value()
                fortnight_driving_time -= x.get_value()

            # driving or work
            if x.get_mode() == 'D' or x.get_mode() == 'W':
                working_time += x.get_value()

            if x.get_mode() == 'R' and (900 <= x.get_value() < 1800):
                first_break = True

            # First break must be at least 15 minutes and second 30 minutes.
            if x.get_mode() == 'R' and (1800 <= x.get_value() < 2700):                 if first_break is True:                     second_break = True                 else:                     first_break = True             # break 45 minutes or more (also can be split to 15min and 30min)             if (x.get_mode() == 'R' and x.get_value() >= 2700) or (second_break is True):

                driving_time = 0
                working_time = 0
                first_break = False
                second_break = False

                if x.get_value() >= 32400:  # >=9h
                    daily_total_time += x.get_value()  # do not count last break for daily_total_time

                    # reduced daily break - more than 13h of work or rest between 9h and 11h
                    if (daily_total_time < 7200 and x.get_value() < 86400) or 32400 <= x.get_value() < 39600:

                        count['reduced_daily_rest'] += 1

                    # full daily break between 11h and 24h
                    elif 39600 <= x.get_value() < 86400:
                        pass
                    # reduced weekly break between 24h and 45h
                    elif 86400 <= x.get_value() < 162000 :  # between 24h and 45h                         if reduced_weekly_rest is True:                         # you can't take two reduced one after another,                         # but you can skip day at work during week - it must be fixed                             # daily_infringements_list.append("Second reduced weekly break taken")                             reduced_weekly_rest = False                         else:                             reduced_weekly_rest = True                         weekly_total_time = 518400                         weekly_driving_time = 201600                         if fortnight is False:                             fortnight = True                         else:                             fortnight_driving_time = 324000                         count['exceeded_daily_driving'] = 0                         count['reduced_daily_rest'] = 0                     # full weekly rest more than 45h                     elif x.get_value() >= 162000:  # 45h
                        reduced_weekly_rest = False
                        weekly_total_time = 518400
                        weekly_driving_time = 201600

                    daily_total_time = 54000
                    daily_driving_time = 36000

            if driving_time > 16200:
                info_driving_break = "Break after 4,5h driving needed"
                daily_infringements_list.append(info_driving_break)
                driving_time = 0

            if working_time > 21600:
                info_break = "Break after 6h work needed"
                daily_infringements_list.append(info_break)
                working_time = 0

            if daily_total_time < 0:
                daily_infringements_list.append('Available daily shift time exceeded')
                daily_total_time = 54000

            if daily_driving_time < 0:
                daily_infringements_list.append('Available daily driving time exceeded')
                daily_driving_time = 36000

            if weekly_total_time < 0:
                daily_infringements_list.append('Available weekly total time of work exceeded')
                weekly_total_time = 518400

            if weekly_driving_time < 0:
                daily_infringements_list.append('Available weekly total driving time exceeded')
                weekly_driving_time = 201600

            if fortnight_driving_time < 0:                 daily_infringements_list.append('Fortnight total driving time exceeded')                 fortnight_driving_time = 324000             # if more than two times between two weekly rests driving time is more than 9h             if count['exceeded_daily_driving'] > 2:
                daily_infringements_list.append('Exceeded daily driving time already used')

            if count['reduced_daily_rest'] > 3:
                daily_infringements_list.append('Too many reduced daily breaks between 2 weekly rest periods')

        return daily_infringements_list

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie na Google

Komentujesz korzystając z konta Google. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s