Home > database >  How should I solve logic error in timestamp using Python?
How should I solve logic error in timestamp using Python?

Time:09-22

I have written a code to calculate a, b, and c. They were initialized at 0. This is my input file

-------------------------------------------------------------
| Line          | Time |     Command    |      Data         |
-------------------------------------------------------------
| 1             | 0015 | ACTIVE         |                   |
| 2             | 0030 | WRITING        |                   |
| 3             | 0100 | WRITING_A      |                   |
| 4             | 0115 | PRECHARGE      |                   |
| 5             | 0120 | REFRESH        |                   |
| 6             | 0150 | ACTIVE         |                   |
| 7             | 0200 | WRITING        |                   |
| 8             | 0314 | PRECHARGE      |                   |
| 9             | 0318 | ACTIVE         |                   |
| 10            | 0345 | WRITING_A      |                   |
| 11            | 0430 | WRITING_A      |                   |
| 12            | 0447 | WRITING        |                   |
| 13            | 0503 | WRITING        |                   |

and the timestamps and commands are used to process the calculation for a, b, and c.

import re
count = {}
timestamps = {}
with open ("page_stats.txt", "r") as f:
    for line in f:
        m = re.split(r"\s*\|\s*", line)
        if len(m) > 3 and re.match(r"\d ", m[1]):
            count[m[3]] = count[m[3]]   1 if m[3] in count else 1
            #print(m[2])
            if m[3] in timestamps:
                timestamps[m[3]].append(m[2])
                #print(m[3], m[2])
            else:
                timestamps[m[3]] = [m[2]]
                #print(m[3], m[2])
    
a = b = c = 0
for key in count:
    print("%-10s: -, %s" % (key, count[key], timestamps[key]))
    if timestamps["ACTIVE"] > timestamps["PRECHARGE"]: #line causing logic error
        a = a   1
print(a)

Before getting into the calculation, I assign the timestamps with respect to the commands. This is the output for this section.

ACTIVE    :  3, ['0015', '0150', '0318']
WRITING   :  4, ['0030', '0200', '0447', '0503']
WRITING_A :  3, ['0100', '0345', '0430']
PRECHARGE :  2, ['0115', '0314']
REFRESH   :  1, ['0120']

To get a, the timestamps of ACTIVE must be greater than PRECHARGE and WRITING must be greater than ACTIVE. (Line 4, 6, 7 will contribute to the first a and Line 8, 9, and 12 contributes to the second a)

To get b, the timestamps of WRITING must be greater than ACTIVE. For the lines that contribute to a such as Line 4, 6, 7, 8, 9, and 12, they cannot be used to calculate b. So, Line 1 and 2 contribute to b.

To get c, the rest of the unused lines containing WRITING will contribute to c.

The expected output:

a = 2
b = 1
c = 1

However, in my code, when I print a, it displays 0, which shows the logic has some error. Any suggestion to amend my code to achieve the goal? I have tried for a few days and the problem is not solved yet.

CodePudding user response:

I made a function that will return the commands in order that match a pattern with gaps allowed. I also made a more compact version of your file reading. There is probably a better version to divide the list into two parts, the problem was to only allow elements in that match the whole pattern. In this one I iterate over the elements twice.

import re
commands = list()
with open ("page_stats.txt", "r") as f:
    for line in f:
        m = re.split(r"\s*\|\s*", line)
        if len(m) > 3 and re.match(r"\d ", m[1]):
            _, line, time, command, data, _ = m
            commands.append((line,time,command))

def search_pattern(pattern, iterable, key=None):
    iter = 0
    count = 0
    length = len(pattern)
    results = []
    sentinel = object()
    
    for elem in iterable:
        original_elem = elem
        if key is not None:
            elem = key(elem)
        if elem == pattern[iter]:
            iter  = 1
            results.append((original_elem,sentinel))
            if iter >= length:
                iter = iter % length
                count  = length
        else:
            results.append((sentinel,original_elem))

    matching = []
    nonmatching = []
    for res in results:
        first,second = res
        if count > 0:
            if second is sentinel:
                matching.append(first)
                count -= 1
            elif first is sentinel:
                nonmatching.append(second)
        else:
            value = first if second is sentinel else second
            nonmatching.append(value)
    
    return matching, nonmatching
    
pattern_a = ['PRECHARGE','ACTIVE','WRITING']
pattern_b = ['ACTIVE','WRITING']
pattern_c = ['WRITING']
matching, nonmatching = search_pattern(pattern_a, commands, key=lambda t: t[2])
a = len(matching)//len(pattern_a)
matching, nonmatching = search_pattern(pattern_b, nonmatching, key=lambda t: t[2])
b = len(matching)//len(pattern_b)
matching, nonmatching = search_pattern(pattern_c, nonmatching, key=lambda t: t[2])
c = len(matching)//len(pattern_c)

print(f'{a=}')
print(f'{b=}')
print(f'{c=}')

Output:

a=2
b=1
c=1
  • Related