首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游泳运动员评估训练计划

游泳运动员评估训练计划
EN

Code Review用户
提问于 2018-06-04 11:30:57
回答 2查看 360关注 0票数 6

这是一个允许用户在游泳训练中自我评估的程序,它将评估保存在一个新的文本文件中,将日期作为标题。有许多重复的代码块,我如何使它们更小?

代码语言:javascript
复制
# We want to get the user input for the warm-up and the main-set.
# We want the user to evaluate himself in the warm-up and the main-set.
# We will allow the user to enter comments about specific sets.
# We want to save the users evaluations so that they can be read later.
# Add error exceptions when done.
import time


def commentw():
    global w_comments
    print("What are your comments for the warm-up?")
    comments = input()
    w_comments.append(comments)


def commentms():
    global ms_comments
    print("What are your comments for the main-set?")
    comments = input()
    ms_comments.append(comments)


warmup = []
while True:
    print("Warm-up:")
    print("Insert number of reps (10, 20, 50,...), type exit to move on to the evaluation.")
    reps = input()
    if reps.lower() == "exit" and warmup != []:
        break
    try:
        val = int(reps)
    except ValueError:
        print("Please enter the data properly")
        continue
    if int(reps) == 0:
        continue

    print("Insert distance(50, 100, 200,...), type exit to move on to evaluation.")
    distance = input()
    if distance.lower() == "exit":
        break
    try:
        val = int(distance)
    except ValueError:
        print("Please enter the data properly.")
        continue
    if int(distance) == 0:
        continue

    print("Insert type (Butterfly drills, Freestyle all-out,...), type exit to move on to the evaluation.")
    types = input()
    if types.lower() == "exit":
        break
    print("\n"*20)
    warmup.append(reps + " x " + distance + " " + types)


print("\n"*20)
print("Evaluation:")
# In the warm-up, the user needs to evaluate himself in each set of reps.
# In order to do that, he will have to evaluate his technique.
# This can be done by knowing how many reps were performed with an ideal technique and focus.
w_evaluation = []
w_total = 0
for item in warmup:
    print("How many reps were performed with intense focus on the technique in the " + item + "?")
    n = int(item.split()[0])
    answer = n+1
    while answer > n or answer == "":
        answer = float(input())
    w_evaluation.append(item + ": " + str(answer/n*10)+"/10.0")
    w_total += answer/n*10


print("\n"*20)
mainset = []
while True:
    print("Main-set:")
    print("Insert number of reps (10, 20, 50,...), type exit to move on to the evaluation.")
    reps = input()
    if reps.lower() == "exit" and mainset != []:
        break
    try:
        val = int(reps)
    except ValueError:
        print("Please enter the data properly.")
        continue

    print("Insert distance(50, 100, 200,...), type exit to move on to evaluation.")
    distance = input()
    if distance.lower() == "exit":
        break
    try:
        val = int(distance)
    except ValueError:
        print("Please enter the data properly.")
        continue

    print("Insert type (Butterfly drills, Freestyle all-out,...), type exit to move on to the evaluation.")
    types = input()
    if types.lower() == "exit":
        break
    print("\n"*20)
    mainset.append(reps + " x " + distance + " " + types)

print("\n"*20)
print("Evaluation:")
# For the main-set evaluation, the user will evaluate himself according technique, speed and focus.
ms_evaluation = []
focus_on = []
ms_total = 0
for item in mainset:
    print("How many reps in " + item + " were performed with the appropriate pace?")
    pace = float(input())
    print("How many reps in " + item+" were performed with appropriate technique?")
    tech = float(input())
    print("How many reps in " + item+" were performed with appropriate focus?")
    focus = float(input())
    n = int(item.split()[0])
    if pace/n < (n/2)/n:
        focus_on.append("Focus on pace in " + item)
    if tech/n < (n/2)/n:
        focus_on.append("Focus on your technique in " + item)
    if focus/n < (n/2)/n:
        focus_on.append("Improve your focus in " + item)
    ms_evaluation.append(item + ": " + str(((pace+tech+focus)/(n*3))*10)+"/10")
    ms_total += ((pace+tech+focus)/(n*3))*10

# Now it is time to print the evaluations for the user and allow him to write comments.
print("\n"*20)
print("============\nWarm-up evaluation\n============")
for item in w_evaluation:
    print(item)
print("Total: " + str(w_total))

