Cycling through a date - python

I have defined day and month in a previous part of the code. I need this program to run when day is less than 7. I am asking for an input of spendings in the last 7 days.
The problem: If the input of day is 4, for example, 4 - 4(days) is day 0 (does not exist), 4 - 5 is day -1, 4 - 6 is day -2, 4 - 7 is day -3. I need it to be day 4 - 4 = 31 or 30 or 28 or 29 (that is already defined), 4 - 5 = 30, 4 - 6 = 29.
I know that this is poorly structured, I apologize, English is not my first language. Will try to make it clear if it is not understood like this.
listOfSpendings = []
x = 0
while x < 7:
if day - x <=0:
month = month - 1
dayDiff= ###SOMETHING I DUNNOOOO
day = monthlenght - dayDiff
print ("How many liters did you spend on the day", day - x, "of", month)
spendings = input()
while True:
try:
spendings = int(spendings)
if spendings < 0:
spendings = input ("Insert a value =! 0")
else:
break
except ValueError:
spendings = input("Incorrect value, correct")
x = x+1
listOfSpendings.append(spendings)
sumSpendings = sum (listOfSpendings)

Your code as it is will run into negative numbers with months as well. Using the datetime library that was suggested you can do the following:
from datetime import datetime, timedelta
list_of_spendings = []
# Month number
for day in [(datetime.now()-timedelta(x)) for x in range(7)]:
print('How many liters did you spend on the day {} of {}'.format(day.day, day.month))
#Rest of your code
OR
# Month name
for day in [(datetime.now()-timedelta(x)) for x in range(7)]:
print('How many liters did you spend on the day {} of {}'.format(day.day, day.strftime('%B')))
#Rest of your code
OR
# Short month name
for day in [(datetime.now()-timedelta(x)) for x in range(7)]:
print('How many liters did you spend on the day {} of {}'.format(day.day, day.strftime('%b')))
#Rest of your code

This is how I figured it out. "Dia" and "mes" are previously defined.
Translations:
listaGastos = listOfSpendings
gastos = spendings
dia = day
mes = month
DuracMes = monthlenght
diaC = currentDay
mesC = currentMonth
Code:
DuracMes = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
listaGastos = []
x = 0
diaC = dia
mesC = mes
while x < 7:
dia = diaC - x
if dia <= 0:
mes = mesC - 1
diaDif = diaC - 1
dia = DuracMes [mes - 1] + dia
print("Quantos litros de soro fisiologico foram gastos no dia", dia, "de", mes)
gastos = input()
while True:
try:
gastos = int (gastos)
if gastos < 0:
gastos = input ("Introduza um valor diferente de 0: ")
else:
break
except ValueError:
gastos = input ("Nao inseriu um valor adequado, quantos litros de soro fisiologico foram gastos nos ultimos sete dias? ")
x += 1
listaGastos.append(gastos)
sumGastos = sum (listaGastos)

Related

Trying to make Alarm Clock with Python, but it is not working

