Why getting invalid literal when running this script? - python

When I run the following script, I get ValueError: invalid literal for int() with base 10: '2-' when the date only contains 1 digit (ie 02-02-2011). However it works fine when the date has 2 digits (ie 11-11-2011). What is the reason for this, and how can I fix it?
from __future__ import division
from easygui import *
import ystockquote
import datetime
import math
def main():
stock = 'NFLX'
name = ystockquote.get_company_name(stock)
start_date = create_date(02,13,2009)
end_date = create_date(10,21,2014)
start_price = get_price_on_date(stock,start_date)
end_price = get_price_on_date(stock,end_date)
if not isinstance(start_price,str):
print "Please enter a different start date, the market was closed on the day you chose!"
quit()
else:
start_price = float(start_price)
if not isinstance(end_price,str):
print "Please enter a different end date, the market was closed on the day you chose!"
quit()
else:
end_price = float(end_price)
no_of_shares = math.floor(10000/float(start_price))
profit = (end_price-start_price)*no_of_shares
print "The profit resulting from investing $10,000 in " + name + " from " + start_date + " to " + end_date + " would have been " + "$" + str(profit) + " or a return of {:.2%}".format(profit/10000) + " ."
def get_price_on_date(stock,date):
a = ystockquote.get_historical_prices(stock,date,date)
for key, value in a.iteritems() :
for key, value in value.iteritems() :
if key == 'Close':
return value
def create_date(month,day,year):
date_string = str(year) + "-" + str(month) + "-" + str(day)
return date_string
if __name__ == '__main__':
main()

Your create_date() function is not returning two-digit day and month numbers in all cases.
Try formatting the values explicitly instead of using str():
date_string = "{0:04}-{1:02}-{2:02}".format(year, month, day)

Related

Finding weekday with specific date

I am learning python and going through some interactive exercises. Specifically, I'm working on Friday the 13th.
I have rewritten several iterations of this but can never seem to lock it down. With this version, it seems to get hung up when run with the simulated start date of 2025-06-12 which means there's a problem with the "this month" section. Since it returns an accurate Friday the 13th except not 2025-06-13, I suspect it's a problem with the elif statement, particularly the
and date.fromisoformat(current_year + '-' + current_month + '-13').weekday == 4:
Here's the most recent iteration of this.
def friday_the_13th():
from datetime import date
current_year = str(date.today().year)
current_month = str(date.today().month)
if len(current_month) == 1: current_month = '0' + current_month
#Function to increment to the 13th of next month
def NextMonth13(startdate):
lst_date = str(startdate)
lst_date = lst_date.split('-')
month = int(lst_date[1])
if month == 12:
year = str(int(lst_date[0]) + 1)
month = '01'
return str(year + '-' + month + '-' + '13')
else:
year = lst_date[0]
month = str(month + 1)
if len(month) == 1: month = '0' + month
return str(year + '-' + month + '-' + '13')
# Return today if today is Friday the 13th
if date.today().weekday() == 4 and date.today().day == 13:
return date.today()
# Check if this month's 13th is in the future and if it's a Friday
elif date.today().day < 13 and date.fromisoformat(current_year + '-' + current_month + '-13').weekday == 4:
return str(date.fromisoformat(current_year + '-' + current_month + '-13'))
#Check next month and return result if Friday 13
else:
result = NextMonth13(date.today())
while not (date.fromisoformat(result).weekday() == 4):
result = NextMonth13(result)
if date.fromisoformat(result).weekday() == 4:
return result
Would someone mind giving me some guidance on what I might be doing wrong?
First, your error is that you forgot the parenthesis after the weekday method call: date.fromisoformat(current_year + '-' + current_month + '-13').weekday() == 4 (FYI, date.fromisoformat(current_year + '-' + current_month + '-13').weekday returns the memory address of the method, something like this <built-in method weekday of datetime.date object at 0x7fa4e36058f0>. As you can see, it is nowhere near the result you were expecting, so it was normal for your program to behave this way.)
Second, you are needlessly complicating yourself by doing str conversions all the time:
def friday_the_13th():
from datetime import datetime, timedelta
days_passed = 0
today = datetime.today()
while True:
curr = today + timedelta(days=days_passed)
if curr.day == 13 and datetime.weekday(curr) == 4:
return str(datetime.date(curr))
days += 1
This is more readable and less prone to error as you only convert to string at the end, after you've handled all your calculations.
Not sure if it helps but to calculate the future Friday 13th you can do something like:
import datetime
def get_13th_future(startdate, months):
result=[]
year=startdate.year
month=startdate.month
checkdate = datetime.date(year=year, month=month, day=13)
for i in range(month):
if checkdate.weekday()==4:
result.append(checkdate.isoformat())
month+=1
if month==13:
year+=1
month=1
checkdate=datetime.date(year=year,month=month,day=13)
return result
startdate=datetime.datetime.now()
print(get_13th_future(startdate,1000))
If you like to search for a specific date you might construct a set instead of the list.