print("\n"*20)
print("============\nMain-set evaluation\n============")
for item in ms_evaluation:
    print(item)
print("Total: " + str(ms_total))

print("Would you like to add comments on certain parts?")
w_comments = []
ms_comments = []
print("These comments could include what to focus on during the next practice.")
print("Type exit to save and exit")
answer = ""
while answer != "exit":
    print("use (w) for warm-up and (m) for main-set.")
    answer = input()
    if answer == "w":
        commentw()
    if answer == "m":
        commentms()

# Now it is time to save everything
# We want to save the evaluation, and the comments
name = time.strftime("%d.%m.%y.txt")
f = open(name, "w+")
f.write("============\nWarm-up evaluation\n============\n")
for item in w_evaluation:
    f.write(item+"\n")
f.write("Total: " + str(w_total))
f.write("\n\nComments: \n")
for item in w_comments:
    f.write(item+"\n")

f.write("\n============\nMain-set evaluation\n============\n")
for item in ms_evaluation:
    f.write(item+"\n")
f.write("Total: " + str(ms_total))
f.write("\n\nComments: \n")
for item in ms_comments:
    f.write(item+"\n")
for item in focus_on:
    f.write(item+"\n")
f.close()
EN

回答 2

Code Review用户

发布于 2018-06-04 15:41:10

函数

而不是一行一行的大型脚本,将其拆分为逻辑函数,这允许代码重用。

使用1 main-method,您在if __name__ == '__main__':-guard后面调用它

特殊条件

如果您有一个函数请求输入您希望'exit'中断流的地方,那么使用一个Exception,这就是它们的目的。

代码语言:javascript
复制
class Exit(Exception): pass    

def ask_positive_int(name: str) -> int:
    while True:
        reps = input(
            f"Insert number of {name}, type exit to move on to the evaluation.")
        if reps.lower() == 'exit':
            raise Exit
        try:
            reps = int(reps)
            if reps >= 0:
                return reps
        except ValueError:
            pass
        print('Answer a correct number')

返回而不是打印

这样,您就可以在多个地方重复使用答案,或者如果您更改了用户界面,您可以这样做而不需要太多的麻烦。

发生器

与其实例化空列表、追加到它并最终返回此列表,不如使用yield元素:

代码语言:javascript
复制
def ask_excercises():
    while True:
        try:
            reps = ask_reps()
            distance = ask_distance()
            excercise_type = ask_type()
        except Exit:
            return
        yield reps, distance, excercise_type

使用

with-statement

打开文件

若要确保文件已关闭,请使用context managers

提升IO

将IO设置在尽可能高的水平,正如布兰登·罗兹在这次谈话中提到的那样。

保存文件以及前面的几点如下所示:

代码语言:javascript
复制
filename = time.strftime("%d.%m.%y.txt")
with open(filename, 'w+') as filehandle:
    save_evaluation(
        filehandle,
        warmup_evaluation,
        main_evaluation,
        comments
    )

多行字符串

而不是

代码语言:javascript
复制
print("Would you like to add comments on certain parts?")
print("These comments could include what to focus on during the next practice.")
print("Type exit to save and exit")

你可以:

代码语言:javascript
复制
print("""
    Would you like to add comments on certain parts?
    These comments could include what to focus on during the next practice.
    Type exit to save and exit
    """)

全码

代码语言:javascript
复制
from collections import defaultdict

import time


class Exit(Exception): pass


def ask_reps() -> int:
    """
    asks the number of repititions to the

    retries untill the user enters a valid integer >= 0 or `exit`
    Returns
    -------
    int
        the number of repititions or `None` when the user enters `exit`
    """
    return ask_positive_int('reps')


def ask_distance() -> int:
    return ask_positive_int('distance')


def ask_positive_int(name: str) -> int:
    while True:
        reps = input(
            f"Insert number of {name}, type exit to move on to the evaluation.")
        if reps.lower() == 'exit':
            raise Exit
        try:
            reps = int(reps)
            if reps >= 0:
                return reps
        except ValueError:
            pass
        print('Answer a correct number')


def ask_evaluation(excercise, characteristic):
    while True:
        answer = input(
            f'How many reps in {excercise}  were performed with the appropriate {characteristic}?')
        try:
            return float(answer)
        except ValueError:
            print('answer a correct number')


def ask_type():
    answer = input(
        f'Insert type of excercise, type exit to move on to the evaluation.')
    if answer.lower() == 'exit':
        raise Exit
    return answer


