【问题标题】:process data on user input处理用户输入的数据
【发布时间】:2017-12-26 19:40:57
【问题描述】:

我有一个场景,我上传一个文本文件,然后提供用户输入,然后根据用户输入进一步处理。

示例文件:

DOWN 07.09.2016 08:21:33 - 07.09.2016 08:23:33
UP   07.11.2016 09:41:07 - 09.11.2016 09:20:33
DOWN 09.11.2016 08:26:33 - 09.11.2016 08:46:33
UP   09.11.2016 08:23:33 - 09.11.2016 08:25:33
DOWN 09.11.2016 08:36:33 - 09.11.2016 08:41:33
DOWN 10.11.2016 08:36:33 - 10.11.2016 08:39:33

代码:

try:
    import Tkinter as Tk
    import tkFileDialog as fileDialog
except ImportError:
    import tkinter as Tk
    import tkinter.filedialog as fileDialog

import datetime



def read_data():
    '''
    Read data from file and convert to list with datetime
    which can be used to calculate time and display.
    '''
    global data

    filename = fileDialog.askopenfilename()

    if filename:
        # read all lines
        with open(filename) as fileHandle:
            lines = fileHandle.readlines()

        # convert to `datetime` (not `timestamp`)
        data = []        
        for line in lines:
            #direction = line[:4].strip()
            #dt1 = line[5:24]
            #dt2 = line[27:46]

            direction, d1, t1, _, d2, t2 = line.split()
            dt1 = d1 + ' ' + t1
            dt2 = d2 + ' ' + t2 

            t1 = datetime.datetime.strptime(dt1, "%d.%m.%Y %H:%M:%S")
            t2 = datetime.datetime.strptime(dt2, "%d.%m.%Y %H:%M:%S")

            seconds = (t2-t1).seconds

            data.append([direction, t1, t2, seconds])

        print(data)


def processText(lines, selected_date):

    total = 0
    start = None

    print(selected_date)
    # if there is `selected_date` then convert to `datetime`
    if selected_date:
        try:
            selected_date = datetime.datetime.strptime(selected_date, "%d.%m.%Y")
        except AttributeError as ex:
            print("ERROR:", ex)
            selected_date = None

    # calculate time
    for direction, t1, t2, seconds in lines:

        if direction == "DOWN":

            # if `selected_date` then filter times
            if selected_date and t1 <= selected_date:
                continue

            if not start:
                start = t1.strftime("%d.%m.%Y %H:%M:%S")

            total += seconds

    # convert to minutes after summing all second
    total = total//60

    return total, start

def calculate():

    all_dates = entry.get().split(',')
    print(all_dates)
    all_dates = [date.strip() for date in all_dates]

    txt = ''

    for current_date in all_dates:
        down, start = processText(data, current_date)
        txt += "Total Downtime is {0} min from {1}\n".format(down, start)

    textVar.set(txt)

# --- main ---

data = None # to keep data from file

# -

root = Tk.Tk()

button = Tk.Button(root, text="Open", command=read_data)
button.grid(column=1, row=1)

textVar = Tk.StringVar(root)

label = Tk.Label(root, textvariable=textVar)
label.grid(column=1, row=2)

entry = Tk.Entry(root)
entry.grid(column=1, row=3)

button2 = Tk.Button(root, text="Calculate", command=calculate)
button2.grid(column=1, row=4)

root.mainloop()

上面的代码提示我选择 Date1.Month1.Year1,Date2.Month2.Year2 格式的日期...(取决于日期的数字输入。)

并将输出返回为:

 Total Downtime is x min from date1.month1.year1 xx:xx:xx(time1)
 Total Downtime is y min from date2.month2.year2 yy:yy:yy(time2)

这里我有停机时间的详细信息(以分钟为单位),我想将其转换为截至日期的百分比。例如 ->

用户输入:

1.9.2016,1.11.2016,1.1.2016