Python unittest, datetime

My problem is:
In my following test, everything is working today but not will work tomorrow, I'm a beginner and did try a lot of options, but I failed, I,m trying pass "now" as a parameter but with no success until now.
I have to stop the "datetime.now()" and put one fixed date to can test all variations.
I had god progress until here, but I'm stuck on this
Can you help me, please?
Thank you.
Flavio
import unittest
from datetime import datetime
def get_last_name_and_birthday(name, d):
x = name.split()
dob = d.split("-")
year, month, day = int(dob[2]), int(dob[1]), int(dob[0])
user_birthday = datetime(year, month, day)
return x[-1], user_birthday
def calc_days(user_birthday):
now = datetime.now()
if user_birthday < now:
birthday = datetime(now.year + 1, user_birthday.month, user_birthday.day)
return (birthday - now).days + 1
else:
birthday = datetime(now.year, user_birthday.month, user_birthday.day)
return (birthday - now).days + 1
def generate_output(last_name, cd):
if cd == 365:
return "Hello Mr " + last_name + " Happy Birthday"
elif cd < 365:
return "Hello Mr " + last_name + " your birthday is in " + str(cd) + " days"
else:
return "Hello Mr " + last_name + " your birthday is in " + str(cd - 365) + " days"
def process_name_and_birthday(name, dob):
last_name, user_birthday = get_last_name_and_birthday(name, dob)
cd = calc_days(user_birthday)
return generate_output(last_name, cd)
#name = input("type your full name: ")
#dob = input("type your date of birthday(dd-mm-yy): ")
#print(process_name_and_birthday(name, dob))
class BirthdayTest(unittest.TestCase):
def test_same_day_birthday(self):
self.assertEqual("Hello Mr Oliveira Happy Birthday", process_name_and_birthday("Flavio Oliveira", "11-06-1990"))
class DaysToBirthdayTest(unittest.TestCase):
def test_days_to_birthday(self):
self.assertEqual("Hello Mr Oliveira your birthday is in 9 days", process_name_and_birthday("Flavio Oliveira", "20-06-1978"))
class DaysToPassedBirthdayTest(unittest.TestCase):
def test_how_many_days_passed_birthday(self):
self.assertEqual("Hello Mr Oliveira your birthday is in 364 days", process_name_and_birthday("Flavio Oliveira", "10-06-1978"))
unittest.main()
Add the following three lines under your import of datetime:
from unittest.mock import Mock
datetime = Mock(wraps=datetime)
datetime.now.return_value = datetime(2020, 6, 11, 20)
There is more information about the mock module here: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock

Need help to make while loop restart my Python program from top

