Traffic light program using while loop in python - traffic

I am trying to run this code in python and I want the code to stop looping when the user enters 30, here I have used break to stop the loop, is there any other way? Any suggestion would be helpful.
`x = input("Enter value: ")
stop_light = int(x)
while True:
if stop_light >= 1 and stop_light < 10:
print('Green light')
stop_light += 1
elif stop_light < 20:
print('Yellow light')
stop_light += 1
elif stop_light < 30:
print("Red light")
stop_light += 1
else:
stop_light = 0
break`

Hm I'm not quite sure what you actually want to achieve. Your version does not loop since the break statement will always be met after the first iteration.
Additionally, you only ask for user input once before the loop actually starts.
Here is what I suppose you want to do, so I moved the user input part inside the loop and added the break condition to the pythonic "switch" statement. This will just ask the user for input for as long as he doesn't enter 30.
while True:
x = input("Enter value: ")
stop_light = int(x)
if stop_light == 30:
break
elif stop_light >= 1 and stop_light < 10:
print('Green light')
stop_light += 1
elif stop_light < 20:
print('Yellow light')
stop_light += 1
elif stop_light < 30:
print("Red light")
stop_light += 1
else:
stop_light = 0

As I have already mentioned, your code does not loop. However, this code does:
while True:
try:
x = input("Enter value: ")
stop_light = int(x)
except ValueError:
print("Try Again")
else:
break
while stop_light <= 30:
if stop_light >= 1 and stop_light < 10:
print('Green light')
elif stop_light < 20:
print('Yellow light')
elif stop_light < 30:
print("Red light")
stop_light += 1
In this, I am utilizing a condition in the while loop. The condition is for the loop to iterate the user value until it becomes 30. The reason for this is because of your condition in the Red light line. I explained this further in the Problem #2 below.
Take notice that I am catching ValueError before proceeding.
Also there is only one of stop_light += 1.
Here are some sample outputs:
Enter value: asdf
Try Again
Enter value: 27
Red light
Red light
Red light
# Breaks and closes the code.
Enter value: 5
Green light
Green light
Green light
Green light
Green light
Yellow light
Yellow light
Yellow light
Yellow light
Yellow light
Yellow light
Yellow light
Yellow light
Yellow light
Yellow light
Red light
Red light
Red light
Red light
Red light
Red light
Red light
Red light
Red light
Red light
# Breaks and closes the code.
Now, these are the problems with your code:
Problem #1
else:
stop_light = 0
This portion doesn't properly handle negative numbers and numbers greater than 30. I don't think you wanted to iterate 30 times for the values that fall into that condition since you didn't apply stop_light += 1 in your code. So, you definitely have to think about what the purpose of this is.
Check out the following code that constantly loops until the value is greater than 30:
while True:
try:
x = input("Enter value: ")
stop_light = int(x)
except ValueError:
print("Try Again")
else:
while stop_light < 30:
if stop_light >= 1 and stop_light < 10:
print('Green light')
elif stop_light < 20:
print('Yellow light')
elif stop_light < 30:
print("Red light")
stop_light += 1
if stop_light > 30:
break
Output:
Enter value: asdf
Try Again
Enter value: 27
Red light
Red light
Red light
Enter value: 31
# Breaks and closes the code.
Problem #2
The reason why I scripted to loop until the value is greater than 30 is because of the following lines in your code:
elif stop_light < 30:
print("Red light")
stop_light += 1
If you wanted the loop to break only when the user inputs 30, then those lines of code above works against that theory. Your loop will break even when stop_light is 29 due to the incrementation of stop_light. You should also look into this flaw of your logic.

Related

If statement not working in roblox studio