don't know where I got stuck. Seems fine for me.
Maybe the loop part doesen't work properly? Let me know if something is wrong.
import datetime
import time
year = (datetime.datetime.today().strftime("%Y"))
month = (datetime.datetime.today().strftime("%m"))
day = (datetime.datetime.today().strftime("%d"))
hour = (datetime.datetime.today().strftime("%H"))
minute = (datetime.datetime.today().strftime("%M"))
second = (datetime.datetime.today().strftime("%S"))
setyear = int(input("Year"))
setmonth = int(input("Month"))
setday = int(input("Day"))
sethour = int(input("Hour"))
setminute = int(input("Minute"))
setsecond = int(input("Second"))
while True:
time.sleep(1)
year = (datetime.datetime.today().strftime("%Y"))
month = (datetime.datetime.today().strftime("%m"))
day = (datetime.datetime.today().strftime("%d"))
hour = (datetime.datetime.today().strftime("%H"))
minute = (datetime.datetime.today().strftime("%M"))
second = (datetime.datetime.today().strftime("%S"))
if year == setyear and month == setmonth and day == setday and hour == sethour and minute == setminute and second == setsecond:
print("Alarm!")
break
else:
print("NO")
I believe because the types don't match and therefore values are interpretted differently.
For example:
input seconds "0" won't match to the seconds returned of "00", i removed your int()
conversions at the start and it now works. You just have to enter the proper digits:
import time
import datetime
year = (datetime.datetime.today().strftime("%Y"))
month = (datetime.datetime.today().strftime("%m"))
day = (datetime.datetime.today().strftime("%d"))
hour = (datetime.datetime.today().strftime("%H"))
minute = (datetime.datetime.today().strftime("%M"))
second = (datetime.datetime.today().strftime("%S"))
setyear = (input("Year"))
setmonth = (input("Month"))
setday = (input("Day"))
sethour = (input("Hour"))
setminute = (input("Minute"))
setsecond = (input("Second"))
while True:
print(year,'-',month,'-',day,' ',hour,':',minute,':',second)
time.sleep(1)
year = (datetime.datetime.today().strftime("%Y"))
month = (datetime.datetime.today().strftime("%m"))
day = (datetime.datetime.today().strftime("%d"))
hour = (datetime.datetime.today().strftime("%H"))
minute = (datetime.datetime.today().strftime("%M"))
second = (datetime.datetime.today().strftime("%S"))
if year == setyear and month == setmonth and day == setday and hour == sethour and minute == setminute and second == setsecond:
print("Alarm!")
break
else:
print("NO")
Output:
Year2020
Month11
Day12
Hour14
Minute12
Second00
2020 - 11 - 12 14 : 10 : 56
NO
2020 - 11 - 12 14 : 11 : 08
NO
....
2020 - 11 - 12 14 : 11 : 59
Alarm!

Python XML Parsing - need to correct while loop

Fairly new to Python. I'm parsing an XML file and the following code returns the undesired results. I can understand why I'm getting my results - there are two escalations in the XML for this deal and I'm getting results for each set. I'm need help updating my code to only return the monthly rent for each escalation in the XML:
<RentEscalations>
<RentEscalation ID="354781">
<BeginIn>7</BeginIn>
<Escalation>3.8</Escalation>
<RecurrenceInterval>12</RecurrenceInterval>
<EscalationType>bump</EscalationType>
</RentEscalation>
<RentEscalation ID="354782">
<BeginIn>61</BeginIn>
<Escalation>1.0</Escalation>
<RecurrenceInterval>12</RecurrenceInterval>
<EscalationType>bump</EscalationType>
</RentEscalation>
</RentEscalations>
The rent starts at $3.00/sqft for the first 6 months. This XML block shows that, for each 12 months (RecurrenceInterval), the rent will be $6.80/sqft ($3.00 base + $3.80 escalation). The following twelve months will be $10.60 ($6.80 + 3.80). Each year, the amount per square foot will increase by $3.80 until the 61st month in the term. At that point, the rent will increase by $1.00/sqft for the remainder of the term. The entire term of the lease is 120 months.
My results include 114 results based on the first escalation (3.80/sqft) followed by 114 rows showing as if the rent starts at $3.00/sqft incrementing by $1.00/sqft each year.
Any help is appreciated!
import xml.etree.ElementTree as ET
import pyodbc
import dateutil.relativedelta as rd
import datetime as dt
tree = ET.parse('C:\\FileLocation\\DealData.xml')
root = tree.getroot()
for deal in root.findall("Deals"):
for dl in deal.findall("Deal"):
dealid = dl.get("DealID")
for dts in dl.findall("DealTerms/DealTerm"):
dtid = dts.get("ID")
darea = float(dts.find("RentableArea").text)
dterm = int(dts.find("LeaseTerm").text)
for brrent in dts.findall("BaseRents/BaseRent"):
brid = brrent.get("ID")
rent = float(brrent.find("Rent").text)
darea = float(dts.find("RentableArea").text)
per = brrent.find("Period").text
dtstart = dts.find("CommencementDate").text
startyr = int(dtstart[0:4])
startmo = int(dtstart[5:7])
startday = int(dtstart[8:])
start = dt.date(startyr, startmo, startday)
end = start + rd.relativedelta(months=dterm)
if brrent.find("Duration").text is None:
duration = 0
else:
duration = int(brrent.find("Duration").text)
termbal = dterm - duration
for resc in dts.findall("RentEscalations/RentEscalation"):
rescid = resc.get("ID")
esctype = resc.find("EscalationType").text
begmo = int(resc.find("BeginIn").text)
esc = float(resc.find("Escalation").text)
intrvl = int(resc.find("RecurrenceInterval").text)
if intrvl != 0:
pers = termbal / intrvl
else:
pers = 0
escst = start + rd.relativedelta(months=begmo - 1)
i = 0
x = begmo
newrate = rent
while i < termbal:
billdt = escst + rd.relativedelta(months=i)
if per == "rsf/year":
monthlyamt = (newrate + esc) * darea / 12.0
if per == "month":
monthlyamt = newrate + esc
if per == "year":
monthlyamt = (newrate + esc) / 12.0
if per == "rsf/month":
monthlyamt = (newrate + esc) * darea
try:
if i % intrvl == 0:
level = x + 1
newrent = monthlyamt
x += 1
newrate += esc
else:
level = x
except ZeroDivisionError:
break
i += 1
if dealid == "1254278":
print(dealid, dtid, rescid, dterm, darea, escst, rent, intrvl, esctype, termbal, \
monthlyamt, billdt, pers, level, newrate, newrent)

