Next Number with Distinct Digits CCC 2013 Senior 1 - python

The 2013 CCC Senior 1 problem on page 4 is to find the smallest number that is larger than the input with distinct digits as the title explains.
I'm a total beginner at programming and I can't find what's wrong with this code:
year = 1987
distinct = 'no'
a = []
while distinct != 'yes':
year += 1
for i in str(year):
if i not in a:
a.append(i)
distinct = "yes"
else:
distinct = "no"
break
print(year)
I think the code is still in the while loop but I don't understand why. The code above is supposed to print 2013. Thank you for your help.

Your approach to increment the year by 1 and check if the digits are distinct is correct, and your code is almost correct. Your mistake is that you initialize a[], your set of digits in the year, only once, but it should be initialized to empty for each year. Move the line a = [] to after the line year += 1 and give it the proper indentation and your code will work. That would make your code into:
year = 1987
distinct = 'no'
while distinct != 'yes':
year += 1
a = []
for i in str(year):
if i not in a:
a.append(i)
distinct = "yes"
else:
distinct = "no"
break
print(year)
Another approach is to use a set, which automatically removes any duplicates. You can check if making the string of the year into a set changes its size. So perhaps use this, which also avoids using a status variable like distinct:
year = 1987
year += 1
while len(set(str(year))) != len(str(year)):
year += 1
print(year)
If you want that status variable, or do not like that repeated line year += 1, you could do this:
year = 1987
distinct = False
while not distinct:
year += 1
if len(set(str(year))) == len(str(year)):
distinct = True
print(year)

Related

python check user input is day of the week

I am attempting to define a function that asks the user which days of the week they are available. I need their input to be saved into a list for future use. I want to ensure they are entering the day of the week properly and that it is in the correct format. I have tried various ways but cannot seem to get it to work correctly.
Here is what I have so far:
daysWeek = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
def daysInput(message):
print(daysWeek)
z = False
while z == False:
i = list(input(message).strip().title().replace(",", " ").split(" "))
print(i)
varify = 0
for day in i:
for dow in daysWeek:
if day == dow:
varify += 1
else:
varify = 0
if varify == 0:
print("Invalid entry")
else:
z = True
return i
When varify += 1 is executed, and a next iteration executes, varify is set back to 0 even though the input day had matched with a correct day in the previous iteration. That means that unless you enter only the last day (Sun), the input will be rejected.
Secondly, if a day is found, and the next day from the input is checked, you'll destroy the previous result, by clearing varify again, even though a match will be found in a next iteration.
You need to implement the logic that for all inputs, some day of the week should match with it. You can do this a lot easier with the all function and the in operator:
daysWeek = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
def daysInput(message):
print(daysWeek)
while True:
inp = list(input(message).strip().title().replace(",", " ").split(" "))
print(inp)
if all(day in daysWeek for day in inp):
return inp
print("Invalid entry")
daysInput("Enter some days of the week: ")

Implement a condition into a array