local Frame = script.Parent.Parent.Frame.BackgroundTransparency
local Red = Frame.RedTeam.BackroundTransparency
local Blue = Frame.BlueTeam.BackroundTransparency
local Button = script.Parent
Button.MouseButton1Click:Connect(
if Frame = 1 then
Frame = 0
Red = 0
Blue = 0
end
if Frame = 0 then
Frame = 1
Red = 1
Blue = 1
)
At
if Frame = 1 then
Frame = 0
Red = 0
Blue = 0
end
I get "Expected else when parsing, instead got =".
Also, at the "end" I get "Expected eof, instead got end"
I cant figure this out and nothing is working.
Replace if Frame = 1 then with if Frame == 1 then
If you want to check wether two values are equal you need to use the equality operator ==, not the assignment operator =.
Also your second if statement is missing its closing end.
Further you probably want to think about your logic.
If Frame equals 0 you'll assign 1. But then you'll end up in the next if statement with the condition Frame == 1 and assign 0 again.
So your code basically does nothing useful.
In lua, if statements use operators which are ==, ~=, >, <, >=, and <=.
the '==' statement basically compares if the first argument they get is the same as the second argument they get, which is the case for you here.
So you'll need to change the Frame = 1 and the Frame = 0 to Frame == 1 and the Frame == 0.
and at the end of your function, it is missing an end there. And also at the start it is not calling a new function. And for peak optimization, instead of using 2 if statements, you can just use 1 with an elseif.
Correction:
local Frame = script.Parent.Parent.Frame.BackgroundTransparency
local Red = Frame.RedTeam.BackroundTransparency
local Blue = Frame.BlueTeam.BackroundTransparency
local Button = script.Parent
Button.MouseButton1Click:Connect(function()
if Frame == 1 then
Frame = 0
Red = 0
Blue = 0
elseif Frame == 0 then
Frame = 1
Red = 1
Blue = 1
end
end)

Discord.py Time Calculation and conversion

So, I recently decided to add a timer command to my discord bot, which takes a specific time and counts down until then. I managed to work that in using something super janky and cobbled together.
This is my code currently:
async def timer(ctx, days, hours, minutes, seconds):
try:
hoursint = int(hours)
daysint = int(days)
minutesint = int(minutes)
secondint = int(seconds)
if daysint < 0:
await ctx.send("I dont think im allowed to do negatives")
raise BaseException
elif hoursint < 0:
await ctx.send("I dont think im allowed to do negatives")
raise BaseException
elif minutesint < 0:
await ctx.send("I dont think im allowed to do negatives")
raise BaseException
elif secondint < 0:
await ctx.send("I dont think im allowed to do negatives")
raise BaseException
elif secondint <= 0 and hoursint <= 0 and daysint <= 0 and minutesint <= 0:
await ctx.send("That's not a time dummy!")
raise BaseException
if secondint >= 60:
secondint = secondint - 60
minutesint += 1
if minutesint >= 60:
minutesint = minutesint - 60
hoursint +=1
if hoursint >= 24:
hoursint = hoursint - 24
daysint += 1
message = await ctx.send("Timer: {seconds}")
if daysint > 0 and hoursint == 0:
hoursint = 23
daysint -= 1
minutesint = 60
secondint = 60
if hoursint > 0 and minutesint == 0:
minutesint = 60
secondint = 60
hoursint -= 1
if secondint == 0 and minutesint > 0:
secondint = 60
minutesint -= 1
while True:
if secondint > 0:
secondint -= 1
if secondint <= 0 and minutesint > 0:
minutesint -=1
secondint = 60
if minutesint <= 0 and hoursint > 0:
hoursint -= 1
minutesint = 60
if hoursint <= 0 and daysint > 0:
daysint -= 1
hoursint = 24
if secondint == 0 and minutesint == 0 and hoursint == 0 and daysint == 0:
await message.edit(content="Ended!")
break
await message.edit(content=f"**Timer: {daysint}:{hoursint}:{minutesint}:{secondint}**")
await asyncio.sleep(1)
await ctx.send(f"{ctx.author.mention} Your countdown Has ended!")
except ValueError:
await ctx.send("Must be a number!")
However, I want to make this a little more intuitive/user friendly. At the moment, it takes inputs only in the "d h m s" format, but I would like it to take a user's date input, I.E "22-2-22, 11:30pm IST" or something similar and set a timer from the current time until that given time.
I haven't been able to figure this out myself and would appreciate any help!
You should use datetime.strptime to work with a datetime object, for which you will have to import from datetime import datetime.
To get all of the user input as string use * before the argument, so it will get the rest of the argument:
async def timer(ctx, *, time):
then you can use datetime.strptime with your format. You can find available "variables" here. In your example, to be able to input 22-02-22, 11:30PM the format would be "%y-%m-%d, %I:%M%p". You can also support multiple formats using try and except:
async def timer(ctx, *, time):
try:
datetime_object = datetime.strptime(time, "%y-%m-%d, %I:%M%p")
except ValueError:
try:
datetime_object = datetime.strptime(time, "second format")
except ValueError:
# And so on
Now you have the time at which the timer finishes, but as it looks like, you want to get how long it takes for it to finish, so you can just subtract the time it ends by the current time:
time_until_timer_end = datetime_object - datetime.now()
and then you can access the days or seconds(which you can then convert to hours) until the timer finishes:
seconds = time_until_timer_end.seconds
total_seconds = time_until_timer_end.total_seconds()
days = time_until_timer_end.days