pandas creating new table from two tables

I have to join two tables and create a table with dates, but my code is way to long and I believe that I done it the super long way.Apparently the soulution to this only had 22 lines. Is there another way and more shorter way to approach this problem. Here is the question
HERE IS MY CODE, and again I believe it is to long and I think there is a shorter way to do this.
import numpy as np
import pandas as pd
import datetime
#YOUR CODE GOES HERE#
def get_month(i):
"""this function returns the number of the month based on stringinput"""
if i == "January":
return 1
elif i == "February":
return 2
elif i == "March":
return 3
elif i == "April":
return 4
elif i == "May":
return 5
elif i == "June":
return 6
elif i == "July":
return 7
elif i == "August":
return 8
elif i == "September":
return 9
elif i == "October":
return 10
elif i == "November":
return 11
elif i == "December":
return 12
def get_reformatted_date(s):
"""this function reformats a datetime object to the output we're looking for"""
return s.strftime("%d-%b-%y")
month_names = []
tab1 = pd.read_csv("data1.csv")
tab2 = pd.read_csv("data2.csv")
tab1_tweets = tab1['Tweet'].tolist()[::-1]
tab2_tweets = tab2['Tweet'].tolist()[::-1]
tab1_months = tab1['Month'].tolist()[::-1]
tab2_months = tab2['Month'].tolist()[::-1]
tab1_days = tab1['Day'].tolist()[::-1]
tab2_days = tab2['Day'].tolist()[::-1]
tab1_years = tab1['Year'].tolist()[::-1]
tab2_years = tab2['Year'].tolist()[::-1]
all_dates = []
all_tweets = []
tab1_count = 0
tab2_count = 0
for i in range(len(tab1_tweets) + len(tab2_tweets)):
if(tab1_count < len(tab1_years) and tab2_count < len(tab2_years)):
t1_date = datetime.date(tab1_years[tab1_count], tab1_months[tab1_count], tab1_days[tab1_count])
t2_date = datetime.date(tab2_years[tab2_count], get_month(tab2_months[tab2_count]), tab2_days[tab2_count])
if t1_date > t2_date:
all_dates.append(t1_date)
all_tweets.append(tab1_tweets[tab1_count])
tab1_count += 1
else:
all_dates.append(t2_date)
all_tweets.append(tab2_tweets[tab2_count])
tab2_count += 1
elif(tab2_count < len(tab2_years)):
t2_date = datetime.date(tab2_years[tab2_count], get_month(tab2_months[tab2_count]), tab2_days[tab2_count])
all_dates.append(t2_date)
all_tweets.append(tab2_tweets[tab2_count])
tab2_count += 1
else:
t1_date = datetime.date(tab1_years[tab1_count], tab1_months[tab1_count], tab1_days[tab1_count])
all_dates.append(t1_date)
all_tweets.append(tab1_tweets[tab1_count])
tab1_count += 1
table_data = {'Date': all_dates, 'Tweet': all_tweets}
df = pd.DataFrame(table_data)
df['Date'] = df['Date'].apply(get_reformatted_date)
print(df)
data1.csv is
Tweet Month Day Year
Hello World 6 2 2013
I want ice-cream! 7 23 2013
Friends will be friends 9 30 2017
Done with school 12 12 2017
the data2.csv is
Month Day Year Hour Tweet
January 2 2015 12 Happy New Year
March 21 2016 7 Today is my final
May 30 2017 23 Summer is about to begin
July 15 2018 11 Ocean is still cold
I think that you can theoretically do this whole thing in one line:
finaldf = (pd.concat([pd.read_csv('data1.csv',
parse_dates={'Date':['Year', 'Month', 'Day']}),
pd.read_csv('data2.csv',
parse_dates={'Date':['Year', 'Month', 'Day']})
[['Date', 'Tweet']]])
.sort_values('Date', ascending=False))
But for the sake of readability, its better to split it into a few lines:
df1 = pd.read_csv('data1.csv', parse_dates={'Date':['Year', 'Month','Day']})
df2 = pd.read_csv('data2.csv', parse_dates={'Date':['Year', 'Month','Day']})
finaldf = (pd.concat([df1, df2[['Date', 'Tweet']]])
.sort_values('Date', ascending=False))
I think that for what you're trying to do, the main things to read up about are the parse_dates argument of pandas read_csv, and pd.concat to concatenate dataframes
Edit: in order to get the dates in the correct format as you have in your example output, you can call this after the code above, using Series.dt.strftime():
finaldf['Date'] = finaldf['Date'].dt.strftime('%d-%b-%y')