def clear_screen():
    print('\n' * 20)


def ask_excercises():
    while True:
        try:
            reps = ask_reps()
            distance = ask_distance()
            excercise_type = ask_type()
        except Exit:
            return
        yield reps, distance, excercise_type


def ask_warmup_evaluation(excercises):
    for excercise in excercises:
        score = ask_evaluation(
            excercise_string(excercise),
            'intense focus on the technique'
        )
        yield excercise, score


def excercise_string(excercise):
    reps, distance, excercise_type = excercise
    return f'{reps} x {distance} {excercise_type}'


def ask_main_evaluation(excercises):
    focus_on = []
    evaluation = []
    for excercise in excercises:
        reps, distance, excercise_type = excercise
        characteristics = ['pace', 'technique', 'focus']
        scores = []
        for characteristic in characteristics:
            answer = ask_evaluation(excercise, characteristic)
            if answer / reps < 0.5:
                focus_on.append((excercise, characteristic))
            scores.append(answer)
        total = sum(scores) / len(scores)
        evaluation.append((excercise, total))
    return evaluation, focus_on,


def print_evaluation(evaluation, filehandle=None):
    total = 0
    for excercise, score in evaluation:
        print(f'{excercise_string(excercise)}: {score} / 10', file=filehandle)
        total += score

    print(f'Total: {total}', file=filehandle)


def get_comments():
    print("""
    Would you like to add comments on certain parts?
    These comments could include what to focus on during the next practice.
    Type exit to save and exit
    """)
    comments = defaultdict(list)
    comment_types = {
        'w': 'warm-up',
        'm': 'main-set',
    }
    message = '\n'.join(
        f'use ({key}) for {description}.'
        for key, description in comment_types.items()
    )
    while True:

        comment_type = input(message).lower()
        if comment_type == 'exit':
            return comments
        comment_type = comment_types.get(comment_type, None)
        if comment_type is None:
            print('enter a valid part to comment on')
            continue
        msg = f'What are your comments for the {comment_types[comment_type]}'
        comment = input(msg)
        comments[comment_type].append(comment)

    return comments


def save_evaluation(
        filehandle,
        warmup_evaluation,
        main_evaluation,
        comments,
        focus_on
):
    filehandle.write("""
    ==================
    Warm-up evaluation
    ==================
    """)
    print_evaluation(warmup_evaluation, filehandle=filehandle)

    filehandle.write("""
    ===================
    Main-set evaluation
    ===================
    """)
    print_evaluation(main_evaluation, filehandle=filehandle)

    filehandle.write("""
        ========
        Comments
        ========""")
    for comment_type, comment_strings in comments.items():
        filehandle.write(comment_type)
        filehandle.writelines(comment_strings)

    filehandle.write("""
    ========
    Focus on
    ========""")
    filehandle.writelines(focus_on)


def main():
    print('Warm-up:')
    warmup_excercises = ask_excercises()
    clear_screen()
    print("Evaluation:")
    warmup_evaluation = list(ask_warmup_evaluation(warmup_excercises))
    print_evaluation(warmup_evaluation)
    clear_screen()

    print("Main-set:")
    main_excercises = ask_excercises()
    clear_screen()
    print("Evaluation:")
    main_evaluation, focus_on = ask_main_evaluation(main_excercises)
    print_evaluation(main_evaluation)
    clear_screen()

    comments = get_comments()
    clear_screen()

    filename = time.strftime("%d.%m.%y.txt")
    with open(filename, 'w+') as filehandle:
        save_evaluation(
            filehandle,
            warmup_evaluation,
            main_evaluation,
            comments,
            focus_on
        )


if __name__ == "__main__":
    main()
票数 7
EN

Code Review用户

发布于 2018-06-04 13:09:14

老实说,看起来只有三块代码是可重用的,所以我把它们变成了函数。我创建了一个comments函数以获取用户的注释,一个enter_exercise函数用于输入练习类型,另一个print_eval函数用于打印评估结果。所有这些参数都有两个主要参数,第一个是只用于输出的类型(“热身”或“主集”),第二个是附加输入的列表(在print_eval的情况下,只有输出,输出值也是总价值)。

