首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >命令行日历

命令行日历
EN

Code Review用户
提问于 2018-03-13 13:21:16
回答 1查看 861关注 0票数 3

我正在制作一个简单的日历应用程序,作为我在CodeCademy课程的一部分。

应用程序的基本功能应该是:查看日历,将事件添加到日历中,更新日历中的事件,从日历中删除事件。

在尝试更新和查找日历中的项目时,我发现自己很难创建函数来识别哪些项目(事件)实际上应该更新或删除,这让我认为,只要在事件名称和日期中添加一个简单的id号,就可以极大地帮助识别日历中的项目。

我想要实现的是拥有某种数据结构(这并不复杂)来获取3条数据,并能够通过以下每一项找到该项:唯一的id、日期、事件名称。

现在我正在使用字典作为calendar = {"YYYY/MM/DD" : "Event name"}

我在寻找这个挑战的一些答案,发现数组使用numpy,但不太确定这是否必要(而且看起来很复杂),所以我问您。如果这是太无知的方法,那么我真的很抱歉,我保证下次会问得更好,但这是我学习蟒蛇的第一周,所以有很多需要学习的地方。

如果你们中的任何人想看代码并给我任何提示,我会很高兴的。(我知道我需要重写所有的东西来考虑新的数据类型)

代码语言:javascript
复制
"""Command Line Calendar
Functionalities:
 - View the calendar
 - Add an event to the calendar
 - Update an existing event
 - Delete an existing event
 The program should behave in the following way:

Prompt the user to view, add, update, or delete an event on the calendar
Depending on the user's input: view, add, update, or delete an event on the calendar
The program should never terminate unless the user decides to exit
"""
from time import sleep, strftime
from calendar import monthrange

def welcome():
  print("Welcome to Command Line Calendar!")
  name = str(input("What's your name?"))
  print("Hello, ", name, ". It's nice to meet you!", sep="")
  sleep(1.5)
  return


def print_menu():
    # Prints menu options in cmd line.
    print(strftime("%A, %m-%d-%Y %H:%M:%S"))
    print("Menu: ")
    sleep(0.5)
    print("1 - View the calendar")
    sleep(0.5)
    print("2 - Add an event to the calendar")
    sleep(0.5)
    print("3 - Update an existing event")
    sleep(0.5)
    print("4 - Delete an existing event")
    sleep(0.5)
    print("0 - Exit the calendar")
    sleep(0.7)
    return


def get_user_input():
    # Gets user_input. Blocks wrong user_input. Only integers 0-4.
    while True:
        try:
            user_input = int(input("Choose your option: "))
            if user_input > 4 or user_input < 0:
                raise ValueError
            break
        except ValueError:
            print("Should be an integer 0-4.")

    return user_input


def choose_function(user_input, cal):
    # Processes user_input and forwards to proper function.
    if user_input == 0:
        exit_calendar()
    elif user_input == 1:
        view_calendar(cal)
    elif user_input == 2:
        add_event(cal)
    elif user_input == 3:
        update_event(cal)
    elif user_input == 4:
        delete_event(cal)
    return


def exit_calendar():
    # Prints a message and exits the program using exit().
    print("Thank you for using Command Line Calendar!")
    print("Exiting...")
    exit()
    return


def view_calendar(cal):
  if len(cal) == 0:
    print("There are no entries to show.")
    print()
    sleep(1)
  else:
    cal_keys_sorted = sorted(cal)
    for k in cal_keys_sorted:
      print(k, "-", cal[k])
    print()


def add_event(cal):
  print("We need 2 piece of data: date and event name.")
  date_str = get_date_as_string()
  event_name = str(input("Event name: "))
  cal[date_str] = event_name
  print()
  print("Calendar item:", date_str, "-", cal[date_str]) # Prints event and date added.
  print()
  print("Item successfully added to the calendar!")
  sleep(1)
  return


def update_event(cal):
    return


def delete_event(cal):
  view_calendar(cal)
  print("We need to find an item you want to delete.")
  find_calendar_item(cal)

    return

def create_calendar():
  calendar = {}
  return calendar

def get_date_as_string():
  # This function takes user input and makes sure it's in proper format: MM/DD/YYYY.
  while True:
    try:
      y = int(input("Year formatted YYYY: "))
      if str(y) < strftime("%Y"):
        raise ValueError
      break
    except ValueError:
      print("Try again with suggested format. Year must be", strftime("%Y"), "or further.")

  while True:  
    try:
      mo = str(input("Month formatted MM: "))
      if len(mo) > 2 or len(mo) < 2:
        raise ValueError
      if int(mo) > 12 or int(mo) < 1:
        raise ValueError
      if str(y) == strftime("%Y"):
        if str(mo) < strftime("%m"):
          raise ValueError
      break
    except ValueError:
      print("Try again with the format suggested. Month should be within 1-12 range, but not in the past.")

  while True:
    try:
      d = str(input("Day formatted DD: "))
      if len(d) > 2 or len(d) < 2:
        raise ValueError
      if int(d) > monthrange(y,int(mo))[1] or int(d) < 1:
        raise ValueError
      if str(y) == strftime("%Y") and \
         str(mo) == strftime("%m") and \
         str(d) < strftime("%d"):
           raise ValueError
      break
    except ValueError:
      print("Try again with the format suggested. Also number of days has to be in range: 01 -", monthrange(y,int(mo))[1])

  date = str(y) + "/" + str(mo) + "/" + str(d)

  return date

