Calculate extra time and write to excel with openpyxl - excel

Good morning as per the attached code, I would like to create a function that if the work shift (Bezahltezeit variable is showed in the Überziet column in Excel) is more than 10 hours, a 25% surcharge is created for every minute worked after ten hours.
I should have a result in minutes so that I can then add it up and convert it to excel.
Also in the nachtzeit column the 10% surcharge is calculated for every minute worked between 10 am and 6 am, as you see in the table it is transcribed in hours and minutes, I should have the result in minutes again so that I can add it up and convert to excel.
The function was created with the help of user #constantstranger whom I thank again!
Thanks
Year = int(IcsStartData.year)
Month = int(IcsStartData.month)
Day = int(IcsStartData.day)
StartH = int(IcsStartData.hour)
StartM = int(IcsStartData.minute)
EndH = int(IcsEndData.hour)
EndM = int(IcsEndData.minute)
currentDateTime = datetime.now()
Date_Time_Stamp = currentDateTime.strftime("%d%m%Y%H%M")
Current_DateTime = currentDateTime.strftime("%d.%m.%Y %H:%M")
Datetime = IcsStartData.strftime("%d.%m.%Y")
StartTime = IcsStartData.strftime("%H.%M")
EndTime = IcsEndData.strftime("%H.%M")
Schichtdauer = IcsSchichtDauer.strftime("%H.%M")
Bezahltezeit = IcsBezahlteZeit.strftime("%H.%M")
Bezahltezeit_Stunden = float(IcsBezahlteZeit.strftime("%H"))
Bezahltezeit_Minuten = float(IcsBezahlteZeit.strftime("%M"))
Terminaldata = IcsEndData.strftime("%d.%m.%Y")
EndDay = int(IcsEndData.day)
EndMonth = int(IcsEndData.month)
EndYear = int(IcsEndData.year)
def excelworking():
endTime = IcsEndData
startTime = IcsStartData
def getRegularAndBonusHours(startTime, endTime):
if endTime < startTime:
raise ValueError(f'endTime {endTime} is before startTime {startTime}')
startDateStr = startTime.strftime("%d.%m.%Y")
bonusStartTime = datetime.strptime(startDateStr + " " + "20:00", "%d.%m.%Y %H:%M")
prevBonusEndTime = datetime.strptime(startTime.strftime("%d.%m.%Y") + " " + "06:00", "%d.%m.%Y %H:%M")
bonusEndTime = prevBonusEndTime + timedelta(days=1)
NachtArbeitZeit = timedelta(days=0)
dienstdauer = endTime - startTime
hours = dienstdauer.total_seconds() // 3600
if hours > 24:
fullDays = hours // 24
NachtArbeitZeit += fullDays * (bonusEndTime - bonusStartTime)
endTime -= timedelta(days=fullDays)
if startTime < prevBonusEndTime:
NachtArbeitZeit += prevBonusEndTime - startTime
if endTime < prevBonusEndTime:
NachtArbeitZeit -= prevBonusEndTime - endTime
if startTime > bonusStartTime:
NachtArbeitZeit -= startTime - bonusStartTime
if endTime > bonusStartTime:
NachtArbeitZeit += min(endTime, bonusEndTime) - bonusStartTime
return dienstdauer, NachtArbeitZeit
def getHours(startTime, endTime, extraFraction):
dienstdauer, NachtArbeitZeit = getRegularAndBonusHours(startTime, endTime)
delta = dienstdauer + NachtArbeitZeit * extraFraction
return delta
def testing(start, end):
dienstdauer, NachtArbeitZeit = getRegularAndBonusHours(start, end)
def getHoursRoundedUp(delta):
return delta.days * 24 + delta.seconds // 3600 + (1 if delta.seconds % 3600 else 0)
regularHours, nachtszulage = getHoursRoundedUp(dienstdauer), getHoursRoundedUp(NachtArbeitZeit)
# print(f'start {start}, end {end}, nachtszulage {nachtszulage}, Nachstüberzeit {NachtArbeitZeit / 60 * 10} dienstdauer: {dienstdauer} {NachtArbeitZeit}')
# Writing on a EXCEL FILE
filename = (f"{myPath}/Monatsplan {username} {month} {year}.xlsx")
emptycell = ' '
wegzeiten = (int('13'))
try:
wb = load_workbook(filename)
ws = wb.worksheets[0] # select first worksheet
except FileNotFoundError:
headers_row = ['Datum','Dienst','Funktion','Von','Bis','Schichtdauer','Bezahlte Zeit (Studen)','Bezahlte Zeit (Minuten)','Zeit Konvertierung','Überzeit (ab 10 St.)','Nachtzeitzuschlag.','Nachtdienstentschädigung','Wegzeiten']
wb = Workbook()
ws = wb.active
ws.append(headers_row)
wb.save(filename)
ws.append([f'{Datetime}',f'{string1}'f'{tagesinfo2}',f'{soup_funktion}',f'{StartTime}',f'{EndTime}',f'{Schichtdauer}',f'{Bezahltezeit_Stunden}',f'{Bezahltezeit_Minuten}',f'{emptycell}',f'{emptycell}',f'{NachtArbeitZeit / 60 * 10}',f'{nachtszulage}',f'{wegzeiten}'])
for cols in ws.iter_cols( ):
if cols[-1].value:
cols[-1].border = Border(left=Side(style='thin'),right=Side(style='thin'),top=Side(style='thin'),bottom=Side(style='thin'))
cols[-1].number_format = '0.00'
wb.save(filename)
wb.close()

