Holiday program error in Python - python

I was asked to make a program that takes the day that I start my travel length of my stay as an input and give the day that I return in as an output so I tried this and I keep getting an error that says (KeyError = -3)
Note: I'm a beginner, so be easy on me :)
dect = {0:'Sunday', 1: 'Monday', 2:'Tuesday',3:'Wednesday', 4:'Thursday',
5:'Friday',6:'Saturday'
}
def day(x):
print( dect[x])
def holiday(start,length):
length = length + start
while True:
if length <= 0:
break
print(length)
else:
length = length - 7
day(length)
s = int(input('Enter the start day: '))
l = int(input('Enter the length of your stay: '))
holiday(s,l)

The value of length can become negative and this is why you're looking up -3 in the dictionary.
For example, if my holiday is 4 days (length = 4) then you're doing length = length - 7 which means you're calling day() with -3 as value.
Your dictionary only has values for the keys 0 - 6 and that's why you're getting a KeyError as the key -3 is not in the dictionary.
You can fix it by changing the check into if length < 7.

What you can do is, simply use datetime module.
from datetime import date,timedelta
d = date.today() + timedelta(days=2)
print d
You can use timedelta to add as many days/hours/whatever you want. See here for the documentation.

Replace your holiday function as -
def holiday(start,length):
length = length + start
length = length % 7
day(length)

Related

KeyError: 20, not sure what is wrong

I am new to python and am currently trying to create a program that will create a list of yearly percentage changes in revenue.
This is what I have so far:
revs = {}
for year in range(14, 20):
revs[year] = float(input("Revenue in {0}: ".format(year)))
revs_change = []
for year in range(14, 20):
next_year = year + 1
revs_change.append((revs[next_year] - revs[year])/revs[year])
print(revs_change[0])
The error comes on the 8th line and it has something to do with using the variable next_year.
Thanks!
If you are going to print out the values of year and next_year the problem is that there is no value for revs[next_year=20].
One way is to do like this-
start = 14
end = 21
for year in range(start, end):
revs[year] = float(input("Revenue in {0}: ".format(year)))
revs_change = []
for year in range(start, end-1):
next_year = year + 1
print(f"Year: {year}, Next Year: {next_year}\n")
revs_change.append( (revs[next_year] - revs[year])/revs[year] )
print(revs_change[0])
In Python, the end limit for any range you give will be taken excluding that upper limit i.e if you set the upper limit as 20, it evaluates up to 19. Give the upper limit as 21 so that you'll get the desired output

Error with user input for standard deviation program