I'm trying to implement another condition into my program but can't seem to figure it out.
Here is the code:
print ("Welcome to the winning card program.")
year_one=[]
year_one.append(eval(input("Enter the salary individual 1 got in year 1: ")))
year_one.append(eval(input("Enter the salary individual 2 got in year 1: ")))
if year_one[0]==year_one[1]:
print("Error. The amount are the same, please reenter information.")
year_two=[]
year_two.append(eval(input("Enter the salary individual 1 got in year 2: ")))
year_two.append(eval(input("Enter the salary individual 2 got in year 2: ")))
if year_two[0]==year_two[1]:
print("Error. The amount are the same, please reenter information.")
year_three=[]
year_three.append(eval(input("Enter the salary individual 1 got in year 3: ")))
year_three.append(eval(input("Enter the salary individual 2 got in year 3: ")))
if year_three[0]==year_three[1]:
print("Error. The amount are the same, please reenter information.")
year_four=[]
year_four.append(eval(input("Enter the salary individual 1 got in year 4: ")))
year_four.append(eval(input("Enter the salary individual 2 got in year 4: ")))
if year_four[0]==year_four[1]:
print("Error. The amount are the same, please reenter information.")
year_five=[]
year_five.append(eval(input("Enter the salary individual 1 got in year 4: ")))
year_five.append(eval(input("Enter the salary individual 2 got in year 4: ")))
if year_five[0]==year_five[1]:
print("Error. The amount are the same, please reenter information.")
individual1_total=year_one[0]+year_two[0]+year_three[0]+year_four[0]+year_five[0]
individual2_total=year_one[1]+year_two[1]+year_three[1]+year_four[1]+year_five[1]
if (individual1_total>individual2_total):
print("Individual one has the highest salary.")
elif (individual2_total>individual1_total):
print("Individual two has the highest salary.")
If the salary for the two individuals for a particular year is exactly the same, you should print an error and make the user enter both the salaries again for that year. (The condition is the salaries should not be the exact same).
I look forward to everyone's feedback.
Thank you in advance.
Ok so building on surge10 here is a more complete replacement of your code. I broke all the pieces down into functions, and made a dictionary as my in in-memory database.
total_years = 5
years = {}
def dict_key(year, userId):
return '{}:{}'.format(year, userId)
def get_user_data(year, userId):
key = dict_key(year, userId)
years[key] = float(input("Enter the salary individual {} got in year {}:".format(userId, year)))
def get_year_salaray(year, userId):
key = dict_key(year, userId)
return years[key]
def any_salaries_match(year, userIds):
for userLeft in userIds:
salary_left = get_year_salaray(year, userLeft)
for userRight in userIds:
if userLeft != userRight:
salary_right = get_year_salaray(year, userRight)
if salary_left == salary_right:
return True
def get_user_totals(userId):
total = 0
for key, value in years.items():
if ':{}'.format(userId) in key:
total += value
return total
for x in range(total_years):
year = x + 1
data_invalid = True
while data_invalid:
userOne = 1
userTwo = 2
get_user_data(year, userOne)
get_user_data(year, userTwo)
if any_salaries_match(year, [userOne, userTwo]):
print("Error. The amount are the same, please reenter information.")
else:
data_invalid = False
userOneTotal = get_user_totals(1)
userTwoTotal = get_user_totals(2)
if (userOneTotal>userTwoTotal):
print("Individual one has the highest salary.")
elif (userTwoTotal>userOneTotal):
print("Individual two has the highest salary.")
Since we were checking for five different years I used a loop for those five years
Later we can get it back into individual years.
print ("Welcome to the winning card program.")
years=[]
for x in range(5):
# range starts at zero so add one all the time
# to start it at one
y = str(x + 1)
errors = True
while errors:
salary_one = input("Enter the salary individual 1 got in year " + y + ": ")
salary_two = input("Enter the salary individual 2 got in year " + y + ": ")
if salary_one == salary_two:
print("Error. The amount are the same, please reenter information.")
errors = True
else:
years.append([salary_one, salary_two])
errors = False
year_one = years[0]
year_two = years[1]
...
print(year_one)
print(year_two)
...

dictionary problem in python with index error

I am writing the program to get two dictionaries, dict1 with names as keys and the number of wins as values, dict 2 with years as keys and the number of times won as values. My question is when I try to get the current year inside the for loop which need for the dict 1, it's always giving me and "index error: list index out of range"
and the problem is here as it shows "year_team[year]=winners[year-1903]".
def main():
dfile=open('worldserieswinners.txt','r')
winners=dfile.read().splitlines()
team_wins={}
year_team={}
for team in winners:
if team not in team_wins:
team_wins[team]=1
else:
team_wins[team]+=1
for year in range(1903, 2010):
if year != 1904 and year != 1994:
year_team[year]=winners[year-1903]
year=int(input('Enter a year between 1903 and 2009 or 0 to quit: '))
while year!= 0:
if year == 1904 or year == 1994:
print('Not played in this year')
elif 1903>year or year>2009:
print('Invalid choice')
else:
team=year_team[year]
wins=team_wins[team]
print('The winning team in',year,'was the',team)
print('The',team,'won',wins,'times between 1903 and 2009.')
year= int(input('Enter a year between 1903 and 2009 or 0 to quit: '))
dfile.close()
main()
Presumably your 'worldserieswinners.txt' file has less than 107 (2010 − 1903) lines, so that the index year-1903 gets out of range.

