Statistics for an Athletic Association

20180921_Codewars_stat_CAA

Posted by Huiyang_Lu on September 21, 2018

Statistics for an Athletic Association

Codewars Kata 13√

Description

Link: stat_CAA

-简述:本题以时|分|秒的数字形式给定一系列长跑运动员的时间成绩,求出其范围、平均值和中位数。
-思路:将数字形式转换为具体时间,求range average medium,然后再将他们转换为数字形式。
-难点:1 format中数字的表达形式

You are the “computer expert” of a local Athletic Association (C.A.A.). Many teams of runners come to compete. Each time you get a string of all race results of every team who has run. For example here is a string showing the individual results of a team of 5 runners:

“01 15 59, 1 47 6, 01 17 20, 1 32 34, 2 3 17”
Each part of the string is of the form: h m s where h, m, s (h for hour, m for minutes, s for seconds) are positive or null integer (represented as strings) with one or two digits. There are no traps in this format.

To compare the results of the teams you are asked for giving three statistics; range, average and median.

Range : difference between the lowest and highest values. In {4, 6, 9, 3, 7} the lowest value is 3, and the highest is 9, so the range is 9 − 3 = 6.

Mean or Average : To calculate mean, add together all of the numbers in a set and then divide the sum by the total count of numbers.

Median : In statistics, the median is the number separating the higher half of a data sample from the lower half. The median of a finite list of numbers can be found by arranging all the observations from lowest value to highest value and picking the middle one (e.g., the median of {3, 3, 5, 9, 11} is 5) when there is an odd number of observations. If there is an even number of observations, then there is no single middle value; the median is then defined to be the mean of the two middle values (the median of {3, 5, 6, 9} is (5 + 6) / 2 = 5.5).

Your task is to return a string giving these 3 values. For the example given above, the string result will be

“Range: 00|47|18 Average: 01|35|15 Median: 01|32|34”of the form: “Range: hh|mm|ss Average: hh|mm|ss Median: hh|mm|ss” where hh, mm, ss are integers (represented by strings) with each 2 digits.

Remarks: if a result in seconds is ab.xy… it will be given truncated as ab. if the given string is “” you will return “”

My solution
def changetoHMS(x):
    h1 = int(x // 3600)
    m1 = int((x - 3600 * h1) // 60)
    s1 = int(x - 3600 * h1 - 60 * m1)
    return ' {h1:02d}|{m1:02d}|{s1:02d}'.format(**locals())

def changetoTime(str):
    b1 = str.split('|')
    return int(b1[0]) * 3600 + int(b1[1]) * 60 + int(b1[2])

def getMedium(lst):
    l = len(lst)
    lst.sort()
    if l % 2 == 0:
        return (lst[l // 2] + lst[l // 2 - 1]) / 2
    else:
        return lst[l // 2]

def stat(strg):
    if strg =='':
        return ''
    else:
        s = strg.split(',')
        lst = []
        for i in range(0,len(s)):
            lst.append(changetoTime(s[i]))
        avgr = changetoHMS(sum(lst)//len(lst))
        rger = changetoHMS(max(lst)-min(lst))
        medr = changetoHMS(getMedium(lst))
        return 'Range:{rger} Average:{avgr} Median:{medr}'.format(**locals())

print(stat("01|15|59, 1|47|16, 01|17|20, 1|32|34, 2|17|17"))
Given solutions
def stat(strg):

    def get_time(s):
        '''Returns the time, in seconds, represented by s.'''
        hh, mm, ss = [int(v) for v in s.split('|')]
        return hh * 3600 + mm * 60 + ss

    def format_time(time):
        '''Returns the given time as a string in the form "hh|mm|ss".'''
        hh = time // 3600
        mm = time // 60 % 60
        ss = time % 60
        return '{hh:02d}|{mm:02d}|{ss:02d}'.format(**locals())

    def get_range(times):
        return times[-1] - times[0]

    def get_average(times):
        return sum(times) // len(times)

    def get_median(times):
        middle = len(times) >> 1
        return (times[middle] if len(times) & 1 else
                (times[middle - 1] + times[middle]) // 2)

    if strg == '':
        return strg
    times = [get_time(s) for s in strg.split(', ')]
    times.sort()
    rng = format_time(get_range(times))
    avg = format_time(get_average(times))
    mdn = format_time(get_median(times))
    return 'Range: {rng} Average: {avg} Median: {mdn}'.format(**locals())
Points

1 报错 ValueError: Unknown format code ‘d’ for object of type ‘float’ 加入format中的参数不是整数,float无法用d表示。

2 format()函数讲解:format()

3 运行时出现以下错误:TypeError: ‘int’ object is not callable 报错处前面定义了一个与函数同名的变量,后期再遇到该函数时,则会报错。将变量改名即可。