print the first three months as a string in python - python

day = 1
month = 3
for x in range(3):
while day <= 31:
print(str(month)+"/"+str(day)+"/2019'")
day += 1
month += 1
I am trying to print the first 31 days from March-May. (I know April has 30 days, but I am not concerned with that.
The while loop works, printing out the first 31 days in march. The code does not loop through 2 more times and increment the month to sequentially print out the 31 days for April and May.
I am used to Java for loops and I am not familiar iterating over an nondeclared variable.

You need to reset the day back to one inside the outer loop otherwise day stays at 31 the second time through the loop. You can do this by moving the assignment inside the loop:
month = 3
for x in range(3):
day = 1
while day <= 31:
print(str(month)+"/"+str(day)+"/2019'")
day += 1
month += 1
Having said that, it's easier just to use for loops:
for month in range(3, 6):
for day in range(1, 32):
print(f"{month}/{day}/2019")

The only problem is that the variable day is not being reseted once a new month starts. You need to move the declaration day=1 inside the for-loop:
month = 3
for x in range(3):
day = 1
while day <= 31:
print(str(month)+"/"+str(day)+"/2019'")
day += 1
month += 1

Related

How to add +1 to a python variable every day?

I have three variables
a = 1
b = 2
c = 3
Every day, I need to add 1 to each variable
a = a + 1 (so a=2)
b = b + 1
c = c + 1
But I need that when tomorrow I run the script, to add 1 unit more:
a = a + 2 (so tomorrow a=3, after 2 days a = 4....)
b = b + 2
c = c + 2
And so on...I need every day to add +1.
Any ideas?
Choose some fixed reference date, and when the code runs, calculate the number of days from the reference date, adjust by some constant offset, and add that to your variables. So, maybe I choose 1/1/2022 as my reference date and an offset of 100 days. This means on 100 days after 1/1/2022 the variables don't get increased at all, 101 days after 1/1/2022 the variables are greater by 1, and so on.
If you need to only increase if the script actually ran on a date, keep a log file of days the script actually ran, or for that matter, save the increments directly!

Different calculations for this month compared to previous months in Pandas Dataframe

Consider sample data:
Month Members
JUL 10
AUG 10
SEP 10
I want to add a new column which is MemberValue, but I want the column to multiply the Members value by 10 if the month is NOT the current month (currently September 2021) and 100 if the Month value is the current month. The expected output would be like this:
Month Members MemberValue
JUL 10 100
AUG 10 100
SEP 10 1000
I have tried various versions of conditionals and continue to the "truth value is ambiguous" which we have all seen before in various contexts. I can calculate the three letter abbreviation of the month and the numerical value of the month (i.e. SEP or 9) but using those as comparisons for calculating the MemberValue column yields the error. I am sure I am missing something simple, but cannot crack this one. Thanks for taking a look.
My latest attempt which failed:
if df.index != months-1:
df['MemberValue'] = df['Members'] * 10
else:
df['MemberValue'] = df['Members'] * 100
Another previous attempt:
cur_month_name = str(today_date_time.strftime('%b')).upper()
if df['Month'] != cur_month_name:
df['MemberValue'] = df['Members'] * 10
else:
df['MemberValue'] = df['Members'] * 100
Also failed.
curr_month_short = str.upper(pd.Timestamp.now().month_name())[0:3]
df.loc[df['Month'] != curr_month_short, 'MemberValue'] = df['Members'] * 10
df.loc[df['Month'] == curr_month_short, 'MemberValue'] = df['Members'] * 100
output:
Out[13]:
Month Members MemberValue
0 JUL 10 100.0
1 AUG 10 100.0
2 SEP 10 1000.0
The first line gets the short name of the month - by simply getting today's month name and then slicing the first 3 letters (and applying str.upper) to them.
df.loc[df['Month'] != curr_month_short, 'MemberValue'] select all the rows where df['Month'] is different than curr_month_short, and assigning to the column MemberValue the value of df['Members'] * 10. Same thing to all rows where the current month is same curr_month_short
As for your code: notice the line df['Month'] != cur_month_name returns a series with boolean values - true or false for each row. if statement doesn't know what to do with it, hence the error. if... else logic can work well if you apply it over a single row at a time (let's say, looping over all row).
In my example, using this condition over .loc is what you intended it to do: take only the rows where the statement is "true", and apply to them the value.
Your code should look like this:
cur_month_name = str(today_date_time.strftime('%b')).upper()
boolean_series = df['Month'] != cur_month_name
df.loc[boolean_series, 'MemberValue'] = df['Members'] * 10
df.loc[~boolean_series, 'MemberValue'] = df['Members'] * 100
(the '~' operator returns the opposite: true turns into false and false into true)
You can use strftime to get abbreviated month name and np.where to apply your operation:
cur_month_name = pd.Timestamp.today().strftime('%b').upper()
df['MemberValue'] = np.where(df['Month'] == cur_month_name,
df['Members']*100, df['Members']*10)
Output:
>>> df
Month Members MemberValue
0 JUL 10 100
1 AUG 10 100
2 SEP 10 1000
>>> cur_month_name
'SEP'
For your previous attempt, your idea is good to use month name but you ask Python to make a test to a list of value (True / False). To do that, you need to apply the test on each row and not on whole series:
>>> df.apply(lambda x: x['Members']*100 if x['Month'] == cur_month_name
else x['Members']*10, axis=1)
0 100
1 100
2 1000
dtype: int64

How to give value 0 to absent values