I would like to get help with this program I have made. The function of the code is so the users can input a city anywhere in the world and they will then get data about the weather for that city.
I want it to restart the program from the top, but it only restarts the program from where the results are.
# - Weather Program -
#Import
import datetime
import requests
import sys
#Input
name_of_user = input("What is your name?: ")
city = input('City Name: ')
#API
api_address='http://api.openweathermap.org/data/2.5/weather?appid=<app_id_token>&q='
url = api_address + city
json_data = requests.get(url).json()
#Variables
format_add = json_data['main']['temp']
day_of_month = str(datetime.date.today().strftime("%d "))
month = datetime.date.today().strftime("%b ")
year = str(datetime.date.today().strftime("%Y "))
time = str(datetime.datetime.now().strftime("%H:%M:%S"))
degrees = format_add - 273.15
humidity = json_data['main']['humidity']
latitude = json_data['coord']['lon']
longitude = json_data['coord']['lat']
#Loop
while True:
#Program
if degrees < 20 and time > str(12.00):
print("\nGood afternoon " + name_of_user + ".")
print("\nThe date today is: " +
day_of_month +
month +
year)
print("The current time is: " + time)
print("The humidity is: " + str(humidity) + '%')
print("Latitude and longitude for " + city + " is: " + str(latitude), str(longitude))
print("The temperature is a mild " + "{:.1f}".format(degrees) +
"°C, you might need a jacket.")
elif degrees < 20 and time < str(12.00):
print("\nGood morning " + name_of_user + ".")
print("\nThe date today is: " +
day_of_month +
month +
year)
print("The current time is: " + time)
print("The humidity is: " + str(humidity) + '%')
print("Latitude and longitude for " + city + " is: " + str(latitude), str(longitude))
print("The temperature is a mild " + "{:.1f}".format(degrees) +
"°C, you might need a jacket.")
elif degrees >= 20 and time > str(12.00):
print("\nGood afternoon " + name_of_user + ".")
print("\nThe date today is: " +
day_of_month +
month +
year)
print("The current time is: " + time)
print("The humidity is: " + str(humidity) + '%')
print("Latitude and longitude for " + city + " is: " + str(latitude), str(longitude))
print("The temperature is a warm " + "{:.1f}".format(degrees) +
"°C, don't forget to drink water.")
elif degrees >= 20 and time < str(12.00):
print("\nGood morning " + name_of_user + ".")
print("\nThe date today is: " +
day_of_month +
month +
year)
print("The current time is: " + time)
print("The humidity is: " + str(humidity) + '%')
print("Latitude and longitude for " + city + " is: " + str(latitude), str(longitude))
print("The temperature is a warm " + "{:.1f}".format(degrees) +
"°C, don't forget to drink water.")
#Loop
restart = input('Would you like to check another city (y/n)?: ')
if restart == 'y':
continue
else:
print('Goodbye')
sys.exit()
So this is what happens.. The loop only loops the question with the input and data already filled in.
What is your name?: Test
City Name: Oslo
Good afternoon Test.
The date today is: 01 May 2019
The current time is: 20:23:36
The humidity is: 76%
Latitude and longitude for Oslo is: 10.74 59.91
The temperature is a mild 12.7°C, you might need a jacket.
Would you like to check another city (y/n)?: y
Good afternoon Test.
The date today is: 01 May 2019
The current time is: 20:23:36
The humidity is: 76%
Latitude and longitude for Oslo is: 10.74 59.91
The temperature is a mild 12.7°C, you might need a jacket.
Would you like to check another city (y/n)?: n
Goodbye
Process finished with exit code 0
I want the code to loop from the top so I can press y so the program will ask me for another city to input.
You are never updating your values. Let's take a simpler example:
x = int(input("What is the number you choose? "))
while True:
if x >3:
print(x)
continue
else:
break
If I run this, I will get x printed out forever if I choose, say 5. The code defining x will never be re-run because it's outside of the loop. To fix this, I can move my code for x into the while loop:
while True:
x = int(input("What number do you choose? "))
if x>3:
print(x)
else:
break
This will run the code for x every time the loop executes, so x can now change. Applying this to your code:
# loop is now up near the top
while True:
# You want these values to change on each iteration of the while
# loop, so they must be contained within the loop
name_of_user = input("What is your name?: ")
city = input('City Name: ')
#API
api_address='http://api.openweathermap.org/data/2.5/weather?appid=<app_id_token>&q='
url = api_address + city
json_data = requests.get(url).json()
#Variables
format_add = json_data['main']['temp']
day_of_month = str(datetime.date.today().strftime("%d "))
month = datetime.date.today().strftime("%b ")
year = str(datetime.date.today().strftime("%Y "))
time = str(datetime.datetime.now().strftime("%H:%M:%S"))
degrees = format_add - 273.15
humidity = json_data['main']['humidity']
latitude = json_data['coord']['lon']
longitude = json_data['coord']['lat']
if degrees... # rest of your statements
Now the value for City can change, and you can apply that to the other data structures as well
Put your while loop starting above the first input. Don't forget to declare your constant variables above the main loop.
The while loop only covers the code that display the results, the code that takes input and request the results is only executed once.
You need to have everything except the import statements within the while loop
All you need to is put the input section and the API sections inside your while true loop.
I will say, I was unable to actually test my solution, but I am almost completely sure that it will work. Good luck!