Count summer days between two dates

I want to count summer days between two dates. Summer is May first to August last.
This will count all days:
import datetime
startdate=datetime.datetime(2015,1,1)
enddate=datetime.datetime(2016,6,1)
delta=enddate-startdate
print delta.days
>>517
But how can only count the passed summer days?
You could define a generator to iterate over every date between startdate and enddate, define a function to check if a date represents a summer day and use sum to count the summer days:
import datetime
startdate = datetime.datetime(2015,1,1)
enddate = datetime.datetime(2016,6,1)
all_dates = (startdate + datetime.timedelta(days=x) for x in range(0, (enddate-startdate).days))
def is_summer_day(date):
return 5 <= date.month <= 8
print(sum(1 for date in all_dates if is_summer_day(date)))
# 154
Thanks to the generator, you don't need to create a huge list in memory with every day between startdate and enddate.
This iteration still considers every single day, even if it's not needed. For very large gaps, you could use the fact that every complete year has 123 summer days according to your definition.
You can create a few functions to count how many summer days you have between two days:
from datetime import date
def get_summer_start(year):
return date(year, 5, 1)
def get_summer_end(year):
return date(year, 8, 31)
def get_start_date(date, year):
return max(date, get_summer_start(year))
def get_end_date(date, year):
return min(date, get_summer_end(year))
def count_summer_days(date1, date2):
date1_year = date1.year
date2_year = date2.year
if date1_year == date2_year:
s = get_start_date(date1, date1_year)
e = get_end_date(date2, date1_year)
return (e - s).days
else:
s1 = max(date1, get_summer_start(date1_year))
e1 = get_summer_end(date1_year)
first_year = max(0,(e1 -s1).days)
s1 = get_summer_start(date2_year)
e1 = min(date2, get_summer_end(date2_year))
last_year = max(0,(e2 -s2).days)
other_years = date2_year - date1_year - 1
summer_days_per_year = (get_summer_end(date1_year) - get_summer_start(date1_year)).days
return first_year + last_year + (other_years * summer_days_per_year)
date1 = date(2015,1,1)
date2 = date(2016,6,1)
print count_summer_days(date1, date2)
Here is a better solution for large periods:
first_summer_day = (5,1)
last_summer_day = (8,31)
from datetime import date
startdate = date(2015,1,1)
enddate = date(2016,6,1)
# make sure that startdate > endate
if startdate > enddate:
startdate, endate = endate, startdate
def iter_yearly_summer_days(startdate, enddate):
for year in range(startdate.year, enddate.year+1):
start_period = startdate if year == startdate.year else date(year, 1, 1)
end_period = enddate if year == enddate.year else date(year, 12, 31)
year_first_summer_day = date(year, *first_summer_day)
year_last_summer_day = date(year, *last_summer_day)
summer_days_that_year = (min(year_last_summer_day, end_period) - max(year_first_summer_day, start_period)).days
print('year {} had {} days of summer'.format(year, summer_days_that_year))
yield summer_days_that_year
print(sum(iter_yearly_summer_days(startdate, enddate)))

