I am doing an assignment for class where we turn military time into standard time and thought I would be clever to have separate functions for getting input and checking the input -- my reasoning being that if the check_input function failed I could keep looping through the get_inputs function until the user entered it in the correct format.
However, when I enter jibberish like "jklfd" my get_input function crashes because it can't turn it into a list which is part of the function.
Is there a better way to handle exceptions in this case? Also any general tips or advice is always appreciated. Thanks in advance for your help!
__author__ = 'Ethan'
#This program takes input in military time in the format hour:minutes and outputs
#the time in standard time hour:minute AM/PM
def main():
print_intro()
while True:
mil_h, m = get_inputs()
if check_input(mil_h,m):
break
reformat_time(mil_h,m)
def print_intro():
print("This program takes input as military time from user")
print("in format hour:minute ex. 23:34")
print("and outputs the time in standard AM/PM format")
print("ex. from above 11:34 PM")
def get_inputs():
raw = input("Enter time: ")
time_list = raw.split(":")
mil_h = int(time_list[0])
m = int(time_list[1])
return mil_h, m
def check_input(mil_h,m):
try:
if mil_h >= 24 or mil_h <0:
print("Time must be in format hh:mm")
print("Hour must be in range 0 to 23")
return False
elif m >= 60 or m <0:
print("Time must be in format hh:mm")
print("Minute must be in range 0 to 59")
return False
else:
return True
except:
print("Input must be in military time in format hh:mm")
def reformat_time(mil_h,m):
am_pm = "AM"
if mil_h == 12:
am_pm = "PM"
stand_h = 12
elif mil_h > 12:
am_pm = "PM"
stand_h = mil_h % 12
else:
stand_h = mil_h
print(stand_h,':', m,' ', am_pm, sep='')
main()
Before splitting the string use an if statement,
if(raw.contains(":")&& raw.length()>=3 && raw) {
list=raw.split(":")
//rest of code
} else { throw exception}
The code for the exception should be edited to look like this:
except:
println("Code must be in military format")
get_inputs()
//recall the check_input method for the values found in get_inputs
check_input()
This way you know that raw is in the right format, you may want to add more prerequisites for raw (like making sure it only contains numbers), so that the program won't crash with unwanted input. (Sorry for the syntax, I don't know python explicitly)
Related
# making a basic calendar
#list of months and their days
month_day = [[1,'January',31],[2,'February',28],
[3,'March',31],[4,'April',30],
[5,'May',31],[6,'June',30],
[7,'July',31],[8,'August',31],
[9,'September',30],[10,'October',31],
[11,'November',30],[12,'December',31]]
#checksum for new year
def isleapyear(year):
if year%4 == 0:
if year%100 == 0:
if year%400 == 0:
month_day[1][2] = 29
else:
month_day[1][2] = 28
else :
month_day[1][2] = 29
else:
month_day[1][2] = 28
#editable date (supposed to be
def Date():
year = 1
day = 31
month = 1
isleapyear(year)
date = [day, month_day[month-1][1], year]
return date
#function to increase day counter by 1
def new_day():
#checksum for month or year rollover
if Date.day == month_day[Date.month-1][2]:
Date.day = 1
if Date.month == 12:
Date.month = 1
Date.year = Date.year + 1
else:
Date.month = month + 1
else:
Date.day = Date.day + 1
new_day()
print (Date())
I am trying to teach myself python, so I have made a project a few smaller projects working together and one of them is a Date tracker. The Date function works. however when i try to call the new day function to bump the day by 1 and change month and year if needed, i get an error "AttributeError: 'function' object has no attribute 'day'". I understand that inside a function is a separate local variable not a global and that your not supposed to make global variables constantly changing. So I'm trying to get one function to call and use anothers variable I plan on making it into a button that changes the day by 1 or 7, I'm just having trouble visualizing how to get the function working. Any direction or help with getting this to work would be greatly appreciated
Thank you all in advance!
Firstly, you can't get variables from function.
One way you can deal with it is in function Date add line global year, day, month, this will make variables year, day, month global so you can use it in all function and outside of functions. And in new_day remove Date..
This should get rid of your problem.
Date.day would only work if Date was class not function.
For example:
class Date:
def __init__(self):
self.year = 1
self.day = 31
self.month = 1
Date().year # Should return 1
Date().day # Should return 31
Date().month # Should return 1
You have to build a dictionary (Or any other container of your choice) which contains multiple True/false type quiz questions.
Every participant/user will attempt 5 rounds and in each round random quiz questions will be displayed to the user/participant.
If the participant answers the quiz question correct, then congratulate him and add the scores.
At the end display the details and score of the participant.
I have tried but I am not getting expected output.
I hope it can be useful for you. There are many other ways to do it but i think in this way you can understand easier what the script is doing.
import requests
import random
import numbers
def get_quiz_questions():
response = requests.get('https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json')
if response.status_code != 200:
return [
["The Mars Rover \"Spirit\" is powered by six small motors the size of \"C\" batteries. It has a top speed of 0.1 mph.", True],
["Burt Reynolds was originally cast to be Han Solo in the first Star Wars film. He dropped out before filming.", True]
]
return response.json()
# Get questions
quiz_questions = get_quiz_questions()
# Get numeric value, retry if it's not valid.
def get_numeric_value(message):
print(message)
value = input()
if not(value and value.isnumeric()):
print('Entered value is not valid\n')
# using recursion to prompt again for a valid value
return get_numeric_value(message)
return int(value)
def request_boolean_answer():
print('Enter answer: [ 0: false | 1: true]')
answer = input()
# Check if the value entered is numeric and if it's not 1 or 0
if answer.isnumeric() and ( 0 != int(answer) != 1):
print('Entered answer is not valid\n')
# using recursion
return request_boolean_answer()
return bool(answer)
# Start Game
num_players = get_numeric_value('\nEnter number of players: ')
num_questions = get_numeric_value('\nEnter number of questions: ')
score = {}
for player in range(num_players):
print("\nPlayer #:", player )
# initialize score for current user
score[f'player_{player}'] = 0
for question in range(num_questions):
question, answer = random.choice(quiz_questions)
print(question)
user_answer = request_boolean_answer()
print(f'Your answer: {user_answer}, correct answer: {answer}\n')
# Add a point if the answer is correct
if answer == user_answer:
score[f'player_{player}']+=1
print(f'\nScore: {score}')
Probably a very stupid Q! Too much office has damaged my brain today.
I am stuck at solving a basic problem from a site.
I have a function that has 3 values in tuple (name, age, gender). I have worked on getting just age & gender in a list & then iterating there to get average if the gender matches M or F and No match if anything apart from it.
Now I am stuck in the problem in BOLD in the code where I am unable to return either one of the output i.e. if gender = "m' or 'f' it works properly, but if it uses avergae_age(members,Z), it doesnt return ' No matches found' instead error, which is obvious.
How do I make this code better?
b) How do I just get the output if anything apart form M/F is input without changing my existing code pls ?
Thanks in advance
def average_age(members,gender):
lst=[]
for x in zip(members):
lst.append(x[0][1])
lst.append(x[0][2])
lst_tuple = [x for x in zip(*[iter(lst)]*2)]
#return lst_tuple
**lst1=[]
for z in lst_tuple:
if z[1]!=gender:
lst1=[]
return ("No matches found.")
for z in lst_tuple:
if z[1]==gender:
lst1.append(z[0])
return (sum(lst1)/len(lst1))**
For input data:
members = [("Maria", 20, "F"), ("Dan", 21, "M"), ("Ana", 30, "F"), ("Max", 40, "M")]
You can compute average age like this:
def average_age(members: list, gender: str):
# Collect ages for the given gender
ages = [member[1] for member in members if member[2] == gender]
try:
return sum(ages) / len(ages)
except ZeroDivisionError:
print("Unable to compute average age")
Using a Tkinter input box, I ask a user for a date in the format YYYYMMDD.
I would like to check if the date has been entered in the correct format , otherwise raise an error box. The following function checks for an integer but just need some help on the next step i.e the date format.
def retrieve_inputBoxes():
startdate = self.e1.get() # gets the startdate value from input box
enddate = self.e2.get() # gets the enddate value from input box
if startdate.isdigit() and enddate.isdigit():
pass
else:
tkinter.messagebox.showerror('Error Message', 'Integer Please!')
return
The easiest way would probably be to employ regex. However, YYYYMMDD is apparently an uncommon format and the regex I found was complicated. Here's an example of a regex for matching the format YYYY-MM-DD:
import re
text = input('Input a date (YYYY-MM-DD): ')
pattern = r'(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])'
match = re.search(pattern, text)
if match:
print(match.group())
else:
print('Wrong format')
This regex will work for the twentieth and twentyfirst centuries and will not care how many days are in each month, just that the maximum is 31.
Probably you've already solved this, but if anyone is facing the same issue you can also convert the data retrieved from the entry widgets to datetime format using the strptime method, and using a try statement to catch exceptions, like:
from datetime import *
def retrieve_inputBoxes():
try:
startdate = datetime.strptime(self.e1.get(), '%Y-%m-%d')
enddate = datetime.strptime(self.e2.get(), '%Y-%m-%d')
except:
print('Wrong datetime format, must be YYYY-MM-DD')
else:
print('startdate: {}, enddate: {}').format(startdate, enddate)
Note that the output string that will result will be something like YYYY-MM-DD HH:MM:SS.ssssss which you can truncate as follows the get only the date:
startdate = str(startdate)[0:10] #This truncates the string to the first 10 digits
enddate = str(enddate)[0:10]
In my opinion, this method is better than the Regex method since this method also detects if the user tries to input an invalid value like 2019-04-31, or situations in which leap years are involved (i.e. 2019-02-29 = Invalid, 2020-02-29 = Valid).
This is the problem.
Write a program to solve a simple payroll calculation. Find the amount of pay given, hours worked, and hourly rate. (The formula to calculate payroll is pay = hourly rate * hours worked.)
What i have so far
def hours():
hours = input("how many hours did you work?: ")
return hours
def rate():
rate= input("How much is your hourly rate?: ")
def grossPay():
grossPay = hours() * rate()
return grossPay
def main():
print("your gross pay is"), + (grossPay)
return grossPay
def main():
print('Payroll Information')
print hours()
print rate()
main()
There are a few issues with the code...
You have no indentation in your code, which is required for Python (though you may have just pasted it into SO incorrectly)
You call the hours function, but one doesn't exist in your code blurb
Opinion: Seems needlessly complex for a simple operation
There are many ways to do this, but putting it all into one function is most natural to me. I'd do something like this...
def calc_and_show_pay():
rate = input("How much is your hourly rate?: ") #collect the hourly rate
hours = input("How many hours did you work?: ") #collect number of hours worked
gross_pay = float(rate) * float(hours) #Convert string input to floats so we can do math on it
print("Payroll Information:") #print out results, per your format in the example
print("Your pay is %f"%(gross_pay)) #could also do print("your pay is:", gross_pay)
return gross_pay #you don't need to return this unless you want to use this number elsewhere (i.e., you have a bigger program where you'll use this as an input somewhere else).
Then of course you can call "calc_and_show_pay()" as you please.