为了简单和清晰,还有一些其他的代码更改。

  1. 没有必要在print('something')之前执行value = input(),将它们更改为value = input('something')
  2. 每次您转换一个输入时,您都应该用一个try...except ValueError包围它,然后将它包围在一个循环中,所以如果它们输入了一些无效的东西,您将给它们另一个输入值的机会。
代码语言:javascript
复制
import time

def get_num(msg,ex_list):
    while True:
        num = input(msg)
        if num.lower() == "exit" and ex_list != []:
            return -1
        try:
            num = int(num)
        except ValueError:
            print("Please enter the data properly")
            continue

        if num <= 0:
            print("Please enter number greater than 0")
            continue
        else:
            return num

def get_float(msg):
    while True:
        try:
            return float(input(msg))
        except ValueError:
            print("Please enter a number.")
            continue

def comments(comment_type,comment_list):
    comments = input("What are your comments for the {}?".format(comment_type))
    comment_list.append(comments)
    return comment_list

def enter_exercise(ex_type,ex_list):
    while True:
        print("{}:".format(ex_type))
        reps = get_num("Insert number of reps (10, 20, 50,...), type exit to move on to the evaluation.",ex_list)
        if reps==-1:
            return ex_list

        distance = get_int("Insert distance(50, 100, 200,...), type exit to move on to evaluation.",ex_list)
        if distance==-1:
            return ex_list

        types = input("Insert type (Butterfly drills, Freestyle all-out,...), type exit to move on to the evaluation.")
        if types.lower() == "exit" and ex_list != []:
            return ex_list
        print("\n"*20)
        ex_list.append(reps + " x " + distance + " " + types)
    return ex_list

def print_eval(ev_type,ev_list,ev_total):
    print("\n"*20)
    print("============\n{} evaluation\n============".format(ev_type))
    for item in ev_list:
        print(item)
    print("Total: " + str(ev_total))

warmup = []
warmup = enter_exercise('Warm-up',warmup)

print("\n"*20)
print("Evaluation:")
# In the warm-up, the user needs to evaluate himself in each set of reps.
# In order to do that, he will have to evaluate his technique.
# This can be done by knowing how many reps were performed with an ideal technique and focus.
w_evaluation = []
w_total = 0
w_evaluation,w_total = eval_exercise(warmup,w_total,w_evaluation)
for item in warmup:
    print("How many reps were performed with intense focus on the technique in the " + item + "?")
    n = int(item.split()[0])
    answer = n+1
    while answer > n or answer == "":
        try:
            answer = float(input())
        except ValueError:
            print("Please enter a number less than or equal to {}.".format(str(n)))
    w_evaluation.append(item + ": " + str(answer/n*10)+"/10.0")
    w_total += answer/n*10

print("\n"*20)
mainset = []
mainset = enter_exercise('Main-set',mainset)

print("\n"*20)
print("Evaluation:")
# For the main-set evaluation, the user will evaluate himself according technique, speed and focus.
ms_evaluation = []
focus_on = []
ms_total = 0
for item in mainset:
    pace = get_float("How many reps in " + item + " were performed with the appropriate pace?")
    tech = get_float("How many reps in " + item+" were performed with appropriate technique?")
    focus = get_float("How many reps in " + item+" were performed with appropriate focus?")

    n = int(item.split()[0])
    if pace/n < (n/2)/n:
        focus_on.append("Focus on pace in " + item)
    if tech/n < (n/2)/n:
        focus_on.append("Focus on your technique in " + item)
    if focus/n < (n/2)/n:
        focus_on.append("Improve your focus in " + item)
    ms_evaluation.append(item + ": " + str(((pace+tech+focus)/(n*3))*10)+"/10")
    ms_total += ((pace+tech+focus)/(n*3))*10

# Now it is time to print the evaluations for the user and allow him to write comments.
print_eval('Warm-up',w_evaluation,w_total)

print_eval('Main-set',ms_evaluation,ms_total)

print("Would you like to add comments on certain parts?")
w_comments = []
ms_comments = []
print("These comments could include what to focus on during the next practice.")
print("Type exit to save and exit")
answer = ""
while answer != "exit":
    answer = input("use (w) for warm-up and (m) for main-set.").lower()
    if answer == "w":
        w_comments = comments('warm-up',w_comments)
    elif answer == "m":
        ms_comments = comments('main-set',ms_comments)
    elif answer == 'exit':
        break

# Now it is time to save everything
# We want to save the evaluation, and the comments
# 
# Did not change anything beyond this point
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/195806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档