I am at my Wits end!

Hi all,

Just cannot get this to work… all i want it to do is print a single cell on top of the table where the searched IP address is located. No matter how hard i look or what table module i use i just cannot get it to do it.

I think this has aged me 5 years trying to figure it out. :face_with_symbols_over_mouth: :face_with_symbols_over_mouth:

Here is my code:

import sys
import argparse
import ipaddress
from scapy.all import *
from tabulate import tabulate
import tabulate_cell_merger.tabulate_cell_merger

def merge(clients, status):
    merged_list = tuple(zip(clients, status))
    return merged_list


parser = argparse.ArgumentParser()
parser.add_argument("IP", help = """Insert the address you want to check.
                    Use CIDR for a subnet""") #IP is the vaiable where the CLI input is stored
parser.add_argument("-v", "--verbosity", required = False, action = "count",
                    help = "Increase the output verbosity") #Changes the amount of data shown
args = parser.parse_args()
ip_add = args.IP

try:
    if "/" in ip_add:
        ipaddress.ip_network(ip_add, strict=False)
        print("This is a Valid CIDR address.... Processing!")
    else:
        ipaddress.ip_address(ip_add)
        print("This is a Valid IP address..... Processing!")
except ValueError:
    print("You did not enter a vaild IP or CIDR address")
    sys.exit(0)

ip = Net(ip_add)
ip_list = []
clients = []
status = []
    
verb = False
if args.verbosity == None:
    verb = False
elif args.verbosity > 0:
    verb = True
    
for add in ip:
    ip_list.append(add)

for ips in ip_list:
    pac = Ether(dst = "ff:ff:ff:ff:ff:ff")/IP(dst=ips)/ICMP()
    ans = srp1(pac,timeout=0.5, verbose = verb)
    
    if ans is None:
        clients.append(ips)
        status.append("down")
    else:
        clients.append(ips)
        status.append("up")
        
header = [ip_add]
table = merge(clients, status)
colspan = {(0,1):2}
with open('My_file.txt', "w") as f:
    f.write(tabulate(table, header, tablefmt = "pretty"))
print('Done')

I
Just
Want
The
IP
In
Its
Single
Cell
Centred!! :sob:

image
This is not what i want!

Please help before my head explodes!!!

Is this scrapy?

Edit: Yeah I googled. Sorry for wasting the space.

Lol all good

You are at Witt’s End. Don’t go west.

As a general rule, I would recommend isolating the problem. In this example it would appear that the issue is all about formatting using the tabulate module, so try creating a script that JUST generates the table (and prints it out - no need to use a file here). To be sure you’re passing it the right data, you can print out the parameters to tabulate() just before you call it.

But what you’re looking for here is usually called “column spanning” or “cell spanning”. Unfortunately, a cursory look through the docs and code for the tabulate package didn’t show up any way of doing that, so it might not be possible.

3 Likes

The prettytable package looks like it can do what you want:

from prettytable import PrettyTable

table = PrettyTable()
table.header = False
table.title = "QWERTY"
table.add_row([1, 2])
table.add_row([3, 4])
print(table)

Output:

+---------+
|  QWERTY |
+----+----+
| 1  | 2  |
| 3  | 4  |
+----+----+

Thank you Alexander that is what I am looking for. Once my blood pressure has dropped I will try it out.

:relaxed:

1 Like

Ok so that was a lot easier than I was making it out to be…

from prettytable import PrettyTable

columns = ["IP", "STATUS"]
title = 'IP ADDRESS'
list_ip  = []
list_status = []
a_var = 1
b_var = 1

for i in range(10):
    b_var = b_var + 1
    a_var = b_var*3 + 1
    list_ip.append(b_var)
    list_status.append(a_var)

table = PrettyTable()
table.title = title
table.header = False
table.padding_width = 2
table.add_column(columns[0], list_ip)
table.add_column(columns[1], list_status)
print(table)

Any recommendations?

The usual style in Python is to use UPPERCASE for constants. When you want to set the table attributes just once, set them during the object creation:

table = PrettyTable(title=TITLE, header=False, padding_width=2)
table.add_column(COLUMNS[0], list_ip)
table.add_column(COLUMNS[1], list_status)
print(table)
1 Like

Thanks Vaclav I didn’t know you could place it there. Looks much neater. :blush:

Note that this way of initializing the object’s attributes is not automatically available. It is not just a different way of placing the settings of the attributes.

Normally you should check the documentation to see which arguments are accepted by the constructor or in the source code check the __init__() method of the class. The arguments are passed to that method.

See object.__init__() for details.

1 Like