Related

Low of specific period (eg: 20 jan 2015 to 15 nov 2021)

This script draws ATH on chart with date and duration
I want to store low of period as well (like high shown in label) to show (high-low) range in the same label. The period does not end today, but as per script.
indicator("Previous Year(s) ATH", overlay = true)
num_years = input.int(1, title = "Number of years back", minval = 1)
var float ATH = high
var int ATH_time = time
var float[] ATH_vals = array.new_float()
var int[] ATH_time_vals = array.new_int()
var int[] ATH_time_change_vals = array.new_int()
ATH := math.max(ATH, high)
if ta.change(ATH) != 0
ATH_time := time
array.unshift(ATH_vals, ATH)
array.unshift(ATH_time_vals, time)
array.unshift(ATH_time_change_vals, ATH_time)
var float ATH1Y = na
if barstate.isconfirmed
search_time = time - 31536000000 * num_years
for i = 0 to array.size(ATH_time_vals) - 1
if array.get(ATH_time_vals, i) < search_time
ATH1Y := array.get(ATH_vals, i)
ATH1Y_time = array.get(ATH_time_change_vals, i)
y = year(ATH1Y_time)
m = month(ATH1Y_time)
d = dayofmonth(ATH1Y_time)
days_ago = (time - ATH1Y_time) / 86400000
date_text = str.tostring(y) + "/" + str.tostring(m) + "/" + str.tostring(d) + " : " + str.tostring(ATH1Y) + "\nDays Ago : " + str.tostring(math.round(days_ago, 2))
if ATH > ATH1Y and ATH[3] <= ATH1Y[3]
label.new(x = bar_index[3], y = ATH[3], text = date_text, style = label.style_label_lower_right)
break
ATH_val = ATH > ATH1Y ? na : ATH1Y
buy_signal = ATH > ATH1Y and ATH[3] <= ATH1Y[3]
plotshape(buy_signal, color = color.green, location = location.belowbar, size = size.small, style = shape.triangleup)
plot(ATH_val, title = "ATH", style = plot.style_linebr)

Track database history