How to fix the while loop in this program?

Write a python program that will take 3 lists:
Name Wage Hours
Juan 7.50 35
Rae 11.00 41
Ivanna 18.25 26
Lilly 9.25 35
Robert 11.10 45
and use this logic:
An employee gets overtime when they have worked more than 40 hours
Overtime pay is calculated using this formula:
Gross Pay = (35*Wage) + ((Hours-35)*Wage*1.5)
Regular pay is calculated using this formula:
Gross Pay = (Hours*Wage)
Use a loop to process these lists.
Print each employee, their wages, Hours and gross pay.
I'm running this program and I have the for loop. The input works fine, but the while loop that its supposed to have the same output is not giving me any output at all. Here's my code.
`Name = ["Juan","Rae","Ivanna", "Lilly", "Robert"]
Hours = [35,41,26,35,45]
Wage = [7.5,11,18.25,9.25,11.1]
print ("Name\tWage\tHours\tGP")
for X in range(5):
GP = 0
if(Hours[X] > 40):
GP = (35*Wage[X]) + ((Hours[X]-35)*Wage[X]*1.5)
else:
GP = Hours[X] * Wage[X]
print (Name[X],"\t", Wage[X],"\t", Hours[X],"\t", GP)
Name = ["Juan","Rae","Ivanna", "Lilly", "Robert"]
Hours = [35,41,26,35,45]
Wage = [7.5,11,18.25,9.25,11.1]
print ("Name\tWage\tHours\tGP")
counter = 5
Y = 0
while (Y):
if (Hours[Y] > 40):
GP = (35*Wage[Y]) + ((Hours[Y]-35)*Wage[Y]*1.5)
else:
GP = Hours[Y] * Wage[Y]
print (Name[Y],"\t", Wage[Y],"\t", Hours[Y],"\t", GP)`
my output is going as
Name Wage Hours GP
Juan 7.5 35 262.5
Rae 11 41 484.0
Ivanna 18.25 26 474.5
Lilly 9.25 35 323.75
Robert 11.1 45 555.0
Name Wage Hours GP
Juan 7.5 35 555.0
I don't know where the error is in the while loop.
Your last line needs to be indented. So instead of
while (Y):
if (Hours[Y] > 40):
GP = (35*Wage[Y]) + ((Hours[Y]-35)*Wage[Y]*1.5)
else:
GP = Hours[Y] * Wage[Y]
print (Name[Y],"\t", Wage[Y],"\t", Hours[Y],"\t", GP)
it needs to be
while (Y):
if (Hours[Y] > 40):
GP = (35*Wage[Y]) + ((Hours[Y]-35)*Wage[Y]*1.5)
else:
GP = Hours[Y] * Wage[Y]
print (Name[Y],"\t", Wage[Y],"\t", Hours[Y],"\t", GP)
because right now the print is outside of the while loop, so it is only printing with the value Y=0.
Have to follow python code indented and need to give proper while loop condition with (increment/decrement/boolean). As your code need to increment the value of Y.
Name = ["Juan","Rae","Ivanna", "Lilly", "Robert"]
Hours = [35,41,26,35,45]
Wage = [7.5,11,18.25,9.25,11.1]
print ("Name\tWage\tHours\tGP")
for X in range(5):
GP = 0
if(Hours[X] > 40):
GP = (35*Wage[X]) + ((Hours[X]-35)*Wage[X]*1.5)
else:
GP = Hours[X] * Wage[X]
print (Name[X],"\t", Wage[X],"\t", Hours[X],"\t", GP)
Name = ["Juan","Rae","Ivanna", "Lilly", "Robert"]
Hours = [35,41,26,35,45]
Wage = [7.5,11,18.25,9.25,11.1]
print ("Name\tWage\tHours\tGP")
counter = 5
Y = 0
while (Y<counter):
if (Hours[Y] > 40):
GP = (35*Wage[Y]) + ((Hours[Y]-35)*Wage[Y]*1.5)
else:
GP = Hours[Y] * Wage[Y]
print (Name[Y],"\t", Wage[Y],"\t", Hours[Y],"\t", GP)
Y=Y+1

Categories