My program is meant to calculate the standard deviation for 5 values given by the users. There is an issue with my code when getting the input in a for loop. Why is that?
givenValues = []
def average(values):
for x in range(0, 6):
total = total + values[x]
if(x==5):
average = total/x
return average
def sqDiff(values):
totalSqDiff = 0
sqDiff = []
av = average(values)
for x in range(0,6):
sqDiff[x] = (values[x] - av)**2
totalSqDiff = totalSqDiff + sqDiff[x]
avSqDiff = totalSqDiff / 5
SqDiffSquared = avSqDiff**2
return SqDiffSquared
for counter in range(0,6):
givenValues[counter] = float(input("Please enter a value: "))
counter = counter + 1
sqDiffSq = sqDiff(givenValues)
print("The standard deviation for the given values is: " + sqDiffSq)
There are several errors in your code.
Which you can easily find out by reading the errormessages your code produces:
in the Function average
insert the line total = 0
you are using it before asigning it.
List appending
Do not use for example
sqDiff[x] = (values[x] - av)**2
You can do this when using dict's but not lists! Since python cannot be sure that the list indices will be continuously assigned use sqDiff.append(...) instead.
Do not concatenate strings with floats. I recommend to read the PEP 0498
(https://www.python.org/dev/peps/pep-0498/) which gives you an idea on how string could/should be formated in python

I cant get my code to work. it keeps saying: IndexError: List index out of range

My code is using the lengths of lists to try and find a percentage of how many scores are over an entered number.It all makes sense but I think some of the code needs some editing because it comes up with that error code.How can I fix it???
Here is the code:
result = [("bob",7),("jeff",2),("harold",3)]
score = [7,2,3]
lower = []
higher = []
index2 = len(score)
indexy = int(index2)
index1 = 0
chosen = int(input("the number of marks you want the percentage to be displayed higher than:"))
for counter in score[indexy]:
if score[index1] >= chosen:
higher.append(score[index1])
else:
lower.append(score[index1])
index1 = index1 + 1
original = indexy
new = len(higher)
decrease = int(original) - int(new)
finished1 = decrease/original
finished = finished1 * 100
finishedlow = original - finished
print(finished,"% of the students got over",chosen,"marks")
print(finishedlow,"% of the students got under",chosen,"marks")
Just notice one thing:
>>>score = [7,2,3]
>>>len(score) = 3
but ,index of list start counting from 0, so
>>>score[3]
IndexError: list index out of range
fix your row 12 to:
...
for counter in score:
if counter >= chosen:
...
if you really want to get the index and use them:
....
for index, number in enumerate(score):
if score[index] >= chosen:
......
Your mistake is in Line 9: for counter in score[indexy]:
counter should iterate through a list not through an int and even that you are referring to a value that is out of index range of your list:
1 - Remember indexing should be from 0 to (len(list)-0).
2 - You cannot iterate through a fixed value of int.
So, you should change Line 9 to :
for counter in score
But I'm not sure of the result you will get from your code, you need to check out your code logic.
There is a lot to optimize in your code.
index2 is an int, so no need to convert it to indexy. Indizes in Python are counted from 0, so the highest index is len(list)-1.
You have a counter, so why use index1 in for-loop? You cannot iterate over a number score[indexy].
results = [("bob",7),("jeff",2),("harold",3)]
chosen = int(input("the number of marks you want the percentage to be displayed higher than:"))
higher = sum(score >= chosen for name, score in results)
finished = higher / len(results)
finishedlow = 1 - finished
print("{0:.0%} of the students got over {1} marks".format(finished, chosen))
print("{0:.0%} of the students got under {1} marks".format(finishedlow, chosen))

python tuple over writing previous data

I am trying to create a function that will start the loop and add a day to current day count, it will ask 3 questions then combine that data to equal Total_Output. I then want 'n' to represent the end of the tuple, and in the next step add the Total_Output to the end of the tuple. But when I run the function it seems like it is creating a new tuple.
Example:
Good Morninghi
This is Day: 1
How much weight did you use?40
How many reps did you do?20
How many sets did you do?6
Day: 1
[4800.0]
This is Day: 2
How much weight did you use?50
How many reps did you do?20
How many sets did you do?6
Day: 2
[6000.0, 6000.0]
This is Day: 3
How much weight did you use?40
How many reps did you do?20
How many sets did you do?6
Day: 3
[4800.0, 4800.0, 4800.0]
failed
Here is the function:
def Start_Work(x):
Num_Days = 0
Total_Output = 0
Wght = 0
Reps = 0
Sets = 0
Day = []
while x == 1 and Num_Days < 6: ##will be doing in cycles of 6 days
Num_Days += 1 ##increase day count with each loop
print "This is Day:",Num_Days
Wght = float(raw_input("How much weight did you use?"))
Reps = float(raw_input("How many reps did you do?"))
Sets = float(raw_input("How many sets did you do?"))
Total_Output = Wght * Reps * Sets
n = Day[:-1] ##go to end of tuple
Day = [Total_Output for n in range(Num_Days)] ##add data (Total_Output to end of tuple
print "Day:",Num_Days
print Day
else:
print "failed"
Input = raw_input("Good Morning")
if Input.lower() == str('hi') or str('start') or str('good morning'):
Start_Work(1)
else:
print "Good Bye"
n = Day[:-1] ##go to end of tuple
Day = [Total_Output for n in range(Num_Days)] ##add data (Total_Output to end of tuple
Does not do what you think it does. You assign n but never use it (the n in the loop is assigned by the for n in), and it only hold a list of the end of the Day variable.
You then set Day to be [Total_Output] * Num_Days, so you make a new list of Num_Days occurrences of Total_Output.
You want:
Day.append(Total_Output)
to replace both of those lines.

Long Count Mayan Date in Python

I need to compile a program that can convert a Gregorian date to a Mayan one. I also need to use 01/01/1970 as a reference date.
The following auxiliary functions work accordingly and have no mistakes.
# turns dates into tuples
def dmj(date):
"""
>>> dmj('01/01/1970')
(1, 1, 1970)
>>> dmj('00012+00012+02012')
(12, 12, 2012)
"""
tup = ()
for i in date:
if i.isdigit() == False and i != ' ':
date = date.replace(i, ' ')
number_str = ''
for i in date:
number_str += i
if i == ' ':
number = int(number_str)
tup += (number,)
number_str = ''
tup += (int(number_str),)
return tup
# counts days that have passed since 01/01/1970
def daysPassed(date):
"""
>>> daysPassed('01/01/1970')
0
>>> daysPassed('20-7-1988')
6775
>>> daysPassed('00012+00012+02012')
15686
"""
from datetime import date
tup = dmj(date)
begin = date(1970, 1, 1)
end = date(tup[2], tup[1], tup[0])
passed = abs(end - begin)
return passed.days
My idea was to first calculate how many days have passed since the beginning of this pictun (20 baktuns long) in 01/01/1970 and then added the days passed since then according to the given date.
In the Mayan calendar a day is refered to as a kin. Their periods (within one pictun) are as follows:
20 kin = 1 uinal; 18 uinal = 1 tun; 20 tun = 1 katun; 20 katun = 1 baktun
In the long count notation the Mayan date for 01/01/1970 is '12.17.16.7.5'. Baktun are written first, then katuns, etc... Mayan dates start from 0. Basically the first kin of a uinal is number zero and the last one number 19, twenty in total.
I've first compiled the following:
def mayanDate(date, separation='')
"""
>>> mayanDate('01/01/1970')
'12/17/16/7/5'
>>> mayaDate('20-7-1988', separator='/')
'12/18/15/4/0'
>>> mayaDate('00012+00012+02012', separator='-')
'12-19-19-17-11'
>>> mayaDate('21 12 2012', separator='+')
'13+0+0+0+0'
>>> mayaDate('26.03.2407')
'14.0.0.0.0'
"""
days = daysPassed(date) + 13 * 144000 + 18 * 7200\
+ 17 * 400 + 8 * 20 + 6
baktun = str((days //((20 **3) * 18)) - 1)
days = days % ((20 **3) * 18)
katun = str((days //((20 **2) * 18)) - 1)
days = days % ((20 **2) * 18)
tun = str((days // (20 **2)) - 1)
days = days % (20 **2)
uinal = str((days // 20) - 1)
days = days % 20 - 1
kin = str(days)
mayanlist = [baktun, katun, tun, uinal, kin]
for i in date:
if i.isdigit() == False and separator == '':
separator = i
break
mayandate = separator.join(mayanlist)
return mayandate
For some strange reason only 01/01/1970 returns the correct Mayan long notation, despite counting from the beginning of an entire pictun (7,900 years in length!). For all other dates it seems to advance too fast through the calendar, despite my second auxiliary function returning the correct values (even for millennia into the future).
I wonder where's the mistake. For instance mayanDate('20-7-1988') returns '12-18-15-6-0' instead of '12-18-15-4-0' and mayanDate('21 12 2012') returns '13 0 1 12 0' instead of '13 0 0 0 0'.
The issue you're seeing with the negative 1 kin for date '15/01/1970' is due to the removal of one from every date ordinal during the calculation. Taking x%20 will always return a value between 0 and 19 inclusive. Taking one from the result necessarily shifts this range to -1 to 18 inclusive.
The number added to the result of daysPassed(date) seems to be a conversion of the long form of 1/1/1970, with one added to each digit. I'm assuming this has been done to counter the fact that the Mayan calendar starts counting at zero, but is unnecessary. The Mayan date 0.0.0.0.1.5 counts 25, not 151646. This doesn't appear to be the source of the error though, since removing this issue from my own code, I still get the same results as described for the 20-7-1988 and 21-12-2012.
I finally rooted out the error when I went back and switched out all the magic numbers in my code for named constants (it makes the code far easier to debug, read and maintain). You state there are 18 uinal in a tun, and 20 tun in a katun, but these numbers are reversed in the code.
Here's my code:
def mayanDate(date_str, seperation=','):
days_in_kin = 1
kin_in_uinal = 20
uinal_in_tun = 18
tun_in_katun = 20
katun_in_baktun = 20
days_in_uinal = days_in_kin * kin_in_uinal
days_in_tun = days_in_uinal * uinal_in_tun
days_in_katun = days_in_tun * tun_in_katun
days_in_baktun = days_in_katun * katun_in_baktun
days_1970 = 12 * days_in_baktun \
+ 17 * days_in_katun\
+ 16 * days_in_tun\
+ 7 * days_in_uinal\
+ 5 * days_in_kin
total_days = daysPassed(date_str) + days_1970
baktun = total_days // days_in_baktun
total_days -= baktun * days_in_baktun
katun = total_days // days_in_katun
total_days -= katun * days_in_katun
tun = total_days // days_in_tun
total_days -= tun * days_in_tun
uinal = total_days // days_in_uinal
total_days -= uinal * days_in_uinal
kin = total_days // days_in_kin
print seperation.join(map(str, (baktun, katun, tun, uinal, kin)))
(I subtracted the previous calculations from total days, rather than using a modulo operator, since I feel it's cleaner. I guess it's a matter of personal preference.)
I may have found something.
>>>mayanDate('15/01/1970')
'12/17/16/8/-1'
Obviously not possible. -1 has to be 19 here and 8 has to be 7. It seems to turn month too early. Still not out why 01/01/1970 remains correct here. No idea what's so special about that date.

Categories