def startlog():
id = enteruser.id
x = time.localtime()
sec = x.tm_sec
min = x.tm_min
hour = x.tm_hour + 1
day = x.tm_mday
date = f"{x.tm_mon}-{x.tm_mday}-{x.tm_year}"
starttime = (day * 86400) + (hour * 3600) + (min * 60) + sec
updatestart = "UPDATE log SET start = ?, date = ? WHERE ID = ?"
c.execute(updatestart, (starttime, date, id,))
conn.commit()
I have this function startlog, and a clone of it endlog.
My database log is consisted of (name, starttime, endtime, date)
Is there any way to keep track of the changes?
Desired output:
Name / Time / Date
x / time1 / date1
x / time2 / date2
I tried creating a list so everytime I'm calling out the function it will append on the list but it disappears after the session.
I used csv for my case since it's just a personal project. I used columns like ID/Time in / Time out / Total Time and used ID to determine which value to display. This is the snippet of my code (using tkinter for gui)
def csvwrite():
with open ('test.cvs', 'a', newline="") as csvfile:
writer = csv.writer(csvfile)
tup1 = (enteruser.id, log.start, log.end)
writer.writerow(tup1)
csvfile.close()
def csvread():
with open('test.cvs', 'r') as csvfile:
reader = csv.reader(csvfile)
filtered = filter(filterer, reader)
res = []
for i in filtered:
print(i)
historylbl = Label(historyWindow.historywndw, text = i)
historylbl.pack()

Python timer stops at random times

Just a warning, my code uses the pyperclip module but you don't have to pip install it because it is just for cosmetic reasons to make it a little easier. It also reads a file but the contents in the file is not important right now and can be replaced with any file with strings separated by lines.
What I want my code to do is:
WORKING 1. I want to be able to enter in a value for each line in the file, the first number representing hours and the second representing minutes.
NOT WORKING 2. I want to start a timer for for the hours and minutes for each time inputted. After I will add a sound but that is not there yet.
Problem: I input 1 minute for it to count down and it randomly stops in the middle of the count down. I don't know why because sometimes it finishes and sometimes it doesn't.
Code: https://pastebin.com/A2tTHtmK
import re
import pyperclip
from collections import OrderedDict
import time
import sys
import winsound
islandAndTimes = {}
fileObject = open("C:\\Users\\harry\\Desktop\\Skyblock Island bossmob warps.txt", "r")
message = fileObject.read()
whatToSearch = re.compile(r'\/is warp \w+')
l1 = whatToSearch.findall(message)
for eachInList in l1:
pyperclip.copy(eachInList)
typeIslandTime = input("How long until it spawns? (hours, minutes) ")
islandAndTimes[eachInList] = typeIslandTime
newIslandAndTimes = OrderedDict(sorted(islandAndTimes.items(), key=lambda t: t[1]))
if typeIslandTime == "0":
del islandAndTimes[eachInList]
print(newIslandAndTimes)
for everyIsland in newIslandAndTimes:
for firstKey, firstValue in newIslandAndTimes.items():
print("\n")
print(firstKey)
splitValues = firstValue.split()
newHours = int(splitValues[0])
newSecond = 0
newMins = int(splitValues[1])
print(newHours, newMins)
hour = time.strftime("%H")
minute = time.strftime("%M")
print("The hour is " + hour + " the minute is " + minute)
newerHours = newHours + int(hour)
newerMinute = newMins + int(minute)
print("total secodns is " + str(int((int(newHours) * 60 * 60) + int(newMins) * 60)-20))
totalSeconds = int(newHours) * 60 * 60 + int(newMins) * 60-20
while newSecond != 19:
time.sleep(1)
if int(hour) < newerHours or int(minute) < newerMinute:
#int(hour) > newerHours or int(minute) > newerMinute
minute = time.strftime("%M")
hour = time.strftime("%H")
second = time.strftime("%S")
sys.stdout.write('\r' + str("Time until ring: " + str(newHours) + " " + str(newMins) + " " + str(newSecond)))
sys.stdout.flush()
if newSecond == 0:
newSecond = 60
newMins = newMins - 1
elif newMins == 0 and newHours > 0:
newHours = newHours - 1
newSecond = newSecond - 1
print('completed')

ical parsing reoccuring events in python

