converting an input date into a string? - python

I want to know how I can convert an input date for example if I enter 01/01/1996, the output would be "1 January 1996", I need to be able to do this for any date that is entered.
I need to use slicing.
Thank you in advance.
inLine = input("please enter a date (dd/mm/yyyy) : ").split(',')
monthNames = ("January", "February", "March", \
"April", "May", "June", \
"July", "August", "September", \
"October", "November", "December" )
month = inLine [:10]
month2 = "month"[:1]
day = inLine
year = inLine[0:2]
year2 = "year"[0:4]
print("this is the date %s %s %s." % (month2, day2, year2))

I don't know why you need split your input when datetime parsing libraries already exist in Python.
>>> from datetime import datetime
>>> datetime.strptime('01/01/1996', '%M/%d/%Y').strftime('%d %B %Y')
'01 January 1996'

This is very simplistic response. You need to go away and learn about arrays, indexing and manipulating them. I also suggest, if this is homework of some kind, you go through and do more examples and look into what happens if, for example, I enter invalid input.
inLine = input("please enter a date (dd/mm/yyyy) : ").split('/')
monthNames = ("January", "February", "March", \
"April", "May", "June", \
"July", "August", "September", \
"October", "November", "December" )
day = int(inLine[0])
month = int(inLine[1])
year = int(inLine[2])
print("this is the date %s %s %s." % (day, monthNames[month-1], year))

Related

Expected type 'SupportsIndex', got 'str' instead

import random
n = str(["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",])
for index in range(n):
In this line:
for index in range(n):
range() is a function in python that the argument is an integer, but you pass n, which is a string.
If you want to loop over the strings in that list, try:
import random
n = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",]
for index in n:
print(index) # print the string in the list
If you want the index of the element in the array, try:
import random
n = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",]
for index, string in enumerate(n):
print(index) # print the index of the string in the list
print(string) # print the string in the list

Creating a function that checks if a date is valid

one of the revision questions was to create a function that checks if a date is valid or not and return a boolean. We were given the first two lines of the function, as so.
Edit: We are not allowed to use inbuilt functions that do all the work such as date.time
month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
Where the days_in_month list contains the maximum day number for the respective months.
Test cases:
is_a_valid_date("January 28 6")) False
is_a_valid_date("January 21")) True
is_a_valid_date(" June 15B ")) False
Code so far:
def is_a_valid_date(date):
month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
clean_date = date.split()
clean_date[1:] = ["".join(clean_date[1:])]
a = False
b = False
if clean_date[0] in month_names:
a = True
x = month_names.find(clean_date[0])
else:
a = a
if clean_date[1].isdigit() == True and int(clean_date[1]) <= int(days_in_month[x]):
b = True
else:
b = b
if a == True and b == True:
return True
else:
return False
I'm having trouble figuring out how to create a condition that sees if the date number inputted is <= the respective month's maximum date number if a = True. I tried using .find but it doesn't seem to work on lists and even then I'm not sure I implemented it properly.
You can simplify that condition like this:
def is_a_valid_date(date):
month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October",
"November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
month, day = date.split(maxsplit=1)
if day.isdigit():
return int(day) <= days_in_month[month_names.index(month)]
return False
Get the name of the month and day from date. Use that name to find days count in days list. Then convert days to int and compare with value from that list. If day can't be converted to int just return False.
I suggest making a dictionary for every max. no. of days per month (eg. days_in_month={January:31,...} and use days_in_month.get(clean_date[0]) instead. so you don't need x also or clean_date[1]
I hope my answer is what you are looking for.
First I have a dictionary that contains all of the months and their max day number values. We check the inputted day value against the inputted month name using the dictionary month_dictionary and get() like this: if day > month_dictionary.get(month):. If the day value is larger than the month's max day value or smaller than 0, than the function returns False and tells you why (which you can delete if you want).
The second function just has a fancy line that makes inputting the date in easier. month, dayRAW = date.split(" ") splits the 1 inputted string into 2 variables, month and dayRAW when the program sees a space in the string. They will then be used in the same way as the first function (after converting the day string into a number, day = int(dayRAW)).
month_dictionary = {"January": 31,
"February": 28,
"March": 31,
"April": 30,
"May": 31,
"June": 30,
"July": 31,
"August": 31,
"September": 30,
"October": 31,
"November": 30,
"December": 31}
def is_a_valid_date_1(month, day):#Input the month with quotes
if day > month_dictionary.get(month):#Finds the corresponding value(number of days) to the month name
print("Day number is too large")
return False
elif day <= 0:
print("Day number can't be zero or smaller")
return False
else:
print("This is a valid date")
return True
def is_a_valid_date_2(date):
month, dayRAW = date.split(" ")#Separates the date string when it sees a space
day = int(dayRAW)#Turns the string into a workable integer
if day > month_dictionary.get(month):#Finds the corresponding value(number of days) to the month name
print("Day number is too large")
return False
elif day <= 0:
print("Day number can't be zero or smaller")
return False
else:
print("This is a valid date")
return True
It also appears mx0 has a condensed version of what I have written. Nice job mate.
I also hope this helps any other passing people :)

