Search code examples
pythonparsingnested-liststelnetlib

Optimization of code to avoid occasional error "ValueError: need more than 0 values to unpack"


I have a program where it connects to a remote system (running Linux) using a telnet connection and runs a binary, which prints some values. I use read_very_eager() to retrieve those values to a buffer and process them (calculate the average of the values basically). The following is my code :

import telnetlib
import time
import string

lpr=[]
lpr_s=[]
lpr_val=[]
lpr_agg=[]
lpr_sum=0
tn1 = telnetlib.Telnet("192.168.1.101")
print tn1.read_until("login: ")
print tn1.write("root1\n")
time.sleep(1)
print tn1.read_until("Password:")
print tn1.write("\n")
print tn1.write("\n")
print tn1.read_until("root1@dvf99:~$")
print tn1.write("su\n")
print tn1.read_until("root@dvf99:/home/root1")
print tn1.write("\n")
time.sleep(10)
print tn1.write("<binary_name>\n")
time.sleep(5)
buf=tn1.read_very_eager()
print buf
time.sleep(10)
buf=tn1.read_very_eager()
print buf
lpr=buf.splitlines()[:10]
print "splitlines :\n"+str(lpr)
for line in lpr:
    lpr_s.append([int(s) for s in line.split() if s.isdigit()])
print(lpr_s)
lpr_val,lpr_agg=zip(*lpr_s)
print(lpr_val)
print "\n"
print(lpr_agg)
for i in range(0,10):
lpr_sum+=lpr_val[i]
print(lpr_sum)
looper=lpr_sum/10
print "\nlooper="+str(looper)+"\n"
tn1.close()

Most of the times, I get output of the statement print(lpr_s) like :

[[46129, 461537], [46168, 507705], [46141, 553846], [46162, 600008], [46159, 646167], [46154, 692321], [46167, 738488], [46176, 784664], [46166, 830830], [46180, 877010]]

But some other times, I get output of the statement print(lpr_s) like :

[[], [46168, 1892467], [46157, 1938624], [46161, 1984785], [46178, 2030963], [46162, 2077125], [46166, 2123291], [46141, 2169432], [46172, 2215604], [46167, 2261771]]

Because of which I get the error ValueError: need more than 0 values to unpack at lpr_val,lpr_agg=zip(*lpr_s). Now, the challenge is I need to optimize the code with the constraint that the procedure should be the same - sleep for 5 seconds, leave the initial values, sleep for 10 seconds, collect 10 values and take their average. I suspect it is read_very_eager() the culprit here which causes the list being blank.

So, my questions are :

  1. Should I consider replacing read_very_eager() with a better solution that I'm not aware of yet?
  2. Should I just let read_very_eager() be and do something like checking for null values in the list and copy only the non-null values to another list? In this case I'm dealing with nested list (lists within a list). How do I get this done?

Solution

  • Why not just skip empty entries?

    for line in lpr:
        res = [int(s) for s in line.split() if s.isdigit()]
        if res:
            lpr_s.append(res)
    

    or if the line turns out empty (I suppose this is it):

    for line in lpr:
        if not line:
            continue
        lpr_s.append([int(s) for s in line.split() if s.isdigit()])