I am extremely new to python and icalendar but I am trying to grab my icalendar from Apple's Icloud website and then be able to access the calendar information so that I can display it on an app. I am able to get any event from the calendar that isn't reoccurring, but it only gets those events and for some reason skips over the reoccurring ones (which is basically the only type of events I schedule now of days) This is the code that I currently have, any ideas on how to get reoccurring events?
from icalendar import Calendar, Event
import urllib.request
def getCalendar():
urlHome = urllib.request.urlopen('https://p10-calendarws.icloud.com/ca/subscribe/1/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX').read()
return urlHome
def displayCalendar(calendar):
showCalHome = Calendar.from_ical(calHome)
for event in showCalHome.walk('VEVENT'):
date = event.get('dtstart').dt
summary = event.get('summary')
print(summary,date)
calendar = getCalendar()
displayCalendar(calendar)
Any thoughts or ideas on what I can do to not only get a list of single events, but also reoccurring events?
Figured it out by parsing through the ICS file itself, turning alot of values into strings and then comparing the strings to what I was looking for, looked something like this:
import json
import requests
from icalendar import Calendar, Event
import urllib.request
from datetime import *
import datetime
from dateutil.rrule import *
def getCalendar():
urlWork = urllib.request.urlopen('https://p10-calendarws.icloud.com/ca/subscribe/1/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX').read()
urlHome = urllib.request.urlopen('https://p10-calendarws.icloud.com/ca/subscribe/1/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX').read()
calendars = [urlHome, urlWork]
return calendars
def getTodaysEvents(calendars):
calHome = calendars[0]
calWork = calendars[1]
allEvents = []
singleEvents = {}
homeEvents = {}
workEvents = {}
today = str(date.today())
year = today[0:4]
month = today[5:7]
day = today[8:10]
currentDay = year + month + day
showCalHome = Calendar.from_ical(calHome)
for component in showCalHome.walk():
if component.name == "VEVENT":
rule = component.get('rrule')
eventDay = str(component.get('dtstart').dt)
if rule is not None:
rrule = dict(rule)
if 'UNTIL' in rrule.keys():
eventEnd = str(rrule['UNTIL'][0])
eventEndYear = eventEnd[0:4]
eventEndMonth = eventEnd[5:7]
eventEndDay = eventEnd[8:10]
endEvent = eventEndYear + eventEndMonth + eventEndDay
if int(endEvent) >= int(currentDay):
print(component.get('summary'))
homeEvents['CALENDAR'] = "HOME"
homeEvents['SUMMARY'] = (component.get('summary'))
homeEvents['LOCATION'] = (component.get('location'))
homeEvents['START'] = (component.get('dtstart').dt)
homeEvents['END'] = (component.get('dtend').dt)
allEvents.append(homeEvents)
# else: (NEED TO IMPLEMENT WEEKLY EVENTS THAT DON'T END and Events that aren't Reoccuring)
# print(component.get('summary'))
# if component.get('location') != 'None':
# print(component.get('location'))
# print(component.get('dtstart').dt)
# print(component.get('dtend').dt)
else:
if str(date.today()) == eventDay[0:10]:
print(component.get('summary'))
singleEvents['CALENDAR'] = "HOME"
singleEvents['SUMMARY'] = (component.get('summary'))
singleEvents['LOCATION'] = (component.get('location'))
singleEvents['START'] = (component.get('dtstart').dt)
singleEvents['END'] = (component.get('dtend').dt)
allEvents.append(singleEvents)
print(allEvents)
showCalWork = Calendar.from_ical(calWork)
for component in showCalWork.walk():
if component.name == "VEVENT":
rule = component.get('rrule')
if rule is not None:
rrule = dict(rule)
today = str(date.today())
year = today[0:4]
month = today[5:7]
day = today[8:10]
currentDay = year + month + day
if 'UNTIL' in rrule.keys():
eventEnd = str(rrule['UNTIL'][0])
eventEndYear = eventEnd[0:4]
eventEndMonth = eventEnd[5:7]
eventEndDay = eventEnd[8:10]
endEvent = eventEndYear + eventEndMonth + eventEndDay
if int(endEvent) >= int(currentDay):
workEvents['CALENDAR'] = "WORK"
workEvents['SUMMARY'] = (component.get('summary'))
workEvents['LOCATION'] = (component.get('location'))
workEvents['START'] = (component.get('dtstart').dt)
workEvents['END'] = (component.get('dtend').dt)
allEvents.append(workEvents)
# else:
# print(component.get('summary'))
# if component.get('location') != 'None':
# print(component.get('location'))
# print(component.get('dtstart').dt)
# print(component.get('dtend').dt)
return allEvents
def displayEvents(events):
print(events)
print()
print("TODAY:")
for event in range(len(events)):
start = str(events[event]['START'])[11:16]
end = str(events[event]["END"])[11:16]
if int(start[0:2]) < 12:
sT = "AM"
else:
pmtime = int(start[0:2]) - 12
start[0:2].replace(start[0:2], str(pmtime))
sT = "PM"
if int(end[0:2]) < 12:
eT = "AM"
else:
pmtime = int(end[0:2]) - 12
end = str(pmtime) + end[2:5]
eT = "PM"
print(events[event]['SUMMARY'] + " - " + events[event]["CALENDAR"])
if str(events[event]['LOCATION']) != "None":
print(events[event]['LOCATION'])
if start[0] == "0" and end[0] == "0":
print(start[1:5] + sT + " - " + end[1:5] + eT)
elif start[0] == "0":
print(start[1:5] + sT + " - " + end + eT)
elif end[0] == "0":
print(start + sT + " - " + end[1:5] + eT)
else:
print(start + sT + " - " + end + eT)
calendars = getCalendar()
events = getTodaysEvents(calendars)
displayEvents(events)
I created a library because I was looking for the exact same use-case.
In your case, recurring-ical-events could be embedded like this:
events = recurring_ical_events.of(calendar).between(start_date, end_date)
for event in events:
# ...