Need program to repeat itself instead of ending

I'm trying to make a guessing game that allows three tries. So far, it works exactly as I want it to, but the user isn't allowed three tries. After the first, the program just ends and you have to restart it to continue playing. I don't want the program to end until three tries are finished.
How can I do this?
Current code:
from random import randint
guesses = 3
secret = randint(0, 999)
number = 1
PreGuess = input("Enter a number: ")
try:
guess = int(PreGuess)
except:
number = 0
if input:
if number == 1:
if 0 < guesses:
if 0 <= guess <= 999:
if guess < secret:
print("too low")
guesses -= 1
elif guess > secret:
print("too big")
guesses -= 1
elif guess == secret:
print("correct")
else:
print("Number is not in the playable range!")
else:
print("game over")
else:
print("Please enter a number.")
Notice that you only call input() once - at the beginning. You also do not have any loops that make the program jump back to the beginning to allow the player to make another guess.
What you should do is enclose the part that you want repeated in a while loop.
...
while guesses > 0:
PreGuess = input("Enter a number: ")
...
if input:
if number == 1:
if 0 <= guess <= 999:
if guess < secret:
print("too low")
guesses -= 1
elif guess > secret:
print("too big")
guesses -= 1
elif guess == secret:
print("correct")
break
else:
print("Number is not in the playable range!")
else:
print("Please enter a number.")
Then, after the while loop, you can check if the loop was terminated because the user won or if the user made 3 incorrect guesses. If the user made 3 incorrect guesses, guesses would equal 0, and if the user successfully guessed the number, guesses would be greater than 0.
if guesses == 0:
print("game over")

Better algorithm with CIEDE2000 to find true opposite colors

