I am new to Python and am having issues getting information to print in a table once 'n' or 'N'is entered. The code is below. I am probably missing something simple but have not been able to figure it out. Any help is appreciated.
Here is the result. As you can see, even after N is printed, it continues to ask for speed input:
Enter the speed in MPH.50
Enter the time travelled in hours.3
Do you have another calculation to enter? (Enter y for yes or N for no: )y
Enter the speed in MPH.60
Enter the time travelled in hours.4
Do you have another calculation to enter? (Enter y for yes or N for no: )y
Enter the speed in MPH.75
Enter the time travelled in hours.3
Do you have another calculation to enter? (Enter y for yes or N for no: )n
Enter the speed in MPH.
' # This program will calculate the distance a vehicle has travelled
# in miles using speed (mph) and the number of hours travelled.
# Create a variable to represent the maxium travel time in hours.
max_travel = 9
min_travel = 1
# Create a variable to represent the maximum speed.
max_speed = 120
# Create a variable to represent the minimum speed.
min_speed = 1
#Define a variable to represent continuation of the program
another = ["y", "Y"]
# Create a variable for saved results to be printed in table
results = []
# main module
def main():
# Get the speed in MPH.
speed = int(input('Enter the speed in MPH.'))
# Validate that the speed entered is not out of range.
while speed > max_speed or speed < min_speed:
if speed > max_speed:
print('ERROR: the speed entered must be a lower number between 1 and 120.')
speed = int(input('Enter a lower speed in MPH.'))
if speed < min_speed:
print('ERROR: the speed entered must be a higher number between 1 and 120.')
speed = int(input('Enter a higher speed in MPH.'))
# Ask user to input travel time in hours
travel_time = int(input('Enter the time travelled in hours.'))
# Validate that the time travelled is within the range of 1 to 9 hours.
while travel_time > max_travel or travel_time < min_travel:
if travel_time > max_travel:
print('ERROR: the time must be a lower number between 1 and 9.')
travel_time = int(input('Enter a different time travelled in hours.'))
# Validate that the time travelled is within the range of 1 to 9 hours.
if travel_time < min_travel:
print('ERROR: the time must be a higher number between 1 and 9.')
travel_time = int(input('Enter a different time travelled in hours.'))
# This will cause the loop, with the exception of the first loop,
# to depend on a 'y' or 'Y' entry to enter any additional entries.
first = False
# Calculate again?
another = input('Do you have another calculation to enter? ' + \
'(Enter y for yes or N for no: )')
# This loop will continue until something other
# than 'y' or 'Y' is entered when prompted.
while another == 'y' or 'Y':
main()
# Calculations saved for table
input_tuple =speed, travel_time
# Print the column headings in a table.
# Print the time travelled and the
# result of the distance calculation
print()
print('Hours\t\tDistance')
print('---------------------')
# Print saved entries and calculations in table
if another !='y' or 'Y':
for input_tuple in results:
# Calculate the distance travelled
distance = speed * travel_time
print("'%s'\t\t'%s'" %(travel_time, distance))
# Call the main function.
def main():
"""
"""'
Beware that the code comes with many indentation errors. Having said that you should at least correct
while another == 'y' or 'Y'
to
while another == 'y' or another == 'Y'
indeed or 'Y' always evaluates to True
Related
In problem set6 I am required to ask user for an input( a float) and then use the input to calculate number of coin the use owe. In my code I used modulo function in a while to increment number of coin by one. Unfortunately I don't get the outcome I expected. Can anyone assist?
Below is my code
# ask the user for change owed
from cs50 import get_float
while True:
change = get_float("Change owed:")
if change > 0:
break
#compute quarter
coin = 0
while change % 0.25 >= 0.25:
change = change - 0.25
coin += 1
#compute dime
while change % 0.1 >= 0.1:
change = change - 1
coint += 1
#compute nickel
while change % 0.5 >= 0.5:
change = change - 0.5
coin += 1
#compute pennies
while change % 0.1 >= 0.1:
change = change - 0.1
coin += 1
print(coin)
in your code lines like:
change % 0.1 >= 0.1
always will be false, because any remainder after division change on some k is less than k.
Your coin always will be 0. Also try to think about order of while loops in your algo, seems it should be differ.
Came across this interesting problem and trying to come up with algorithm.
I was able to write a backtracking solution:
def get_possible_seatings(seats, dist):
# Account for the last seat
seats.append(0)
arrangement = []
total_seatings = 0
def dfs(curr, prev_dist):
nonlocal total_seatings
if curr > len(seats):
return
if curr == len(seats):
total_seatings += 1
return
# We have only one choice, don't sit
if prev_dist < dist:
dfs(curr+1, prev_dist+seats[curr])
else:
# We have 2 choices here
arrangement.append(curr)
dfs(curr+1, seats[curr]) # We do sit
arrangement.pop(-1)
dfs(curr+1, prev_dist+seats[curr]) # We don't sit
return
for index in range(len(seats)):
arrangement.clear()
arrangement.append(index)
dfs(index + 1, seats[index])
# Account for no seats occupied
return total_seatings + 1
And my own version of the dynamic-programming solution:
def get_possible_seatings(seats, distance):
"""
This is O(n^2) solution
"""
# Account for the last seat
seats.append(0)
# Each seat can be occupied individually
dp = [1] * len(seats)
# Keep track of total distance from first seat
total_distance = [0] * len(seats)
prefix_sum = seats[0]
for index, i in enumerate(seats[1:], 1):
total_distance[index] = prefix_sum
prefix_sum += i
# Start from second seat onwards, this is the curr seat 'i'
for i in range(1, len(seats)):
"""
Check each of the seat starting from 1st. If the distance between current seat 'i' and previous
seat 'j' is desirable, add the dp at previous seat 'j' to current dp
This basically means, that both previous seat and current seat can be occupied together then
total number of ways to seat will increase by number of ways to be seated at previous seat
"""
for j in range(i):
if total_distance[i] - total_distance[j] >= distance:
dp[i] += dp[j]
# Account for no seat occupied
return sum(dp) + 1
But I am unable to wrap my head around the O(n) solution posted in the original link
Could not figure out the logic without comments :(
My take is:
It looks like sliding window technique where we keep left and right prefix sums. And keep expanding window(right) till we hit the desired distance. Then keep shrinking it(left) as long as we are at distance >= desired distance.
Can anyone help me confirm this, please?
I've been looking around for a few hours, and I couldn't find any solutions for this specific problem. I did see one person who asked the same question, but they didn't provide code, and so didn't get an answer. My problem is this:
I have a program that sends the turtle left and right randomly for a set number of turns. The turning part works, but when I try to save the canvas, it only saves the visible part, which often cuts things off. I have tried increasing the size of the setup canvas, as well as the screen capture, but the saved file always ends up in the top left corner, and so gets cut off. I'm attaching my entire program (it's short, don't worry), because I'm not sure exactly what aspect needs to change.
Any help would be greatly appreciated!
import turtle
import random
'''
Takes a variable, number, of how many random turns the turtle should make and a variable filenumber,
which is used to save multiple different iterations of the program per program execution
'''
def left_or_right(number,filenumber):
# Counters to make sure the turtle doesn't turn too many times
count = 0
subright = 0
subleft = 0
#sets up screen
win_width, win_height, bg_color = 10000, 10000,'white'
turtle.setup()
turtle.screensize(win_width, win_height,bg_color)
# Clears the screen, sets the turtle in the middle of the screen, drops the pen and hides the
# Turtle. If you want to see the turtles do the drawing, turn turtle.tracer to True, and
# uncomment out turtle.speed('fastest')
turtle.clear()
turtle.home()
turtle.hideturtle()
turtle.pendown()
turtle.speed('fastest')
turtle.tracer(False)
# A for loop for the turtle's turns
for i in range(number):
# Calls decider to you can get a random direction every time
decider = random.randint(0, 1)
# in order to minimize the turtle just going around in circles,
# if the turtle has made more that 3 of the same turn, turn it the other way
# the next to if statements deal with the turtle turning right too many times
if decider == 1 and subright <= 3:
turtle.right(90)
turtle.forward(20)
count += 1
subright += 1
elif decider == 1 and subright > 3:
turtle.left(90)
turtle.forward(20)
count += 1
subright = 0
# The next two if statements make sure the turtle doesn't turn right too many times
elif decider == 0 and subleft <= 3:
turtle.left(90)
turtle.forward(20)
count += 1
subleft += 1
elif decider == 0 and subleft > 3:
turtle.right(90)
turtle.forward(20)
count += 1
subleft = 0
# if the number of turns is equal to what the user inputed, stop making the turns
# and update the screen
if count == number:
turtle.penup()
turtle.update()
# Take a screen capture of the screen and saves it to where the python file is
ts = turtle.getscreen()
ts.getcanvas().postscript(file=filenumber,height=10000, width=10000)
# turtle.done() is here as a debugging tool. If you set the number of files you're
# generating to one, you can keep the turtle window open to check that the file correctly
# copied the turtle screen
#turtle.done()
''' Takes a variable, filenumber, which is the number of generated files you want'''
def filegen(filenumber):
for i in range(filenumber):
# Calls the left or right function as many times as you told it to
# Note: this is where the left or right function get's its turn number parameters
left_or_right(10000,i)
def main():
# calls filegen as many times as you want it to
filegen(4)
if __name__ == '__main__':
main()
I need more efficient code which does the same thing I already have, but better.
I made a dynamic lighting system for my game. The way I currently have it programmed, the lighting values update each hour.
The time is blitted onto a monitor in-game and 'self.custom' is used in screen.fill() before a background with transparent sky (which also changes colour) is placed in front of it.
But I only wrote it this way as a prototype to test other features faster. It looks messy as code and I would also rather have the sky fluidly changing after every 56 ticks (minimum possible), rather than in larger time blocks of 600 ticks.
I divided 14400 by 255 (RGB values range) to get 56 (as an int) but my brain's fried and I can't think what I need to do with those values.
Here's the way it currently looks -
if self.time in range(0, 599):
self.showTime = '12 AM'
self.custom = (0,0,0)
elif self.time in range(600, 1199):
self.custom = (24,24,24)
self.showTime = '1 AM'
...
etc...
I hope I explained well enough what the problem is and what I want?
You could define everything up front (either as a dict, as I've done here, or just as a tuple/list):
timeData = [
{'showTime': '12 AM', 'custom': (0,0,0)},
{'showTime': '1 AM', 'custom': (24,24,24)},
...
]
and then use integer division to check what index in that list the time should correspond to:
idx = (self.time // 56) % len(timeData) # 0 if time < 56
# 1 if 56 <= time < 112
# ...
self.showTime = timeData[idx]['showTime']
self.custom = timeData[idx]['custom']
That's assuming that you're setting custom manually, and not doing a solid gradient from black to white. If you are, then you could omit putting that in timeData, and just calculate it based on idx, which would be conceptually easier than doing it based directly on self.time:
self.custom = (20 * idx,) * 3 # make 3-tuple with 3 of the same value
If you want a gradient effect, you could calculate it every time you want the sky to update.
if self.time < (14400/2): #If the time is before midday
self.rgb_value = int(((14400/2)/255)*self.time) #Set the sky colour to a value between 0 and 255, where 0 is at midnight and 255 is at midday.
elif self.time == (14400/2): #If the time is midday
self.rgb_value = 255 #Midday is full brightness
elif self.time > (14400/2) and self.time < 14400: #If the time is after midday
self.rgb_value = int(((14400/2)/255)*-(self.time-14400)) #The code is similar to before midday, but subtract the full length from self.time, and invert the result, to get the time until midnight.
elif self.time == 14400: #If the time is midnight
self.rgb_value = 0 #It is dark at midnight
self.custom = (self.rgb_value,self.rgb_value,self.rgb_value) #Convert the value into a colour.
For the clock display, you can have a list like:
clockoptions = [ (0,599,"12 AM"),
(600,1199,"1 AM"),
...
]
and pull values from it every time the clock is updated using the code
for opt in clockoptions:
if self.time >= opt[0] and self.time <= opt[1]:
self.showTime = opt[2]
break #Stop the loop from continuing to iterate unnecessarily.
This code is untested but I hope this helps.
I'm making a program to calculate primes, and I look at the remainder of the possible prime I'm testing and all the primes I have so far, but stop if I get to the point where I am comparing the PossPrime to anything above its square root. (I can explain this if needed). I don't care about any digits after the decimal point of the sqrt; is there a way to tell Python not to bother calculating those?
And, is there a way to integrate that aspect (only testing the primes under it until I get to the sqrt) into the for loop?
#There's some boring setup before here that isn't problematic.
while True:
PossWasDivis = False #initialize the var (used to convey if the possible prime was divis)
sqrtP = int(sqrt(PossPrime))
for iterationOfArray in range(2, sqrtP):
# print ("Comparing: (", PossPrime, "% (", GlobPrimeList [iterationOfArray],")) == 0")
if (PossPrime % (GlobPrimeList [iterationOfArray])) == 0:
# print(PossPrime, "was divisable by", GlobPrimeList[iterationOfArray],"! Breaking for loop")
PossWasDivis = True
break
if (GlobPrimeList [iterationOfArray]) > sqrtP:
break
if PossWasDivis == False: # Occurs when none of the tested #s are divis
GlobPrimeList.append (PossPrime)
f.write(str(PossPrime)+'\n')
#Switch between incramenting PossPrime between 2 and 4
if PossPrimeStat == 2:
PossPrimeStat = 4
PossPrime += 4
else: # if PossPrimeStat == 4:
PossPrimeStat = 2
PossPrime += 2
The GlobPrimeList has some primes preloaded in it to start out with and continues finding more indefinitely until I cancel the program.
I don't care about any digits after the decimal point of the sqrt; is there a way to tell Python not to bother calculating those?
Nope.
math.sqrt() works with floating-point values. The precision you get is baked right in to the math.
Python does contain functions for "arbitrary-precision" math, where you can specify how much precision you will get... but those functions are much slower than the functions that operate on float values. If you want faster code, you will be using float values, and there is no way to tell Python not compute the whole value.