I have a list of tuples, including the date, and the number of "beeps" on that date. However, if there were 0 beeps on a certain date, then that date is simply not present in the list. I need these dates to be present, with the number 0 for the beeps
I've tried solving this using excel and python, but I can't find a solution for it.
16/10/2017 7
18/10/2017 3
21/10/2017 7
23/10/2017 20
24/10/2017 7
25/10/2017 6
This is the start of what I have, and I need this to become:
16/10/2017 7
17/10/2017 0
18/10/2017 3
19/10/2017 0
20/10/2017 0
21/10/2017 7
22/10/2017 0
23/10/2017 20
24/10/2017 7
25/10/2017 6
First save the first date with its value. Then iterate through the dates, saving the dates between the last saved date and the current date with a value of 0, then saving the current date with its value.
A psuedo-code solution would be:
last_saved_date, value = read_first_date()
save(last_saved_date, value)
while not_at_end_of_file():
date, value = read_date()
while last_saved_date + 1 < date:
last_saved_date += 1
save(last_saved_date, 0)
save(date, value)
last_saved_date = date

Find a day of week for given first day in month

How could be calculated a day of the week if we know the day number of the first day in month?
Lets say we have 1..7 days in a week
I want to get number of the 4th day in the month if the 1st = 5 (Friday) then result should be 1 (Monday).
1st - 5 Friday
2nd - 6 Saturday
3rd - 7 Sunday
4th - 1 Monday
(a=4, b=5) = 1
I tried to calculate the common formula:
result = (a + b - 1) % 7
So it works for all cases except the case when a = 3, 10, 17, 24, 31, because result = 0, but should be 7.
How can it be fixed to get this formula work for all days?
You need to avoid the result zero. Here is one way:
result = (a + b - 2) % 7 + 1
You subtract one more from your sum, to allow zero and work on the previous day, then you take the remainder modulo 7 to get the day which can include zero, then add one to get to the day wanted and avoid zero. Note that the order of operations will do the modulus before adding one. If you want to make that more explicit, you could use
result = ((a + b - 2) % 7) + 1

Python date function bugs

I am trying to create a function in python which will display the date. So I can see the program run, I have set one day to five seconds, so every five seconds it will become the next 'day' and it will print the date.
I know there is already an in-build function for displaying a date, however I am very new to python and I am trying to improve my skills (so excuse my poor coding.)
I have set the starting date to the first of January, 2000.
Here is my code:
import time
def showDate():
year = 00
month = 1
day = 1
oneDay = 5
longMonths = [1, 3, 5, 7, 8, 10, 12]
shortMonths = [4, 6, 9, 11]
while True:
time.sleep(1)
oneDay = oneDay - 1
if oneDay == 0:
if month in longMonths:
if day > 31:
day = day + 1
else:
month = month + 1
day = 0
if month == 2:
if day > 28:
day = day + 1
else:
month = month + 1
day = 0
if month in shortMonths:
if day > 30:
day = day + 1
else:
month = month + 1
day = 0
if day == 31 and month == 12:
year = year + 1
print(str(day) + '/' + str(month) + '/' + str(year))
oneDay = 5
showDate()
However, when I try to run the program this is the output I get this:
>>>
0/3/0
0/5/0
0/7/0
0/8/0
0/10/0
0/12/0
0/13/0
0/13/0
0/13/0
I don't know why this is happening, could someone please suggest a solution?
There's no possible path through your code where day gets incremented.
I think you are actually confused between > and <: you check if day is greater than 31 or 28, which it never is. I think you mean if day < 31: and so on.
First of all, it's easier to just set time.sleep(5) instead of looping over time.sleep(1) 5 times. It's better to have a list of values with days of the month, not just 2 lists of the long and short months. Also your while loop is currently indefinite, is that intentional?
Anyway, your main problem was comparing day > 31, but there's lots of things that can be improved. As I said, I'm removing the use of oneDay to just do sleep(5) as it's cleaner and having one daysInMonths list.
import time
def showDate():
year = 00
month = 1
day = 1
daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
Now you can have only one if check about if the day has reached the end of a month, like this:
while True:
time.sleep(5)
if day < daysInMonths[month-1]:
day += 1
This will check the index of the list for the current month. It uses -1 because lists begin at index 0, and your months begin at 1. (ie. the months run from 1-12 but the list's indices are 0-11). Also I used the += operator, which is basically short hand for var = var + something. It works the same and looks neater.
This test encompasses all months, and then the alternative scenario is that you need to increment the month. I recommend in this block that you first check if the month is 12 and then increment the year from there. Also you should be setting day and month back to 1, since that was their starting value. If it's not the end of the year, increment the month and set day back to 1.
else:
if month == 12:
year += 1
day = 1
month = 1
else:
month += 1
day = 1
print("{}/{}/{}".format(day, month, year))
I also used the string.format syntax for neatness. With format, it will substitute the variables you pass in for {} in the string. It makes it easier to lay out how the string should actually look, and it converts the variables to string format implicitly.
Try this.
The day comparisons should be <, not >. When going to the next month, I set the day to 1, because there are no days 0 in the calendar. And I use elif for the subsequent month tests, because all the cases are exclusive.
def showDate():
year = 00
month = 1
day = 1
oneDay = 5
longMonths = [1, 3, 5, 7, 8, 10, 12]
shortMonths = [4, 6, 9, 11]
while True:
time.sleep(1)
oneDay = oneDay - 1
if oneDay == 0:
if month in longMonths:
if day < 31:
day = day + 1
else:
month = month + 1
day = 1
elif month == 2:
if day < 28:
day = day + 1
else:
month = month + 1
day = 1
if month in shortMonths:
if day < 30:
day = day + 1
else:
month = month + 1
day = 1
if day == 31 and month == 12:
year = year + 1
month = 1
print(str(day) + '/' + str(month) + '/' + str(year))
oneDay = 5

Categories

Resources