def find_calendar_item(cal):
  print("1 - Find calendar item by date")
  print("2 - Find calendar item by event name")
  # Checks if input is an integer 1-2
  while True:
    try: 
      user_input = int(input("Choose your option: "))
      if (user_input > 2) or (user_input < 1):
        raise ValueError
      break
    except ValueError: 
      print("Choose 1 to find by date or 2 to find by event name.")
    if user_input == 1:
      find_item_by_date(cal)
    if user_input == 2:
      item_name = find_item_by_name(cal)


def find_item_by_name(cal):
  temp_cal = {}
  while True:
    user_input = str(input("What name do you want to find? "))
    # Adding substrings found to temp_cal
    i = 1
    for k in cal:
      if user_input.lower() in str(cal[k]).lower():
        temp_cal[i] = cal[k]
        i += 1
    # If no items found
    if len(list(temp_cal.keys())) == 0:
      print("No items with", user_input, "found. Try again!")
      print()
    else: 
      break

  for k1 in temp_cal:
    print(k1, '-', temp_cal[k1])
  print("0 - It's not on the list")
  while True:
    try:
      user_input2 = int(input("Is the item you are looking for any of these?"))
      if user_input2 < 0 or user_input2 > len(list(temp_cal.keys())):
        raise ValueError
      break
    except ValueError:
      print("Choose from 0-", len(list(temp_cal.keys())))
  if user_input2 == 0:
    print("Okay, let's try another name.")
    print()
    find_item_by_name(cal)
    return
  for key in cal:
    if temp_cal[user_input2] == cal[key]:
      return key

def find_item_by_date(cal):
  return

def calendar_app():
  welcome()
  cal = create_calendar()
  while True:
    print_menu()
    user_input = get_user_input()
    choose_function(user_input, cal)
  return

#calendar_app()

print(strftime("%A, %m - %d - %Y"))

cal = {
  "2018/03/12" : "Work",
  "2018/12/24" : "Christmas",
  "2019/03/03" : "Manicure",
}
view_calendar(cal)
print()
print()
print()
find_item_by_name(cal)
EN

回答 1

Code Review用户

发布于 2018-03-14 05:30:59

通过快速回顾,我可以提出以下建议:

  • 默认情况下,input()返回一个字符串,您不需要用str(包装它
  • print函数可以使用f-字符串(如果使用Python3.4或更高版本)。例如,您的行变成以下一行: print("Hello,",name,".很高兴见到您!“,sep="")打印(f”Hello,{name}.很高兴见到您!“)
  • 您不需要在exit()之后返回-应该类似于(请记住import sys):def exit_calendar():print(“感谢您使用命令行日历!\n退出.”)sys.exit()
  • 新程序员经常做的一件事就是写注释。Bob叔叔告诉我们,如果你必须写一个注释,那么你的代码就错了。例如,这个注释:#打印一条消息并使用exit()退出程序。是多余的,因为您已经将函数命名为exit_calendar。很容易解释的。没有必要在注释中重复您的代码已经声明的内容。
  • print() ->在打印语句中使用"\n"
  • 函数末尾的return。你只需要那些,如果你要返回的东西,否则它将“返回”给调用者。
代码语言:javascript
复制
def find_calendar_item(cal):
  print("1 - Find calendar item by date")
  print("2 - Find calendar item by event name")
  # Checks if input is an integer 1-2
  while True:
    try: 
      user_input = int(input("Choose your option: "))
      if (user_input > 2) or (user_input < 1):
        raise ValueError
      break
    except ValueError: 
      print("Choose 1 to find by date or 2 to find by event name.")
    if user_input == 1:
      find_item_by_date(cal)
    if user_input == 2:
      item_name = find_item_by_name(cal)

我可以看到上述块存在以下问题:

冗余注释、冗余括号、使用while循环并向控制程序流抛出异常,将输入转换为整数(您不做任何数学计算,因此实际上不需要将其转换为整数)并使用未使用的变量(item_name = find_item...)进行赋值。

我会这样做的:

代码语言:javascript
复制
def find_calendar_item(cal):
    print("1 - Find calendar item by date")
    print("2 - Find calendar item by event name")
    print("Any other key returns to previous function.")
    user_input = input("Choose your option: ")
    if user_input in ("1", "2"):
        find_item_by_date(cal) if user_input == "1" else find_item_by_name(cal)

诚然,我实际上不会做最后一行,纯粹是因为它不清楚编码,但是它演示了三元的,并且可以以这种方式使用函数。

删除while循环,删除异常,不转换输入。如果按下任何其他键会发生什么(您应该相信您的用户知道他们是否按了正确的键--不要过度设计它--另外,因为他们必须按输入才能完成输入,如果他们确实按了其他的键,他们就有机会修复它)。

希望这会有帮助,祝你好运!

*代码是错误的:不是说错,而是没有以一种容易理解的方式表达指令。如果我无法阅读您的代码并理解您想要做的事情--那么您就浪费了编写代码的时间(显然,规则总是有例外,有时需要注释)。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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