I need to write a program which calculates the number of hours a person has used a machine but I can not go over 23:59:59

I have this code so far. I need to write a program which prints the billing information for a machine which is hired out.
hours = 23
minutes = 81
seconds = 0
seconds_in_minute = 60
seconds_in_hour = 3600
final_seconds = seconds % 60
final_seconds2 = ((2 - len(str(final_seconds))) * "0") + str(final_seconds)
extra_minutes = int(seconds / 60)
final_minutes = (minutes + extra_minutes) % 60
final_minutes2 = ((2 - len(str(final_minutes))) * "0") + str(final_minutes)
extra_hours = int(minutes / 60)
final_hours = (hours + extra_hours)
final_hours2 = ((2 - len(str(final_hours))) * "0") + str(final_hours)
cost_for_seconds = 2
cost_for_seconds_in_full_minute = 1.6
cost_for_seconds_in_full_hour = 1.2
seconds_cost = cost_for_seconds * final_seconds
minutes_cost = cost_for_seconds_in_full_minute * (final_minutes * seconds_in_minute)
hours_cost = cost_for_seconds_in_full_hour * (final_hours * seconds_in_hour)
cost_for_seconds = 2
cost_for_seconds_in_full_minute = 1.6
cost_for_seconds_in_full_hour = 1.2
seconds_cost = cost_for_seconds * final_seconds
minutes_cost = cost_for_seconds_in_full_minute * (final_minutes * seconds_in_minute)
hours_cost = cost_for_seconds_in_full_hour * (final_hours * seconds_in_hour)
print("hours =", hours)
print("minutes =", minutes)
print("seconds =", seconds)
print("=" * 35)
print(" ", " ", "Total time: ", final_hours2, ":", final_minutes2, ":", final_seconds2 , sep = "")
print(" ", " ", "Cost: ", "$", int(seconds_cost + minutes_cost + hours_cost), sep = "")
print("=" * 35)
Which produces the output of
hours = 23
minutes = 81
seconds = 0
===================================
Total time: 24:21:00
Cost: $101376
===================================
Problem is I need it to be in the format 00:21:00
I need it so that the cost is still the same, but the hours display is never 24 hours or over.
I think what you are looking for is the modulo operation.
After calculating final_hours, you need to do :
final_hours = final_hours % 24
Your final hours will always be a value beetween 0 and 23
Just add a day for every 24 hours:
Here is a code snippet that will normalize seconds, minutes, hours, days:
extra_minutes, seconds = divmod(seconds, 60)
extra_hours, minutes = divmod(minutes + extra_minutes, 60)
extra_days, hours = divmod(hours + extra_hours, 24)
days += extra_days
and here is a way to make a string with time in HH:MM:SS zero-padded format:
"{:02d}:{:02d}:{:02d}".format(hours, minutes, seconds)
Hope it helps.

Resources