import datetime
import random
import time
import math
player_1 = input("Player one: ")
speed = int(input("Speed in km/h: "))
speed_ms = ((speed)/3.6)
conditions = input("Wet or dry conditions? (all lowercase)")
if conditions == "wet":
friction_coefficient = 0.4
else:
friction_coefficient = 0.6
time.sleep(0.5)
print("Get ready..")
time.sleep(random.randint(1,12))
then = datetime.datetime.now()
t = input("GO!! ")
now = datetime.datetime.now()
diff = then-now
reaction_time = round(abs(diff.total_seconds()), 2)
Rt = (math.sqrt((reaction_time*98)/490))
print('Your final reaction time was: ', (Rt), '!\n')
Rd = (Rt * speed_ms)
print('Your final reaction distance was: ', (Rd), '!\n')
Bd = (((speed_ms)**2) / 19.6 * (friction_coefficient))
print('Your final breaking distance was: ', (Bd), '!\n')
Sd = ((Rd)+(Bd))
############################################################################
print("\n\n---===========FINAL STOPPING DISTANCE===========---")
print('--------------', (Sd), 'meters', '------------')
#1 楼
有些数字似乎是凭空冒出来的,但并非如此。我能理解
3.6
甚至19.6
(是\ $ 2g \ $,不是吗?),但我不知道98/490
代表什么。将它们声明为具有有意义名称的符号常量。可能不是负面的。如果是这样,我宁愿抛出一个异常,因为无论如何结果都是毫无意义的。您四舍五入还为时过早。没有反应时间未舍入的惩罚计算
abs
,但是舍入会导致精度损失。打印结果时仅取整。括号太多。
diff
比Rt
干净得多。评论
\ $ \ begingroup \ $
当然,现在肯定会大于该值,所以diff始终为负数吗?尽管删除abs并设置diff = now可能更有意义-然后
\ $ \ endgroup \ $
– Mick O'Hea
18 Mar 15 '11:25
\ $ \ begingroup \ $
现在可能并不总是大于那时。例如,2016年的最后一秒2016-12-31T23:59:60可能小于倒数第二个2016-12-31T23:59:59.99,因为我不确定en.wikipedia.org/wiki/Leap_second是否为在UNIX时代正确实施。您现在应该断言>然后
\ $ \ endgroup \ $
–csiz
18-3-15在17:56
\ $ \ begingroup \ $
我想,使用类似time.time()或timeit.default_timer()之类的计时器函数代替datetime可以避免此问题。对于正在测量的内容,也就是从秒表经过的时间长度,而不是日历上两点之间的距离,这可能是更合适的抽象。请参阅:stackoverflow.com/questions/7370801/…
\ $ \ endgroup \ $
– wwarriner
18 Mar 15 '18在22:48
\ $ \ begingroup \ $
@ hjpotter92一定有一个原因使这种编码符合1/5的要求。否则,除以5对我来说仍然毫无意义。
\ $ \ endgroup \ $
–vnp
18 Mar 16 '18 4:51
\ $ \ begingroup \ $
@Nzall:但这不是错误。 100%准确。这就是它需要做的。如果您不希望这样做,那么您使用的是错误的工具,并且可能应该查看java.time.Clock。
\ $ \ endgroup \ $
–鸭鸭
18 Mar 17 '18 at 0:36
#2 楼
我建议将代码分成函数,以便您可以轻松地将代码import
放入Python shell并测试您的计算是否正确(而不仅仅是认为它是正确的)。要扩展其他答案,您可以可能:
重试询问速度是否不是整数(当
int
函数引发ValueError
时检测到); 以同样的方式,因为您实际上不是需要检查
wet
和dry
,您可以问一个简单的是/否问题; 在打印GO之前刷新输入流(在Linux上使用
termios
或在Windows上使用msvcrt
); 将
time.perf_counter()
优先于datetime.now()
,计算程序中两点之间的时间; 计算所有结果,然后打印出来。
建议的改进:
import random
import time
def flush_input():
try:
import msvcrt
while msvcrt.kbhit():
msvcrt.getch()
except ImportError:
import sys, termios #for linux/unix
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
def ask_speed():
while True:
speed = input("Speed in km/h: ")
try:
return int(speed)
except ValueError:
print("An integer is required!")
def ask_is_wet():
is_wet = input("Is the road wet? [y/n] ")
return is_wet.lower() in ('y', 'yes')
def compute_distances(speed_kmh, reaction_time, is_wet):
speed_ms = speed_kmh / 3.6
friction_coefficient = 0.4 if is_wet else 0.6
reaction_time = (reaction_time * 98 / 490)**.5
reaction_distance = reaction_time * speed_ms
braking_distance = speed_ms**2 / (19.6 * friction_coefficient)
total_distance = reaction_distance + braking_distance
return reaction_time, reaction_distance, braking_distance, total_distance
def get_reaction_time(prompt="GO!! "):
time.sleep(random.randint(1, 12))
then = time.perf_counter()
flush_input()
input(prompt)
now = time.perf_counter()
return now - then
def main():
name = input("Player one: ")
speed = ask_speed()
is_wet = ask_is_wet()
time.sleep(0.5)
print("Get ready..")
reaction_time = get_reaction_time()
reaction, distance, braking, total = compute_distances(speed, reaction_time, is_wet)
print('Your final reaction time was: ', reaction, '!\n')
print('Your final reaction distance was: ', distance, '!\n')
print('Your final braking distance was: ', braking, '!\n')
print("\n\n---===========FINAL STOPPING DISTANCE===========---")
print('--------------', total, 'meters', '------------')
if __name__ == '__main__':
main()
评论
\ $ \ begingroup \ $
为什么没有人指出98/490是/ 5?
\ $ \ endgroup \ $
– hjpotter92
18 Mar 15 '18 at 12:34
\ $ \ begingroup \ $
@ hjpotter92这应该是对vnp答案的更好补充
\ $ \ endgroup \ $
–301_Moved_Permanently
18年3月15日在16:00
#3 楼
如果
speed_ms
的用户输入不是整数,则会崩溃如果用户在
t = input("GO!! ")
之前按任意键,其反应时间将保存为0。这是代码的主要缺陷,应予以修复。#4 楼
如果潮湿,则friction_coefficient
会更低。这意味着Bd
会更低(这可能是错误的)。 由于所有不必要的括号,很难看到这一点。您错过了必要的名称。特别是
Rt
,这可能意味着反应时间-已经有一个名称Rd
的值非常合理。 Bd
包含Rt
是可疑的。如果正确,则需要发表评论。评论
\ $ \ begingroup \ $
平方根在我看来是完全错误的。 reaction_time是以秒为单位的完全明智的时间,然后将Rt用作以秒为单位的时间-但这是一个值,单位为“平方根秒”。
\ $ \ endgroup \ $
–马丁·邦纳(Martin Bonner)支持莫妮卡(Monica)
18 Mar 15'在14:20
#5 楼
读取并分配了
player_1
,但从未使用过。如果用户拼错了
wet
(例如Wet
或wet
),则程序会认为dry
的意思是-它应该再次询问,直到得到它理解的答案为止或玩家放弃(并考虑添加icy
以获得更多的乐趣)。#6 楼
不要依赖用户按照您的指示输入小写字母。做conditions = input("Wet or dry conditions? (all lowercase)").lower()
。而不是进行if else
,而是分别检查每种可能性,然后再次询问是否都没有(如果可能的话,您可能要进行'wet' in conditions
而不是''wet'==条件,以防在末尾放置多余的空格或其他内容)。 由于您将要除以非整数,所以无论如何都将以浮点数结尾,因此将
speed
强制转换为以浮点数开头可能会更好,如果不这样做,请避免舍入输入一个整数。您还应该执行try
块来捕获输入非数字的人。评论
\ $ \ begingroup \ $
如果仍然要转换为小写字母(这是一件好事),为什么提示用户输入小写字母?
\ $ \ endgroup \ $
–David Richerby
18 Mar 16 '18在17:14
\ $ \ begingroup \ $
@DavidRicherby 1.我认为不值得改变。 2.冗余是好的。 3.如果用户不确定要使用哪种格式,告诉他们使用小写字母比说“嘿,我们将所有字母都写成小写字母,这样就不用担心”更简单。
\ $ \ endgroup \ $
–累计
18 Mar 16 '18 at 17:50
#7 楼
输出格式:print
在逗号分隔的参数之间调用输出空格;这会导致如下输出: Your final reaction time was: 1.6 !
这些多余的空格很难看。一个简单的解决方法是
sep
的print
参数: print('Your final reaction time was: ', (Rt), '!\n', sep='')
Your final reaction time was: 1.6!
这将在三个部分之间不打印空格。另外,您可以执行一些字符串连接操作,但是我更喜欢第一种方法。 “ lang-none prettyprint-override”>
Your final reaction time was 1.6 seconds!
西方最慢的枪...
评论
拼写-制动(从动词“制动”开始),而非“断裂”(从“断裂”开始)。不同的东西虽然听起来很一样,但很容易混淆。我既不是数学家,也不是医生,但我怀疑我是否能立即做出反应,阻止汽车在40米内以每小时130公里的速度行驶?
@ThomasAyoub:我希望医生仅在制动距离过大时才需要介入。
这并不能保证答案,但是您应该真正遵循Python样式指南PEP8。特别是,您的标识符应遵循Python样式。
我认为这是由于对“放下尺子”反应时间t = sqrt(2 * d / g)的错误解释/操纵,而距离以cm为单位,简化为t = sqrt(d / 490)。 >