Bokeh plot with x values overlap

I did a plot with the bokeh library, the output seems OK except for a overlapping of the x categorical variables.
There is a simple way to separate each month so there is no overlap between each other ?
I tried with dodge() but I couldn't define the parameters inside the function
cumple.txt file:
{"people":
[{"name": "daniela", "birthday": "8/05/1990"},
{"name": "mariano", "birthday": "5/08/1990"},
{"name": "agustin", "birthday": "27/11/1993"},
{"name": "laura", "birthday": "20/10/2000"}]}
Here is my code and the output:
from collections import Counter
import json
from bokeh.plotting import figure, show, output_file
with open("cumple.txt", "r") as f:
info = json.load(f)#carga todo el dictionario en info
s=[]
for i in info['people']:
s.append(i['birthday'])
months=[]
num_to_string = {
1: "January",
2: "February",
3: "March",
4: "April",
5: "May",
6: "June",
7: "July",
8: "August",
9: "September",
10: "October",
11: "November",
12: "December"
}
month=0
for x in s:
month=int(x.split('/')[1])[![enter image description here][1]][1]
months.append(num_to_string[month])
output_file("figura.html")
x_categories = []
for u in num_to_string.values():
x_categories.append(u)
print(x_categories)
x=[]
for j in months:
x.append(j)
print (x)
y=[]
for r in Counter(months).values():
y.append(r)
print(y)
p = figure(title='cumple de amigos',x_range=x_categories, x_axis_label='months', y_axis_label='amount of birthdays')
p.title.align = 'center'
p.vbar(x=x, top=y, width=0.5)
show(p)
print(Counter(months))
Two obvious ways to avoid the labels overlapping:
Increase the width of the graph by setting plot_width:
p = figure(title='cumple de amigos',x_range=x_categories, x_axis_label='months', y_axis_label='amount of birthdays', plot_width=1000)
Rotate the X-axis labels (don't forget to import pi):
p.xaxis.major_label_orientation = pi/4

Creating attributes of attributes - possible?

I am dealing with monthly data for a number of different data sets (e.g. air temperature, ocean temperature, wind speeds etc), whereby each month and each data set will share similar attributes. I want to be able to initialise and populate these attributes as efficiently as possible. So far I can only think of trying to somehow append new attributes to pre-existing attributes. Is this possible in Python?
For example, let's say I initialise all my monthly variables like the following:
class Data_Read:
def __init__(self, monthly=np.zeros((200,200,40))): #3D data
self.jan = monthly
self.feb = monthly
self.march = monthly
self.april = monthly
self.may = monthly
self.june = monthly
self.july = monthly
self.august = monthly
self.sept = monthly
self.oct = monthly
self.nov = monthly
self.dec = monthly
Then I can create a new data set for each month which will become something like air_temp.jan or wind_speed.june by doing the following:
air_temp = Data_Read()
wind_speed = Data_Read()
These would be the raw data attributes. However I would then like to do some processing to each of these data sets (like de-trending). Is there a way I can create a class (or a new class?) that will generate new attributes like self.jan.detrend. Basically I want to avoid having to write 12 lines of code for every attribute I want to create, and then be able to easily call any "attribute of the attribute" in my data processing functions thereafter.
Many thanks.
Here's an example of how you could store everything internally in a dictionary and still reference the arrays as attributes as well as call functions on arrays by name:
import numpy as np
class Data_Read:
def __init__(self, monthly_shape=(200, 200, 40)): #3D data
months = [
"jan",
"feb",
"march",
"april",
"may",
"june",
"july",
"august",
"sept",
"oct",
"nov",
"dec"
]
self._months = {month: np.zeros(monthly_shape) for month in months}
def detrend(self, month):
# this is a dummy function that just increments
return self._months[month] + 1
def __getattr__(self, name):
if name in self._months:
return self._months[name]
return super().__getattr__(name)
air_temp = Data_Read()
print(air_temp.jan.shape) # (200, 200, 40)
print((air_temp.detrend("jan") == 1).all()) # True
You can also achieve the same result using setattr and getattr because attributes are just stored in a dictionary on the object anyway:
import numpy as np
class Data_Read:
def __init__(self, monthly_shape=(200, 200, 40)): #3D data
months = [
"jan",
"feb",
"march",
"april",
"may",
"june",
"july",
"august",
"sept",
"oct",
"nov",
"dec"
]
for month in months:
setattr(self, month, np.zeros(monthly_shape))
def detrend(self, month):
# this is a dummy function that just increments
return getattr(self, month) + 1

difference between two dates python [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
from datetime import date
future = input("Enter a date(dd/mm/yyyy): ")
daystring = future[0:2]
monthstring = future[3:5]
yearstring = future[6:10]
today = (date.today())
month = date.today().month
year = date.today().year
day = date.today().day
if monthstring == "01" or "03" or "05" or "07" or "08" or "10" or "12":
if daystring > "31":
print("Invalid Date Entered")
if monthstring == "04" or "06" or "09" or "11":
if daystring > "30":
print("Invalid Date Entered")
months = ["Jan", "Feb", "Mar", "Apr", "May", "June",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
daysinmonth = [31, 29, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31]
if future < today or monthstring > "12":
print("Invalid Date Entered")
else:
layout = "%d/%m/%Y"
a = datetime.strptime(future, layout)
b = datetime.strptime(today, layout)
delta = a - b
print ("The difference between the inputted date and todays date is: ",delta.days, "days")
This code is to ask the user to input a date in the future and then the code should use that input and subtract the current date from it.
For example, today is 01/11/2014 and if the user inputs 03/11/2014 the output should be that the difference is 2 days.
However, I'm getting an error every time I input the future date.
import dateutil.parser as parser
import datetime
date1 = parser.parse(input("Enter Date:"))
print( (datetime.datetime.now() - date1).days )
dateutil is very good at parsing natural date strings ...
you will probably need to install dateutil
easy_install python-dateutil
if you want to not use dateutil as mentioned you can use strptime
def get_user_date(prompt="Enter Date:"):
while True:
try:
return datetime.datetime.strptime("%m/%d/%y",input(prompt))
except ValueError:
print( "Invalid Input!" )
this code I think will work in python 3
There are different things to be considered. Try to take in considerations these points
Check if the user is entering right datetime. You can use regular expression to do that. You can use RE module.
mat=re.match('(\d{2})[/](\d{2})[/](\d{4})$', str(future))
You should filter values between 1-12 for months, and between 1-31 for days. Then distinguish between months, and don't forget February in both cases (leap year or no). You can use calender module to check that.
t= calendar.monthrange(int(yearstring), 2) # This is to check if February has 29 or 28 (is leap year or no), you can do that by checking the day number of "datetime.date (int(yearstring), 3, 1) - datetime.timedelta (days = 1)"
Then, compare between two dates, you should use right time format for every date.
a = date.datetime.strptime(future, "%d/%m/%Y").date()
b = date.datetime.strptime(today, "%Y-%m-%d").date()
delta = a-b
Your code would look like:
import datetime as date
import re
import calendar
future = input("Enter a date(dd/mm/yyyy): ")
#eg: future="02/03/2015"
#print future
mat=re.match('(\d{2})[/](\d{2})[/](\d{4})$', str(future))
if mat is None:
print("Invalid Date Entered, try to enter a date in this form(dd/mm/yyyy) ")
else:
daystring,monthstring,yearstring= mat.groups()
today= str(date.datetime.now()).split(" ")[0]
year, month, day = today.split("-")
months = ["Jan", "Feb", "Mar", "Apr", "May", "June","Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
daysinmonth = [31, 29, 31, 30, 31, 30, 31, 31, 30,31, 30, 31]
if int(daystring)>0 and int(daystring)<=31 and int(monthstring)>0 and int(monthstring) <= 12 and int(yearstring)>0:
if monthstring in ["01", "03", "05" ,"07","08","10", "12"]:
if int(daystring) > 31:
print("Invalid Date Entered - Number of days can't exceed 31.")
if monthstring in ["04","06","09","11"]:
if int(daystring) > 30:
print("Invalid Date Entered - Number of days can't exceed 31.")
if monthstring == "02":
t= calendar.monthrange(int(yearstring), 2) # This is to check if February has 29 or 28 (is leap year or no), you can do that by checking the day number of "datetime.date (int(yearstring), 3, 1) - datetime.timedelta (days = 1)"
if int(daystring) !=t: #You forget faberuary
print("Invalid Date Entered - of days can't exceed 28 or 29")
a = date.datetime.strptime(future, "%d/%m/%Y").date()
b = date.datetime.strptime(today, "%Y-%m-%d").date()
delta = a-b # The future - Today ::> to get a positive number
if delta.days >0:
print ("The difference between the inputted date and todays date is: ",delta.days, "days")
else:
print("Date is in the past")
else:
print("Invalid Date Entered")

Categories

Resources