Python declare winner using dictionary and loop

This is the output of the code I am trying to write. I have seen this done for C++, but not python with a dictionary. The key here is the dictionary is not optional. I need to use it to fulfill the assignment.
ID Candidate Votes Received % of Total Vote
1 Johnson 5000 55.55
2 Miller 4000 44.44
Total 9000
and the winner is Johnson!
I need to use a dictionary and a loop to create this. However, I am stuck on 3 points.
1.The percent- current code returns the percent before it has the whole total ex: first candidate always has 100%.
2. Declare a winner- code finds the max votes and returns the number value but I need it to return the name.
3. How to format the dictionary values so it lines up under the header. I don't think is possible, but it must be a requirement to use a dictionary for a reason. I am thinking I need to make a copy of the dictionary and format that?
Here is what I have so far:
totalVotes=[]
dct = {}
i = 1
while(True):
name = input('Please enter a name: ')
if name == '':
break
votes = input('Please enter vote total for canidate: ')
totalVotes.append(votes)
totalVotesInt= map(int, totalVotes)
total = sum(totalVotesInt)
dct[i] = {name,votes,int(votes)/total*100}
i += 1
header='{:>0}{:>10}{:>10}{:>20}'.format('ID','Name','Votes','% of Total Vote')
print(header)
print("\n".join("{}\t{}".format(key, value) for key, value in dct.items()))
print('Total '+str(total))
print('The Winner of the Election is '+max(totalVotes))
Which returns:
Please enter a name: Smith
Please enter vote total for canidate: 100
Please enter a name: Frieda
Please enter vote total for canidate: 200
Please enter a name: West
Please enter vote total for canidate: 10
Please enter a name:
ID Name Votes % of Total Vote
1 {'Smith', '100', 100.0}
2 {'Frieda', 66.66666666666666, '200'}
3 {3.225806451612903, '10', 'West'}
Total 310
The Winner of the Election is 200
You add the number of each candidates votes at the same time you calculate the percent vote for each candidate. You need to find the total votes first, then divide each candidates votes by the total
You are returning the max of a list of integers. Obviously you aren't going to get a string. You need some way to connect the number votes with the candidate.
Don't bother. You can try to figure out how many tabs you need to get the whole thing lined up, but from experience, it is basically impossible. You could separate them with commas and open it in excel as a csv, or you could just make the user figure out what number goes with what.
The other answer uses data tables, so I will take another, more vanilla and cool approach to getting what you want.
class candidate():
def __init__(self, name, votes):
self.name = name
self.votes = int(votes)
def percentvotes(self, total):
self.percent = self.votes/total
def printself(self, i):
print('{}\t{}\t\t{}\t\t{}'.format(i, self.name, self.votes, self.percent))
def getinput():
inp = input('Please enter your candidates name and votes')
return inp
candidates = []
inp = getinput()
s = 0
while inp != '':
s+=1
candidates.append(candidate(*inp.split(" ")))
inp = getinput()
for c in candidates:
c.percentvotes(s)
candidates.sort(key = lambda x:-x.percent)
print('ID\tname\t\tvotes\t\tpercentage')
for i, c in enumerate(candidates):
c.printself(i+1)
I have added very little changes to your code to make it work:
I have mentioned the changes as comments in the code.
Edit: It's more efficient to use objects for each candidate if you require scaling in the future.
totalVotes=[]
dct = {}
i = 1
while(True):
name = input('Please enter a name: ')
if name == '':
break
votes = input('Please enter vote total for canidate: ')
totalVotes.append(votes)
totalVotesInt= map(int, totalVotes)
total = sum(totalVotesInt)
# I change it to a list so it's much easier to append to it later
dct[i] = list((name,int(votes)))
i += 1
# I calculate the total percent of votes in the end and append to the candidate
maxVal = 0
for i in range(1, len(dct) + 1):
if dct[i][1] > maxVal:
maxInd = i
dct[i].append(int((dct[i][len(dct[i]) - 1]) / total * 100))
header='{:>0}{:>10}{:>10}{:>20}'.format('ID','Name','Votes','% of Total Vote')
print(dct)
print(header)
print("\n".join("{}\t{}".format(key, value) for key, value in dct.items()))
print('Total '+str(total))
print('The Winner of the Election is '+ dct[maxInd][0]))
I believe that this is the solution you are looking for. Just change the input statements in case you are using Python 2.x. Using Dataframe, the output will be exactly how you wanted.
import pandas as pd
import numpy as np
df = pd.DataFrame(columns=["Candidate", "Votes Received","Percentage of total votes"])
names=list()
votes=list()
while True:
name = str(input("Enter Name of Candidate."))
if name=='':
break
else:
vote = int(input("Enter the number of votes obtained."))
names.append(name)
votes.append(vote)
s=sum(votes)
xx=(votes.index(max(votes)))
myArray = np.array(votes)
percent = myArray/s*100
for i in range(len(names)):
df1 = pd.DataFrame(data=[[names[i],votes[i],percent[i]]],columns=["Candidate", "Votes Received","Percentage of total votes"])
df = pd.concat([df,df1], axis=0)
df.index = range(len(df.index))
print (df)
print ("Total votes = ",s)
print ("The man who won is ",names[xx])

