I'm doing a task in Python, which is to create a zodiac calendar judging by input month and day of the month.
I've made a successful calendar, however, I have no idea how to solve the problem, if I input an incorrect month name or nonexistent date.
I have tried tons of things: to create a different hierarchy, or under each zodiac sign I wrote else: print ('Entering an incorrect date'). I even tried to register with if day <0 and day> 31 or month! = 'March' or month! = 'April', etc... It turned out to be a huge useless function in the end, and nothing worked either.
I feel that there is a one-line solution here to detect days < 0 and > 31 and incorrect month name, but I just can't understand it. Could somebody help, please?
month = input('Enter the month: ')
day = int(input ('Enter the date of month: '))
if day >= 21 and day <= 31 and month.lower() == 'march' or day >=1 and day <= 19 and month.lower() == 'april':
zodiac='Aries'
if day >= 20 and day <= 30 and month.lower() == 'april' or day >=1 and day <= 19 and month.lower() == 'may':
zodiac='Taurus'
if day >= 21 and day <= 31 and month.lower() == 'may' or day >=1 and day <= 20 and month.lower() == 'june':
zodiac='Gemini'
if day >= 21 and day <= 30 and month.lower() == 'june' or day >=1 and day <= 22 and month.lower() == 'july':
zodiac='Cancer'
if day >= 23 and day <= 31 and month.lower() == 'july' or day >=1 and day <= 22 and month.lower() == 'august':
zodiac='Leo'
if day >= 23 and day <= 31 and month.lower() == 'august' or day >=1 and day <= 22 and month.lower() == 'september':
zodiac='Virgo'
if day >= 23 and day <= 30 and month.lower() == 'september' or day >=1 and day <= 22 and month.lower() == 'october':
zodiac='Libra'
if day >= 23 and day <= 31 and month.lower() == 'october' or day >=1 and day <= 21 and month.lower() == 'november':
zodiac='Scorpio'
if day >= 22 and day <= 30 and month.lower() == 'november' or day >=1 and day <= 21 and month.lower() == 'december':
zodiac='Sagittarius'
if day >= 22 and day <= 31 and month.lower() == 'december' or day >=1 and day <= 19 and month.lower() == 'january':
zodiac='Capricorn'
if day >= 20 and day <= 31 and month.lower() == 'january' or day >=1 and day <= 18 and month.lower() == 'february':
zodiac='Aquarius'
if day >= 19 and day <= 28 and month.lower() == 'february' or day >=1 and day <= 20 and month.lower() == 'march':
zodiac='Pisces'
print('Conclusion:')
print(zodiac)
You might want to look into the datetime module. With it, you can do comparisons between dates and times easily without the need for extraneous if statements.
For example, if one were to do something like:
import datetime
dt = datetime.datetime.today()
print dt.month
Then you would get:
3
So instead of reading in input for months in a string format, you could simply ask for the number of the month to help create a datetime object more easily. Alternatively, you could do something like this:
month_input = input("What is the month?")
months = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"]
month_input = month_input.lower().strip() #convert to lowercase and remove whitespace
month_num = months.index(month_input) + 1 #Add one because lists start at index 0
That way you can get the number of the month to use a datetime object to do your comparisons and evaluations from there.
Related
Write a program that takes a date as input and outputs the date's season in the northern hemisphere. The input is a string to represent the month and an int to represent the day.
Ex: If the input is:
April
11
the output is:
Spring
In addition, check if the string and int are valid (an actual month and day).
Ex: If the input is:
Blue
65
the output is:
Invalid
The dates for each season in the northern hemisphere are:
Spring: March 20 - June 20
Summer: June 21 - September 21
Autumn: September 22 - December 20
Winter: December 21 - March 19
input_month = input()
input_day = int(input())
if input_month == ('April' or 'May') and 1<= input_day <=31:
print('Spring')
if input_month == ('March') and 20<= input_day <= 31:
print('Spring')
if input_month == ('June') and 1<= input_day <= 20:
print('Spring')
if input_month == ('July' or 'August') and 1<= input_day <=31:
print('Summer')
if input_month == ('June') and 20<= input_day <= 30:
print('Summer')
if input_month == ('September') and 1<= input_day <= 21:
print('Summer')
if input_month == ('October') and 1<= input_day <= 31:
print('Autumn')
if input_month == ('November') and 1<= input_day <=31:
print('Autumn')
if input_month == ('September') and 22<= input_day <= 30:
print('Autumn')
if input_month == ('December') and 1<= input_day <= 20:
print('Autumn')
if input_month == ('January') and 1<= input_day <= 31:
print('Winter')
if input_month == ('February') and 1<= input_day <= 28:
print('Winter')
if input_month == ('December') and 21<= input_day <= 31:
print('Winter')
if input_month == ('March') and 1 <=input_day <= 19:
print('Winter')
else:
print('Invalid')
Below is the test results I got for the code
Total score: 6 / 10
1:Compare output
0 / 1
Output differs. See highlights below.
Special character legend
Input
April
11
Your output
Spring
Invalid
Expected output
Spring
2:Compare output
1 / 1
Input
March
3
Your output
Winter
3:Compare output
1 / 1
Input
Word
21
Your output
Invalid
4:Compare output
1 / 1
Input
February
39
Your output
Invalid
5:Compare output
0 / 1
Output differs. See highlights below.
Special character legend
Input
June
21
Your output
Summer
Invalid
Expected output
Summer
6:Compare output
0 / 1
Output differs. See highlights below.
Special character legend
Input
November
7
Your output
Autumn
Invalid
Expected output
Autumn
7:Compare output
1 / 1
Input
September
31
Your output
Invalid
8:Compare output
1 / 1
Input
December
-1
Your output
Invalid
9:Compare output
1 / 1
Input
February
0
Your output
Invalid
10:Compare output
0 / 1
Output differs. See highlights below.
Special character legend
Input
October
31
Your output
Autumn
Invalid
Expected output
Autumn
To eliminate all your complex checks, I used the dictionary data structure and a couple of lists. I also created a namedtuple called Season which defines a tuple consisting of the season as a string followed by two ints indicating the first day of the month the season is valid as well as the last day of the month the season is valid. Thus, some months have two Season records for the respective seasons. Here is my code:
from collections import namedtuple
Season = namedtuple('Season',['SN', 'stDay', 'ndDay'])
def findSeason():
months = ['January', 'Febuary', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December']
month_length = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
calendar = {'January':[Season('Winter', 1, 31)],
'February': [Season('Winter', 1, 29)],
'March': [Season('Winter', 1, 19), Season('Spring', 20, 31)],
'April': [Season('Spring', 1, 30)],
'May': [Season('Spring', 1, 31)],
'June': [Season('Spring', 1, 20), Season('Summer', 21, 30)],
'July': [Season('Summer', 1, 31)],
'August': [Season('Summer', 1, 31)],
'September': [Season('Summer', 1, 21), Season('Autumn', 22, 30)],
'October': [Season('Autumn', 1, 31)],
'November': [Season("Autumn", 1, 30)],
'December': [Season('Autumn', 1, 20), Season('Winter', 21, 31)]}
day = None
month = None
mnth_indx = None
while True:
month = input("Please enter a month: ")
if month in calendar.keys():
mnth_indx = months.index(month)
break
print(f"Please enter a valid Month to include: {', '.join(months)}")
while True:
day = int(input("Please enter a day: "))
if day > 0 and day <= month_length[mnth_indx]:
break
print(f"Please enter a valid day in range of 1 to {month_length[mnth_indx]} for the month of {month}")
season_list = calendar[month]
for sn in season_list:
if day >= sn.stDay and day <= sn.ndDay:
print (f'The Current Season is {sn.SN}')
return
print('Error Invalid Data')
return
To run execute:
findSeason()
This will result in something along the lines of:
Please enter a month: Septembeer
Please enter a valid Month to include: January, Febuary, March, April, May, June, July, August, September, October, November, December
Please enter a month: September
Please enter a day: 16
The Current Season is Summer
So i have this problem, I want to calculate an amount of money between the first and last day of the month.
Example:
I am going to receive a payment of $1000 for a job that is going to take 3 months but i want to subtract the amount I'm going to receive each month lets say I work 8 a day 5 days a week.
def get_montly_adjustments(self, start_date, end_date, project_id):
# calculating the month first day and last day
month_range = monthrange(year, month)
first_day_month_str = "%s-%s-01" % (year, month)
last_day_month_str = "%s-%s-01" % (year, month, month_range[1])
month_first_day = datetime.strptime(first_day_month_str, "%Y-%m-%d")
month_last_day = datetime.strptime(last_day_month_str, "%Y-%m-%d")
I have created a function to calculate the first and last day of the month but im looking for an idea on how to calculate the amount?
Thanks!.
First, let's not convert a date to string and parse it back. We can do better:
def get_montly_adjustments(self, start_date, end_date, project_id):
first_of_month = date(start_date.year, start_date.month, 1)
last_of_month = date(start_date.year, start_date.month + 1, 1) + timedelta(-1)
Assuming that workdays are Monday through Friday, I get
day = first_of_month
workdays = 0
while day <= last_of_month:
if day.weekday() not in [5, 6]: # Saturday, Sunday
workdays += 1
day += timedelta(1)
print(f"workdays: {workdays}")
It's not clear to me how you expect to be paid. This probably depends on country and law regulations. One approach would be as follows
Starting on 2021-06-09, work until 2021-09-08 (3 months) gives 4 payments:
9 to 30 in June = 22 days (= x workdays)
1 to 31 in July = 31 days (= x workdays)
1 to 31 in August = 31 days (= x workdays)
1 to 8 in September = 8 days (= x workdays)
Code for that:
def get_montly_adjustments(self, start_date, end_date, project_id):
# Calculate all workdays in project range
day = start_date
last_of_month = date(day.year, day.month + 1, 1) + timedelta(-1)
workdays = 0
workdayspermonth = []
while day <= end_date:
if day.weekday() not in [5, 6]:
workdays += 1
if day == last_of_month or day == end_date:
workdayspermonth.append(workdays)
workdays = 0
last_of_month = date(day.year, day.month + 2, 1) + timedelta(-1) # next last of month
day += timedelta(1)
# Get to the money
monthnames = {1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "May", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Oct",
11: "Nov", 12: "Dec"}
totalworkdays = sum(workdayspermonth)
print(f"Total workdays: {totalworkdays}")
moneyperday = 1000 / totalworkdays
print(f"That's an awesome {moneyperday:.2f} USD per day")
for month in range(len(workdayspermonth)):
workdays = workdayspermonth[month]
print(f"Get paid! {workdays * moneyperday:.2f} USD for {workdays} workdays in {monthnames[start_date.month + month]}")
Output for
get_montly_adjustments(None, date(2021, 6, 9), date(2021, 9, 9), 815)
is
Total workdays: 67
That's an awesome 14.93 USD per day
Get paid! 238.81 USD for 16 workdays in Jun
Get paid! 328.36 USD for 22 workdays in Jul
Get paid! 328.36 USD for 22 workdays in Aug
Get paid! 104.48 USD for 7 workdays in Sep
I'm going to use pandas date range but perhaps someone can modify it for datetime.
create the days in the month range:
days = pd.date_range("01/01/2021", "03/01/2021", freq="D")
state what days you work:
working_days = ["Mon", "Tue", "Wed", "Thu", "Fri"]
Find the days in the month you would work in that time:
worked_days = days[days.strftime('%a').isin(days_worked)]
multiply the number of days worked by your price per day:
cost = len(worked_days)*8*price_per_hour
You may need to take into account bank holidays, days off etc.
I'm teaching myself python to ATBS. Instead of spending 45 minutes typing out a bunch of repetitive data in excel I've spent the past 90 failing to write a simple calendar script.
Starting with the values "2012-09-01" and "2012-09-30" I want to each line to increase the month value by 1 it hits 12 and at which point the year value advances by 1, until the date 2018-12-31.
e.g.
"2012-09-01 2012-09-30
2012-10-01 2012-10-31
2012-11-01 2012-11-30
2012-12-01 2012-12-31"
Here's my code, which stops at 2012-12-31.
import datetime
year = 2012
month = 9
day_start = 1
day_end = 31
while year <= 2018:
while month <= 12:
if month == 4 or month == 6 or month == 9 or month == 11:
day_end = 30
else:
day_end = 31
print(datetime.date(year, month, day_start), " ", datetime.date(year, month, day_end))
month = month + 1
year = year + 1
Any help is much appreciated!
Check this out. Using the calendar library to detect leap years.
import datetime
import calendar
year = 2012
month = 9
day_start = 1
day_end = 31
while year <= 2018:
while month <= 12:
if month == 4 or month == 6 or month == 9 or month == 11:
day_end = 30
elif month == 2:
day_end = 29 if calendar.isleap(year) else 28
else:
day_end = 31
print(datetime.date(year, month, day_start), " ", datetime.date(year, month, day_end))
month = month + 1
year = year + 1
month = 1
Line
if month == 4 or month == 6 or month == 9 or month == 11:
can be abbreviated to:
if month in (4, 6, 9, 11):
I have a dataframe with a column that includes individuals' birthdays. I would like to map that column to the individuals' astrology sign using code I found (below). I am having trouble writing the code to creat the variables.
My current dataframe looks like this
birthdate answer YEAR MONTH-DAY
1970-03-31 5 1970 03-31
1970-05-25 9 1970 05-25
1970-06-05 3 1970 06-05
1970-08-28 2 1970 08-28
The code I found that creates a function to map the dates is available at this website: https://www.geeksforgeeks.org/program-display-astrological-sign-zodiac-sign-given-date-birth/
Any tips would be appreciated.
Change previous answer by Series.dt.month_name with lowercase strings:
def zodiac_sign(day, month):
# checks month and date within the valid range
# of a specified zodiac
if month == 'december':
return 'Sagittarius' if (day < 22) else 'capricorn'
elif month == 'january':
return 'Capricorn' if (day < 20) else 'aquarius'
elif month == 'february':
return 'Aquarius' if (day < 19) else 'pisces'
elif month == 'march':
return 'Pisces' if (day < 21) else 'aries'
elif month == 'april':
return 'Aries' if (day < 20) else 'taurus'
elif month == 'may':
return 'Taurus' if (day < 21) else 'gemini'
elif month == 'june':
return 'Gemini' if (day < 21) else 'cancer'
elif month == 'july':
return 'Cancer' if (day < 23) else 'leo'
elif month == 'august':
return 'Leo' if (day < 23) else 'virgo'
elif month == 'september':
return 'Virgo' if (day < 23) else 'libra'
elif month == 'october':
return 'Libra' if (day < 23) else 'scorpio'
elif month == 'november':
return 'scorpio' if (day < 22) else 'sagittarius'
dates = pd.to_datetime(astrology['birthdate'])
y = dates.dt.year
now = pd.to_datetime('now').year
astrology = astrology.assign(month = dates.dt.month_name().str.lower(),
day = dates.dt.day,
year = y.mask(y > now, y - 100))
print (astrology)
birthdate answer YEAR MONTH-DAY month day year
0 1970-03-31 5 1970 03-31 march 31 1970
1 1970-05-25 9 1970 05-25 may 25 1970
2 1970-06-05 3 1970 06-05 june 5 1970
3 1970-08-28 2 1970 08-28 august 28 1970
astrology['sign'] = astrology.apply(lambda x: zodiac_sign(x['day'], x['month']), axis=1)
print (astrology)
birthdate answer YEAR MONTH-DAY month day year sign
0 1970-03-31 5 1970 03-31 march 31 1970 aries
1 1970-05-25 9 1970 05-25 may 25 1970 gemini
2 1970-06-05 3 1970 06-05 june 5 1970 Gemini
3 1970-08-28 2 1970 08-28 august 28 1970 virgo
You can apply the zodiac_sign function to the dataframe as -
import pandas as pd
from io import StringIO
# Sample
x = StringIO("""birthdate,answer,YEAR,MONTH-DAY
1970-03-31,5,1970,03-31
1970-05-25,9,1970,05-25
1970-06-05,3,1970,06-05
1970-08-28,2,1970,08-28
""")
df = pd.read_csv(x, sep=',')
df['birthdate'] = pd.to_datetime(df['birthdate'])
df['zodiac_sign'] = df['birthdate'].apply(lambda x: zodiac_sign(x.day, x.strftime("%B").lower()))
print(df)
Output:
birthdate answer YEAR MONTH-DAY zodiac_sign
0 1970-03-31 5 1970 03-31 aries
1 1970-05-25 9 1970 05-25 gemini
2 1970-06-05 3 1970 06-05 Gemini
3 1970-08-28 2 1970 08-28 virgo
I'm writing a program where the user will input 3 numbers the day month and year and it will output in the format 2nd January 2014. So far i have done this
year =input("what year is it")
month=int(input("what is the numerical value of the month"))
day=input("what number day is it")
if month == 1:
January = str(month)
if day == 1 or 21 or 31:
print (day+"st January",year)
elif day == 2 or 22:
print (day+"nd January",year)
elif day ==3 or 23:
print (day+"rd January",year)
elif day == 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 or 18 or 19 or 20 or 24 or 25 or 26 or 27 or 28 or 29 or 30:
print (day+"th January",year)
the problem i have run into is that when i input a day such as 4 it will ouput as 4st January 2014.
I am using python 3 and have learnt for and while loops and also if statements if that helps
Use the libraries and dictionaries, a good rule to remember is if you need more than two ifs a dictionary might be better.
from datetime import date
ext_dir = {1:'st.', 2:'nd.', 3:'rd.',
21:'st.', 22:'nd.', 23:'rd.',
31:'st.' } # all the rest are th
# prompt for the year month day as numbers remember to int them
thedate = date(year, month, day)
ext = ext_dir.get(day, 'th.')
datestr = thedate.strftime('%%d%s %%M %%Y' % ext)
The problem you are running in to is that when you perform the check:
if day == 1 or 21 or 31:
operator precedence in python makes this statement act something like this:
if (day == 1) or (21) or (31):
and in python, like many other languages, non-null/non-zero values are "true", so you always evaluate to true in the first test. To fix this, modify the if statement, and all of the following tests to look more like the following:
if (day == 1) or (day == 21) or (day == 31):
year =input("what year is it")
month=int(input("what is the numerical value of the month"))
day=input("what number day is it")
if month == 1:
January = str(month)
if day == 1 or day == 21 or day == 31:
print (day+"st January",year)
elif day == 2 or day == 22:
print (day+"nd January",year)
elif day ==3 or day == 23:
print (day+"rd January",year)
else:
print (day+"th January",year)