0

I need to count the the different IDENTIFIERS and print a number count for the them. The information comes from a data stream that looks like this:

                             IDENTIFIER
7756753.940 receivetest: m s 0x0000069a 8 00 00 00 00 00 e4 8a 9a 
7756754.409 receivetest: m s 0x00000663 8 2f 00 62 02 00 e4 8a 9a 
7756754.878 receivetest: m s 0x0000069e 8 00 1f 5e 28 34 83 59 1a 
7756755.348 receivetest: m s 0x00000690 8 00 18 00 28 34 83 59 1a 
7756853.908 receivetest: m s 0x0000069a 8 00 00 00 00 00 e4 8a 9a 
7756854.377 receivetest: m s 0x0000069e 8 00 1f 5e 28 34 83 59 1a 
7756854.846 receivetest: m s 0x00000663 8 2f 00 62 02 00 e4 8a 9a 
7756855.316 receivetest: m s 0x00000690 8 00 18 00 28 34 83 59 1a 
7756953.961 receivetest: m s 0x0000069a 8 00 00 00 00 00 e4 8a 9a 
7756954.430 receivetest: m s 0x00000663 8 2f 00 62 02 00 e4 8a 9a 
7756954.857 receivetest: m s 0x0000069e 8 00 1f 5e 28 34 83 59 1a 
7756955.326 receivetest: m s 0x00000690 8 00 18 00 28 34 83 59 1a 
7757053.929 receivetest: m s 0x0000069a 8 00 00 00 00 00 e4 8a 9a 
7757054.398 receivetest: m s 0x00000663 8 2f 00 62 02 00 e4 8a 9a 
7757054.868 receivetest: m s 0x0000069e 8 00 1f 5e 28 34 83 59 1a 
7757055.337 receivetest: m s 0x00000690 8 00 18 00 28 34 83 59 1a 
7757153.940 receivetest: m s 0x0000069a 8 00 00 00 00 00 e4 8a 9a 
7757154.409 receivetest: m s 0x00000663 8 2f 00 62 02 00 e4 8a 9a 
7757154.878 receivetest: m s 0x0000069e 8 00 1f 5e 28 34 83 59 1a 
7757155.348 receivetest: m s 0x00000690 8 00 18 00 28 34 83 59 1a 
7757227.369 receivetest: m s 0x00000688 8 00 00 00 00 00 00 00 00 

Here is my code:

#!/usr/bin/python

import subprocess
import re, os, pprint

DICT = {}

def RECEIVE(COMMAND):
    PROCESS = subprocess.Popen(COMMAND, stdout=subprocess.PIPE)
    LINES = iter(PROCESS.stdout.readline, "")
    for LINE in LINES:
        if re.match(r"^\d+.*$",LINE):
            SPLITLINE = LINE.split()
            del SPLITLINE[1:4]
            TIMER = SPLITLINE[0]
            IDENTIFIER = SPLITLINE[1]
            DLC = SPLITLINE[2]
            HEXBITS = SPLITLINE[3:]
            COUNTER = DICT.count(IDENTIFIER)
            DICT[IDENTIFIER] = [DLC, HEXBITS, TIMER[6:], COUNTER]
            for IDENTIFIER, HEXBITS in DICT.items():
                os.system("clear")
                pprint.pprint(DICT)

RECEIVE(["receivetest", "-f=/dev/pcan33"])

I just need to print the number of times any given IDENTIFIER has been read

Jalcock501
  • 389
  • 2
  • 6
  • 18
  • 3
    And what's the problem? Does the code not work? Any errors? – matsjoyce Dec 23 '14 at 15:57
  • 4
    Please use [_Python_ code style](http://dinsdale.python.org/dev/peps/pep-0008/) don't use capitalized words for variables and method names – rook Dec 23 '14 at 16:00
  • the counter does not count the number of times each indiviudal identifier has been read, if doesn't display anything at all when printed either – Jalcock501 Dec 23 '14 at 16:03
  • You want the total number of times, or a running counter that updates on each reception? – xtofl Dec 23 '14 at 16:03
  • I'm surprised this isn't throwing errors when you try to run it. I don't think `count` is a viable method for Python dictionaries. – rchang Dec 23 '14 at 16:05
  • a counter that updates with each reception – Jalcock501 Dec 23 '14 at 16:07

4 Answers4

3

You could use collections.Counter, but a collections.defaultdict will be sufficient for this case:

from collections import defaultdict

def RECEIVE(COMMAND):
    counts = defaultdict(int)

    # <your code>
    IDENTIFIER = SPLITLINE[1]
    counts[IDENTIFIER] += 1
    # <rest of your code>

    # <whenever you want to see how many times some identifier has appeared>
    print(counts[SOME_IDENTIFIER])
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • this is fine if I wanted a count for one identifier but I want a count for each – Jalcock501 Dec 23 '14 at 16:05
  • This would maintain the number of times each identifier has occurred. You can query any identifier of your choice, and it will print how many times that identifier has occurred. If that identifier has not occurred at all, a `0` will be printed – inspectorG4dget Dec 23 '14 at 16:07
  • 1
    @Jalcock501 When all your input is done coming in, do something like `for (id, count) in counts.items(): print(id, count)` (I'm inferring from your code you're in Python 3.x?) – rchang Dec 23 '14 at 16:09
  • @rchang the input never stops it is a constant stream and no python 2.7.3 – Jalcock501 Dec 23 '14 at 16:14
1

You could, of course, use simple gnu tools like

receivetest -f=/dev/pcan33 | cut -f 5 | uniq | wc -l

But if you insist on using python...

identifiers = set(line.split()[4] for line in lines)
xtofl
  • 40,723
  • 12
  • 105
  • 192
0

If you just want a dictionary to count objects you could do something like this:

id_count = {}
def recieve():
    # insert your subprocess and read here, change the loop
    for line in identifiers.split('\n'):
    if re.match(r"^\d+.*$",line):
        identifier = line.split()[4]
        if identifier in id_count.keys():
            id_count[identifier] += 1
        else:
            id_count[identifier] = 1

afterwards you can print or access the dict to see how many times you received each identifier

joeButler
  • 1,643
  • 1
  • 20
  • 41
0
>>> DICT = {}
>>> for LINE in LINES:
...   SPLITLINE = LINE.split()
...   try:
...      DICT[SPLITLINE[4]] = DICT[SPLITLINE[4]] + 1
...   except:
...      DICT[SPLITLINE[4]] = 1
... 
>>> DICT
{'0x0000069a': 5, '0x00000690': 5, '0x00000688': 1, '0x00000663': 5, '0x0000069e': 5}
Vivek Sable
  • 9,938
  • 3
  • 40
  • 56