在物理课上,我们正在做调查。有些数字似乎是凭空冒出来的,但事实并非如此。数学是正确的(我想)我只是想对代码提供一些反馈。

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', '------------')


评论

拼写-制动(从动词“制动”开始),而非“断裂”(从“断裂”开始)。不同的东西虽然听起来很一样,但很容易混淆。

我既不是数学家,也不是医生,但我怀疑我是否能立即做出反应,阻止汽车在40米内以每小时130公里的速度行驶?

@ThomasAyoub:我希望医生仅在制动距离过大时才需要介入。

这并不能保证答案,但是您应该真正遵循Python样式指南PEP8。特别是,您的标识符应遵循Python样式。

我认为这是由于对“放下尺子”反应时间t = sqrt(2 * d / g)的错误解释/操纵,而距离以cm为单位,简化为t = sqrt(d / 490)。 >

#1 楼




有些数字似乎是凭空冒出来的,但并非如此。我能理解3.6甚至19.6(是\ $ 2g \ $,不是吗?),但我不知道98/490代表什么。将它们声明为具有有意义名称的符号常量。可能不是负面的。如果是这样,我宁愿抛出一个异常,因为无论如何结果都是毫无意义的。

您四舍五入还为时过早。没有反应时间未舍入的惩罚计算abs,但是舍入会导致精度损失。打印结果时仅取整。
括号太多。 diffRt干净得多。


评论


\ $ \ 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时检测到);
以同样的方式,因为您实际上不是需要检查wetdry,您可以问一个简单的是/否问题;
在打印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(例如Wetwet),则程序会认为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 !
 


这些多余的空格很难看。一个简单的解决方法是sepprint参数:

 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!

西方最慢的枪...