输出:

 Total Downtime is 30 min from 1.9.2016 08:21:33 & Availability percentage from selected date to till date : xx.xxx% 
 Total Downtime is 28 min from 1.11.2016 08:26:33 & Availability percentage from selected date to till date : yy.yyy%
 Total Downtime is 30 min from 1.11.2016 08:26:33 & Availability percentage from selected date to till date : zz.zzz%

可用性计算背后的逻辑是

total number of min down from date(which is retrieved)/total number of min till date * 100

我被困在这部分,这可以实现吗?任何帮助都会很棒!

【问题讨论】:

  • 是的,它可以实现 - 您必须先添加所有分钟数。增加分钟数有问题吗?顺便说一句:如果你用None 而不是selected_date 执行processText(),那么你会得到“所有分钟的总数”。然后你可以减去“从选定日期开始的总分钟数”得到“到选定日期的总分钟数”
  • 您应该提供a Minimal, Complete, and Verifiable example 而不是整个代码。
  • 是的,我不知道我应该如何继续获取到所选日期的总分钟数。

标签: python python-3.x python-2.7 tkinter


【解决方案1】:

如果您使用None 而不是日期运行processText(),那么您会得到它关闭时的总分钟数

total_down, start = processText(data, None)

你可以用它来计算百分比。

percentage = (down/total_down) * 100

您可以使用字符串格式{:.2f} 在点后仅显示两位数

def calculate():

    all_dates = entry.get().split(',')
    print(all_dates)
    all_dates = [date.strip() for date in all_dates]

    # calculate total number of minutes when it was down
    total_down, start = processText(data, None) # <-- None

    print('total_down:', total_down)

    txt = ''

    for current_date in all_dates:
        down, start = processText(data, current_date)

        # calculate percetage
        percentage = (down/total_down) * 100

        # use string formatting {:.2f} to display only two digits after dot
        txt += "Total Downtime is {} min from {} ({:.2f}%)\n".format(down, start, percentage)

    textVar.set(txt)


如果您想要总分钟数,那么您必须更改processText 并添加新参数(即word),这将检查directionDOWN 还是UP或两者兼有 (word = None)

def processText(lines, selected_date, word="DOWN"):

    total = 0
    start = None

    print(selected_date)
    # if there is `selected_date` then convert to `datetime`
    if selected_date:
        try:
            selected_date = datetime.datetime.strptime(selected_date, "%d.%m.%Y")
        except AttributeError as ex:
            print("ERROR:", ex)
            selected_date = None

    # calculate time
    for direction, t1, t2, seconds in lines:

        if not word or word == direction:

            # if `selected_date` then filter times
            if selected_date and t1 <= selected_date:
                continue

            if not start:
                start = t1.strftime("%d.%m.%Y %H:%M:%S")

            total += seconds

    # convert to minutes after summing all second
    total = total//60

    return total, start

def calculate():

    all_dates = entry.get().split(',')
    print(all_dates)
    all_dates = [date.strip() for date in all_dates]

    # calculate total number of minutes when it was down and up
    total_down, start = processText(data, None, None)

    print('total_down:', total_down)

    txt = ''

    for current_date in all_dates:
        down, start = processText(data, current_date, "DOWN")
        percentage = (down/total_down) * 100
        txt += "Total Downtime is {} min from {} ({:.2f}%)\n".format(down, start, percentage)

    textVar.set(txt)

【讨论】:

  • 查看代码 - 它计算total_down,然后使用此值计算percentage,并使用{:.2f} 以点后两位数显示百分比。
  • 这里我选择了日期 > 12.9.2016 这提供了 2.07% 的停机时间,但根据计算逻辑它应该提供 99.07%
  • 您附上的屏幕截图是第二个答案还是第一个答案?
  • 第一个版本的截图 - 所以我把它放在第一个代码之后。
  • 第二个版本计算上下的总分钟数 - 所以它给出的值较小。但是如果你在total_down, start = processText(data, None, "DOWN") 中使用单词“DOWN”,那么你可以获得相同的结果。第二个版本更通用,如果您还想计算它的 UP 时间,它会很有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多