Using Python 3.7 and the colormath module, I had some fun trying to find the complete opposite of one color (ex. The opposite color of black [0, 0, 0] is yellow [255, 255, 0] with a DE of 101.20397657762743) or trying to find the two colors with the most color difference (i.e. "Navy" [0, 0, 110] and "Chartreuse" [143, 255, 0] with a DE of 119.4740815993416, from my potentially inaccurate testing).
Unfortunately, the only way I have found to find the opposite of a given color is just to bruteforce with a little bit of optimization by comparing the given color with (almost) every single sRGB color combo (or, [0, 0, 0] to [255, 255, 255]).
Python 3.7 code:
from colormath.color_objects import sRGBColor as RGBC, LabColor as LabC
from colormath.color_conversions import convert_color as cv_c
from colormath.color_diff import delta_e_cie2000 as de2k
from time import perf_counter as clock
# Example: X11's "Midnight Blue", edit as 'RGBC(r, g, b,...'
reference = RGBC(25, 25, 112, is_upscaled=1)
lab_ref = cv_c(reference, LabC)
# Set max delta
max_delta = 0
# Set estimate calculation's range inverals as factors of 255 (1, 3, 5, 15, 17, 51, 85, 255)
resolution = 17
# Estimate the opposite color
for sample_r in range(0, 256, resolution):
for sample_g in range(0, 256, resolution):
for sample_b in range(0, 256, resolution):
# Convert the sample to Lab
sample = RGBC(sample_r, sample_g, sample_b, is_upscaled=1)
lab_samp = cv_c(sample, LabC)
# Find the color difference
delta = de2k(lab_ref, lab_samp)
# Compare current delta with previous highest delta
if delta > max_delta:
# Overwrite highest delta with current delta
max_delta = delta
# Save estimate for optimization
estimate = sample.get_upscaled_value_tuple()
# Keep any 255 values from estimate, leads to 'range(255, 256)'
low_r = 0 if estimate[0] != 255 else 255
low_g = 0 if estimate[1] != 255 else 255
low_b = 0 if estimate[2] != 255 else 255
# Keep any 0 values from estimate, leads to 'range(0, 1)'
high_r = 256 if estimate[0] != 0 else 1
high_g = 256 if estimate[1] != 0 else 1
high_b = 256 if estimate[2] != 0 else 1
# Reset max delta
max_delta = 0
# Find a better opposite color from estimate
for sample_r in range(low_r, high_r):
for sample_g in range(low_g, high_g):
for sample_b in range(low_b, high_b):
# Convert the sample color to Lab
sample = RGBC(sample_r, sample_g, sample_b, is_upscaled=1)
lab_samp = cv_c(sample, LabC)
# Find the color difference
delta = de2k(lab_ref, lab_samp)
# Compare current delta with previous highest delta
if delta > max_delta:
# Overwrite highest delta with current delta
max_delta = delta
# Overwrite best opposite color with current sample
opposite = sample
# Print the reference, opposite color, and delta E
print(f'{reference.get_upscaled_value_tuple()} with {opposite.get_upscaled_value_tuple()}, {max_delta}')
# Print program time
print(clock())
# Example:
# Returns '(25, 25, 112) with (166, 255, 0), 108.95350620860522
# 2.580066949'
The above code will run for 2.5 seconds to about 19 minutes (assumes second opposite calculation takes 128^3 jumps, returns same value) to about 2 hours 15 minutes (assumes worst possible case is 254^3 jumps, as in no optimization occurs) on my system (3.00 GHz)
CIEDE2000's equations can be seen at this site. Notice the notes at the bottom of the page.
I want to know if there is a more efficient algorithm that can find the complete opposite of a given RGB color. I want to be able to use said algorithm to create a spreadsheet that contains every RGB color and its opposite color before CIEDE202X or CIEDE20XX comes out.
Note: this is my first question on StackOverflow
Edit 1:
Created better estimate optimization. Instead of just keeping 0 or 255 if the estimate had one, I would reduce the limits so that they were only at a maximum of +-32 from the estimate. Runtime reduced to at most 4 seconds on 3.00 GHz.
# Red channel optimization
if estimate[0] == 0 or estimate[0] == 255:
low_r = estimate[0]
high_r = estimate[0] + 1
elif estimate[0] > 32 and estimate[0] < 224:
low_r = estimate[0] - 32
high_r = estimate[0] + 32
elif estimate[0] < 33:
low_r = 0
high_r = estimate[0] + 32
else:
low_r = estimate[0] - 32
high_r = 256
# Green channel optimization
if estimate[1] == 0 or estimate[1] == 255:
low_g = estimate[1]
high_g = estimate[1] + 1
elif estimate[1] > 32 and estimate[1] < 224:
low_g = estimate[1] - 32
high_g = estimate[1] + 32
elif estimate[1] < 33:
low_g = 0
high_g = estimate[1] + 32
else:
low_g = estimate[1] - 32
high_g = 256
# Blue channel optimization
if estimate[2] == 0 or estimate[2] == 255:
low_b = estimate[2]
high_b = estimate[2] + 1
elif estimate[2] > 32 and estimate[2] < 224:
low_b = estimate[2] - 32
high_b = estimate[2] + 32
elif estimate[2] < 33:
low_b = 0
high_b = estimate[2] + 32
else:
low_b = estimate[2] - 32
high_b = 256
CIE DeltaE 2000 is not appropriate for large colour differences so large differences in the range [10, 20]+ simply cannot be evaluated with this quasi-metric and you should probably look at something else such as HyAB colour difference metric: https://onlinelibrary.wiley.com/doi/abs/10.1002/col.22451 or alike.

Implementing Loops from Pseudocode

I was wondering if anyone could suggest to me how to implement this loop in the following pseudocode:
8: loop
9: while f[0] = 0 do
10: for i = 1 to N do
11: f[i ยก 1] = f[i]
12: c[N + 1 - i] = c[N - i]
13: end for
14: f[N] = 0
15: c[0] = 0
16: k = k + 1
17: end while
18: if deg(f) = 0 then
19: goto Step 32
20: end if
......... ...... ....
31: end loop
My question is how I should implement the loop that starts on line 8 and ends on 31; I am comfortable with the statements between lines 8 to 31, but what kind of loop do I use on line 8, and what conditions do I give for the loop?
Thanks in advance.
That's an infinite loop. No conditions, just loop forever. The only way out is to get to step 19. In C-like languages you can write that as while (true) or for (;;):
for (;;) {
// ...
if (deg(f) == 0) {
goto afterLoop;
}
// ...
}
afterLoop:
// ...
goto is frowned upon, though. It'd be better to replace goto Step 32 with a break statement, which exits a loop immediately:
for (;;) {
// ...
if (deg(f) == 0) {
break;
}
// ...
}
For what it's worth, if you didn't have steps 21-30 you could use a do/while loop, where the loop condition goes at the bottom of the loop instead of the top:
do {
// ...
}
while (deg(f) != 0);
That would work if lines 18-20 were the final lines in the loop. Since they're not, it looks like option #2 is the one to go with.
If you are going to write pseudocode in such detail, you might as well write in the target language. Pseudocode should be a much broader brush - something like this (not related to your code):
for each bank account
check balance as of last month
if balance greater than promotion limit
send out valued customer pack
endif
endfor

Resources