Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting a log analysis script from Python to Nim

Tags:

nim-lang

Nim looks (very) close to Python, but I am still having a hard time translating the following script:

import sys

months = { "Jan": 1, "Feb": 2, "Mar": 3, "Apr": 4, "May": 5, "Jun": 6,
           "Jul": 7, "Aug": 8, "Sep": 9, "Oct": 10, "Nov": 11, "Dec": 12 }

months_r = { v:k for k,v in months.items() }

totals = {}

for line in sys.stdin:
    if "redis" in line and "Partial" in line:
        f1, f2 = line.split()[:2]
        w = (months[f1], int(f2))
        totals[w] = totals.get(w, 0) + 1

for k in sorted(totals.keys()):
    print(months_r[k[0]], k[1], totals[k])

Even after reading the Manual for a few hours, I am still unsure about tuples and the way to convert the month names back and forth (my attempts with a table have failed, I did not manage to access the table like it is done in Python).

Any help will be greatly appreciated.

Thanks

like image 620
user15795022 Avatar asked Nov 18 '25 02:11

user15795022


2 Answers

Just being silly now, but I couldn't leave this alone without refactoring it to use an enum instead of the month tables

import tables, strutils, algorithm,sequtils

type Month = enum Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec

var totals: CountTable[(Month, int)]

for line in stdin.lines:
  if "redis" in line and "Partial" in line:
        let flds = line.split()
        inc totals,(flds[0].parseEnum[:Month], flds[1].parseInt)

for k in toSeq(totals.keys).sorted:
    echo k[0], " ", k[1], " ", totals[k]

Edit: had to nick @xbello's solution using the CountTable, too good.

like image 132
shirleyquirk Avatar answered Nov 20 '25 18:11

shirleyquirk


I don't have good news. Nim code is lot longer then python code, but anyway here is my implementation, eventhough i do not understand what your program should do.

import tables, strutils, os, parseutils, algorithm

var months = {"Jan": 1, "Feb": 2, "Mar": 3, "Apr": 4, "May": 5, "Jun": 6,
        "Jul": 7, "Aug": 8, "Sep": 9, "Oct": 10, "Nov": 11, "Dec": 12}.toTable

var invertedMonths: Table[int, string]

for k, v in months:
    invertedMonths[v] = k

var totals: Table[(int, int), int]

while true:
    let line = readLine(stdin)
    if line.strip == "": break
    if "redis" in line and "Partial" in line:
        let args = line.split()
        let w = (months[args[0]], parseInt(args[1]))
        totals[w] = totals.getOrDefault(w, 0) + 1

var keys = newSeq[(int, int)](totals.len)

keys.setLen(0)

for k in totals.keys():
    keys.add(k)

# i have no idea how python would sort this
keys.sort(proc(a, b: (int, int)): int =
    a[0] + a[1] - b[0] - b[1]
)

for k in keys:
    echo invertedMonths[k[0]], " ", k[1], " ", totals[k]

edit

After some advice is restructures code as follows and length looks lot better now.

import tables, strutils, algorithm, sequtils

var months = {"Jan": 1, "Feb": 2, "Mar": 3, "Apr": 4, "May": 5, "Jun": 6,
        "Jul": 7, "Aug": 8, "Sep": 9, "Oct": 10, "Nov": 11, "Dec": 12}.toTable

var invertedMonths: Table[int, string]

for k, v in months: invertedMonths[v] = k

var totals: Table[(int, int), int]

for line in stdin.lines:
    if line.strip == "": break
    if "redis" in line and "Partial" in line:
        let args = line.split()
        let w = (months[args[0]], parseInt(args[1]))
        totals[w] = totals.getOrDefault(w, 0) + 1

for k in toSeq(totals.keys).sorted:
    echo invertedMonths[k[0]], " ", k[1], " ", totals[k]
like image 29
Jakub Dóka Avatar answered Nov 20 '25 17:11

Jakub Dóka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!