Python functions and formatting not working

I'm currently having a problem with a function in python. This is my code before I tried putting it in a function:
for i in range(4):
for y in Days:
for x in "ABCDEF":
data = input("What was the punctuality for bus " + x + " on " + str(y) + ", Week " + str(Week) + "? ")
Bus = "Bus" + str(x)
Buses[Bus].append(str(data))
print()
Week += 1
And it works like it is meant to, however I tried putting it in a function:
def InputData():
for i in range(4):
for y in Days:
for x in "ABCDEF":
data = input("What was the punctuality for bus " + x + " on " + str(y) + ", Week " + str(Week) + "? ")
Bus = "Bus" + str(x)
Buses[Bus].append(str(data))
print()
Week += 1
And I am getting errors about the whole Week += 1 part. They say:
[pyflakes] local variable 'Week' (defined in enclosing scope on line 11)
referenced before assignment
[pyflakes] local variable 'Week' is assigned to but never used
Any help would be greatly appreciated.
Week = 0
Put this at the beginning of your code.

Checking the format/contents of a string

This program is intended to ask for the date as dd/mm/yyyy. It should then check to see if the user inputted the date in the correct format (dd/mm/yyyy). My program is not able to recognize the format correctly. This is my program:
date = (input("enter the date as dd/mm/yyyy: "))
date = day, month, year = date.split("/")
if date == (day + '/' + month + '/' + year):
print (date)
if len(day) == 1 or len(day) == 2:
print("1")
if len(month) == 1 or len(month) == 2:
print("2")
if len(year) == 4:
print ("3")
else:
if len(day) == 1 or len(day) == 2:
print("4")
if len(month) == 1 or len(month) == 2:
print("5")
if len(year) == 4:
print ("6")
The numbers being printed currently have no other purpose than to just check the validity of the date. So far, only 4,5, and 6 are being printed, meaning my program is not recognizing the formatting of the date.
Your solution doesn't work because date=day, month, year = date.split("/") sets date to a list, then you're comparing it to a string (day + '/' + month + '/' + year). However, your solution is a solved problem, do instead:
import datetime
date = (input("enter the date as dd/mm/yyyy: "))
try: datetime.datetime.strptime(date,"%d/%m/%Y")
except ValueError: # incorrect format
In addition, you probably are turning this into a datetime object later on anyway, so you can do so in the try block!
As a further optimization, be aware that many users won't WANT to enter their dates using / as a datesep! Do some introspection on your input, and adjust your datesep appropriately.
date = input("enter the date: ")
if "-" in date: datesep = "-"
elif "/" in date: datesep = "/"
elif "." in date: datesep = "."
else: datesep = ""
if len(date) < 6: yeartype = "%y"
elif date[-4:-2] not in ("19","20"): yeartype = "%y"
else: yeartype = "%Y"
try: date = datetime.datetime.strptime(date,"%d{0}%m{0}{1}".format(datesep,yeartype))
except ValueError: # invalid date
Now your code will end up with a valid datetime object of Feb 2nd 2014 for:
02022014
222014
0222014
222014
020214
02214
2214
02-02-2014
02/02/2014
2-2-14
2/2/2014
2/2/14
etc etc etc
You can use the datetime module:
import datetime
def checkdate(date):
try:
datelist = date.split('/')
datetime.datetime(year=int(datelist[2]), month=int(datelist[1]),day=int(datelist[0]))
return True
except:
return False

Categories

Resources