Returning multiple values from a Python function

How do I pass the return statement from calculateTuitionIncrease into an array and then use that array when calculating the total cost?
Here's my code:
import math
def calculateTuitionIncrease(cost, increase, years):
#This function calculates the projected tuition increase for each year.
counter = 0
while counter <= years:
increasedCost = (cost)+(cost*increase)
return increasedCost
def calculateTotalCost(terms,tuition,creditHours,books,roomAndBoard,scholarships):
#This function will calculate the total cost of all your expenses.
totalBookCost = (books*terms)
totalTuitionCost = (tuition*creditHours)*(terms)
totalRoomAndBoard =(roomAndBoard*terms)
totalCost = (totalBookCost+totalTuitionCost+totalRoomAndBoard)-(scholarships)
return totalCost
def main():
#Variable declaration/initialization
years = 0
terms = 0
numberOfSchools = 0
tuitionCost1 = 0
tuitionCost2 = 0
tuitionCost3 = 0
tuitionCost = 0
bookCost = 0
roomAndBoard = 0
scholarships = 0
tuitionIncrease = 0
increasedCost = 0
creditHours = 0
overallCost = 0
#User inputs
years = int(input("Will you be going to school for 2, 4 or 6 years?"))
#If-statements for if user will be going to multiple schools.
if years == 4 or years == 6:
numberOfSchools = int(input("How many schools do you plan on attending during this time?"))
if numberOfSchools == 2:
tuitionCost1 = int(input("How much will you be paying per credit hour at the first school you'll be attending?"))
tuitionCost2 = int(input("How much will you be paying per credit hour at the second school you'll be attending?"))
tuitionCost = (tuitionCost1+tuitionCost2)/(2) #Finds average tuition between schools & assigns it to a variable
elif numberOfSchools == 3:
tuitionCost1 = int(input("How much will you be paying per credit hour at the first school you'll be attending?"))
tuitionCost2 = int(input("How much will you be paying per credit hour at the second school you'll be attending?"))
tuitionCost3 = int(input("How much will you be paying per credit hour at the third school you'll be attending?"))
tuitionCost = (tuitionCost1+tuitionCost2+tuitionCost3)/(3) #Finds average tuition cost between schools & assigns it to a variable
else:
tuitionCost = int(input("Please enter how much you will be paying per credit hour."))
terms = (years*2)
tuitionIncrease = float(input("Please enter the projected tuition increase per year in percentage form (ex. if increase is 7% enter .07)."))
creditHours = int(input("On average, how many credit hours will you be receiving per term?"))
roomAndBoard = int(input("Please enter what your price of room and board will be per term."))
bookCost = int(input("Please enter what your average book cost will be per term."))
scholarships = int(input("Please enter the total amount you will be recieving from grants and scholarships."))
#Calls function that calculates tuition increase per year
increasedCost = calculateTuitionIncrease(tuitionCost,tuitionIncrease,years)
#Calls function that calculates the total cost.
overallCost = calculateTotalCost(terms,tuitionCost,creditHours,bookCost,roomAndBoard,scholarships)
print ("Your total estimated college cost is", overallCost)
main()
For starters, it looks like calculateTuitionIncrease should be returning a list, because currently it's returning a single value and the loop is wrong (it's not advancing at all):
def calculateTuitionIncrease(cost, increase, years):
# This function calculates the projected tuition increase for each year.
counter = 0
answer = []
while counter <= years:
increasedCost = (cost)+(cost*increase)
answer.append(increasedCost)
counter += 1
return answer
As for the second part of the question, it's not clear how you're supposed to "use that array when calculating the total cost", but surely you must iterate over the list returned by calculateTuitionIncrease and do something with each element, for each year - you should know how to do this, it must be part of the problem description you received.
It looks like you're trying to return multiple values from the calculateTotalCost function. You could try using a tuple, which is like a mini-array that you can create by listing some values inside parentheses.
For instance, in your code you could replace
return totalCost
with
return (totalCost, totalBookCost, totalTuitionCost, totalRoomAndBoard)
The short answer is that you would make an empty list before the loop, and then append new items to it inside of your loop. After the loop you can either return the list or do something else with the list.
def calculateTuitionIncrease(cost, increase, years):
#This function calculates the projected tuition increase for each year.
counter = 0
# make an empty list
# before you start the loop
costsPerYear = []
# you should use 'less than' here (or start the counter at 1)
while counter < years:
increasedCost = (cost)+(cost*increase)
# append this cost to the end of the list
costPerYear.append(increasedCost)
# add one to the counter
counter = counter + 1
# once the loop is over, return the list
return costsPerYear
Then you could sum this quantity:
adjustedTuitions = calculateTuitionIncrease(cost, increase, years)
totalTuitionCost = sum(adjustedTuitions)
Alternatively, you can return the sum of those estimates
and use a for loop in place of the while loop.
def calculateTuitionIncrease(cost, increase, years):
#This function calculates the projected tuition increase for each year.
# make an empty list
# before you start the loop
costsPerYear = []
for year in range(years):
increasedCost = (cost)+(cost*increase)
# append this cost to the end of the list
costPerYear.append(increasedCost)
# return the sum of those costs
return sum(costsPerYear)
and use it like this:
totalTuitionCost = calculateTuitionIncrease(cost, increase, years)
Here's a tutorial on for loops and lists.
Also, you don't need to import the math module, because you're not using any of its special math functions.
You can use yield instead of return and use that function as iterator. So that's the example:
def calculateTuitionIncrease(cost, increase, years):
#This function calculates the projected tuition increase for each year.
counter = 0
while counter <= years:
counter += 1
yield (cost)+(cost*increase)
print(sum(calculateTuitionIncrease(1000, 10, 5))) # -> 66000
# the same but long way
sum = 0
for i in calculateTuitionIncrease(1000, 10, 5):
sum += i
print(sum) # -> 66000

Categories

Resources