Format the output data - python

I'm a novice in programming. Faced with such a problem. Are monitoring servers using Zabbix. It has its own API. The challenge is through a script in Python to connect to the monitor server and get information about printers and their counters and put in the file. The output file should have the format:
name printer \tab counter printer
Like that:
HP1212 124512
I connect and receive data, but cannot record it in two columns using a '\t'.
My code:
`
from pyzabbix import ZabbixAPI
zapi = ZabbixAPI("http://*****/zabbix")
zapi.login("******", "*******")
item_name='Print_counter'
hosts = zapi.host.get( #get printers name
groupids=8,
output=['name'])
items = zapi.item.get( #get printers counter
groupids=8,
output=['lastvalue'],
filter={'name':item_name})`
I understand that the problem is likely trivial, but how to solve I don't know.
I edited my question:
If im use:
for host in hosts:
a = host['name']
print a
.. I get:
tpr001
tpr002
...
tpr020
it my printers.
If i use:
for item in items:
b = host['value']
print b
I get:
12456
34645
...
56468
It counters off my printers.
I want to group the output of my query like this:
tpr001 12456
tpr002 34645
... ...
tpr020 56468

I think you need something like this :
for host in hosts:
a=host['name']
for item in items:
b=item['lastvalue']
print a,'\t',b`

I do not know what exactly is given by your zapi.host.get and zapi.item.get, but your loops dont work, as you expect.
In your first loop a gets a new value in each cycle so you find the last value in it, if the loop ends. And because of your print command after the loop you see exact that value.
Maybe you should put second loop into the first like
for host in hosts:
a=host['name']
for item in items:
b=item['lastvalue']
print a,'\t',b`
But in this case you would combine each row from hosts with each row from items.
Maybe your items.get- command needs the name es filter, something like
for host in hosts:
a=host['name']
items = zapi.item.get( #get printers counter
groupids=8,
output=['lastvalue'],
filter={'name':a})
Maybe you even do not need to ask for hosts, because all your information are inside items
for item in items:
b=item['lastvalue']
a=item['name']
print a,'\t',b
Hope, this helps, but I think you should learn about basics in programming, if you want to go further (and it is easier to understand, if you give speaking names instead of a and b, so not only we better understand, what you expect

It sounds strange to me, that you want to rely on Output order of two different lists. But if so, you could try
for i in range(len(Hosts)):
host = Hosts[i]
item = Items[i]
a=host['name']
b=item['lastvalue']
print a,'\t',b

Related

Use generic keys in dictionary in Python

I am trying to name keys in my dictionary in a generic way because the name will be based on the data I get from a file. I am a new beginner to Python and I am not able to solve it, hope to get answer from u guys.
For example:
from collections import defaultdict
dic = defaultdict(dict)
dic = {}
if cycle = fergurson:
dic[cycle] = {}
if loop = mourinho:
a = 2
dic[cycle][loop] = {a}
Sorry if there is syntax error or any other mistake.
The variable fergurson and mourinho will be changing due to different files that I will import later on.
So I am expecting to see my output when i type :
dic[fergurson][mourinho]
the result will be:
>>>dic[fergurson][mourinho]
['2']
It will be done by using Python
Naming things, as they say, is one of the two hardest problems in Computer Science. That and cache invalidation and off-by-one errors.
Instead of focusing on what to call it now, think of how you're going to use the variable in your code a few lines down.
If you were to read code that was
for filename in directory_list:
print filename
It would be easy to presume that it is printing out a list of filenames
On the other hand, if the same code had different names
for a in b:
print a
it would be a lot less expressive as to what it is doing other than printing out a list of who knows what.
I know that this doesn't help what to call your 'dic' variable, but I hope that it gets you on the right track to find the right one for you.
i have found a way, if it is wrong please correct it
import re
dictionary={}
dsw = "I am a Geography teacher"
abc = "I am a clever student"
search = re.search(r'(?<=Geography )(.\w+)',dsw)
dictionary[search]={}
again = re.search(r'(?<=clever )(.\w+)' abc)
dictionary[search][again]={}
number = 56
dictionary[search][again]={number}
and so when you want to find your specific dictionary after running the program:
dictionary["teacher"]["student"]
you will get
>>>'56'
This is what i mean to

Python, Lists associated with each other

Im looking for thoughts on solving what im trying to achieve.
Im looking to do a dns query in python say for instance;
import adns
c=adns.init()
c.synchronous("www.google.com", adns.rr.A)
Im looking to store the output;
(0, 'www.l.google.com', 1167604334, ('216.239.37.99', '216.239.37.104'))
in a list, but the list would need to be associated with teh domain name.
So www.google.com would need to be associated with the common name and ip addresses. So if I had a list of domains they are all printed with their relevant data.
Can you have a list inside another list? Abit like a database i guess?
yep, a dict will do
data = []
domain = "www.google.com"
data[domain] = c.synchronous(domain, adns.rr.A)
print data

Python Struct Arrays

Currently working on some Python scripts to interact with the Spacwalk\Satellite API. I'm able to return one piece of an array I'm looking for, but not the rest. Below is the API call I'm making in my script. (key) is the session key to authenticate with the server.
duplicates = client.system.listDuplicatesByHostname(key)
Running my script will produce the following kind of output:
print duplicates
[{'hostname': 'host01', 'systems': [{'last_checkin': <DateTime '20131231T14:06:54' at 192a908>, 'systemName': 'host01.example.com', 'systemId': 1000011017}
I can pull out the 'hostname' field using something like this:
for duplicate in duplicates:
print 'Hostname: %s' % ( duplicate.get('hostname')
But I can't retrieve any of the other items. "systems" is apparently a separate array (nested?) within the first array. I'm unsure of how to reference that second "systems" array. The API reference says the output will be in this format:
Returns:
array:
struct - Duplicate Group
string "hostname"
array "systems"
struct - system
int "systemId"
string "systemName"
dateTime.iso8601 "last_checkin" - Last time server successfully checked in
I'm not sure how to pull out the other values such as systemID, systemName. Is this considered a tuple? How would I go about retrieving these values? (I'm very new to Python, I've read about "structs" but haven't found any examples that really made sense to me.) Not necessarily looking for an answer to this exact question, but anywhere someone could point me to examples that clearly explain how to work with these kinds of arrays would be most helpful!!
Inside of the for loop you will have a dictionary called duplicate that contains the keys 'hostname' and 'systems', so duplicate['hostname'] will get the hostname (a string) and duplicate['systems'] will get the systems array.
You can then access an individual element from that systesm array using indexing, for example duplicate['systems'][0] would get the first system. However what you probably want to be doing instead is create a loop like for system in duplicate['systems'], that way you can iterate over each system in order.
Each system you get will be a dictionary that has the keys 'systemId', 'systemName', and 'last_checkin'.
Here is what I imagine the full code might look like:
for duplicate in duplicates:
print 'Hostname: ' + duplicate['hostname']
for system in duplicate['systems']:
print 'System ID: ' + system['systemId']
print 'System Name: ' + system['systemName']
print 'Last Checkin: ' + system['last_checkin']
I would suggest taking a look at the data structures tutorial.
Thanks guys, the input provided helped me figure this out. I got the output I needed using the following:
for duplicate in duplicates:
print 'IP: ' + duplicate['ip']
for system in duplicate['systems']:
print 'SystemID: ', system['systemId'], 'Name: ', system['systemName']

Detect changes in an array and run command for new values

I have an array of IP's that changes from time to time and i want for every new IP that comes up to run a command.
The code I have is:
while (network.status!="connected"):
p=network.connections
for i in p:
print i.ip #checks the IP's in the array i
time.sleep(10)
So i want whenever there is a new value in the array i to run a specific command.
What's the most efficient way to do this in python.
Use a set and look at the difference in each loop:
old = set()
while network.status != "connected":
p = set(network.connections)
for i in p - old:
print i.ip # new ips that were added
for i in old - p:
print i.ip # old ips that were removed
old = p
time.sleep(10)
How about subclassing the list and connecting it to some handler?
Have a look here:
https://stackoverflow.com/a/12203829/1091116
What you want to do is to rename 'validate' and make it react to adding items in the list.

Help with Python loop weirdness?

I'm learning Python as my second programming language (my first real one if you don't count HTML/CSS/Javascript). I'm trying to build something useful as my first real application - an IRC bot that alerts people via SMS when certain things happen in the channel. Per a request by someone, I'm (trying) to build in scheduling preferences where people can choose not to get alerts from between hours X and Y of the day.
Anyways, here's the code I'm having trouble with:
db = open("db.csv")
for line in db:
row = line.split(",") # storing stuff in a CSV, reading out of it
recipient = row[0] # who the SMS is going to
s = row[1] # gets the first hour of the "no alert" time range
f = row[2] # gets last hour of above
nrt = [] # empty array that will store hours
curtime = time.strftime("%H") # current hour
if s == "no":
print "They always want alerts, sending email" # start time will = "no" if they always want alerts
# send mail code goes here
else:
for hour in range(int(s), int(f)): #takes start, end hours, loops through to get hours in between, stores them in the above list
nrt.append(hour)
if curtime in nrt: # best way I could find of doing this, probably a better way, like I said I'm new
print "They don't want an alert during the current hour, not sending" # <== what it says
else:
# they do want an alert during the current hour, send an email
# send mail code here
The only problem I'm having is somehow the script only ends up looping through one of the lines (or something like that) because I only get one result every time, even if I have more than one entry in the CSV file.
If this is a regular CSV file you should not try to parse it yourself. Use the standard library csv module.
Here is a short example from the docs:
import csv
reader = csv.reader(open("some.csv", "rb"))
for row in reader:
print row
There are at least two bugs in your program:
curtime = time.strftime("%H")
...
for hour in range(int(s), int(f)):
nrt.append(hour)
# this is an inefficient synonym for
# nrt = range(int(s), int(f))
if curtime in nrt:
...
First, curtime is a string, whereas nrt is a list of integers. Python is strongly typed, so the two are not interchangeable, and won't compare equal:
'4' == 4 # False
'4' in [3, 4, 5] # False
This revised code addresses that issue, and is also more efficient than generating a list and searching for the current hour in it:
cur_hour = time.localtime().tm_hour
if int(s) <= cur_hour < int(f):
# You can "chain" comparison operators in Python
# so that a op1 b op2 c is equivalent to a op1 b and b op2c
...
A second issue that the above does not address is that your program will not behave properly if the hours wrap around midnight (e.g. s = 22 and f = 8).
Neither of these problems are necessarily related to "the script only ends up looping through one of the lines", but you haven't given us enough information to figure out why that might be. A more useful way to ask questions is to post a brief but complete code snippet that shows the behavior you are observing, along with sample input and the resulting error messages, if any (along with traceback).
Have you tried something more simple? Just to see how your file is actually read by Python:
db = open("db.csv")
for line in db:
print line
There can be problem with format of your csv-file. That happens, for instance, when you open Unix file in Windows environment. In that case the whole file looks like single string as Windows and Unix have different line separators. So, I don't know certain cause of your problem, but offer to think in that direction.
Update:
Your have multiple ways through the body of your loop:
when s is "no": "They always want alerts, sending email" will be printed.
when s is not "no" and curtime in nrt: "They don't want an alert during the current hour, not sending" will be printed.
when s is not "no" and curtime in nrt is false (the last else): nothing will be printed and no other action undertaken.
Shouldn't you place some print statement in the last else branch?
Also, what is exact output of your snippet? Is it "They always want alerts, sending email"?
I would check the logic in your conditionals. You looping construct should work.
You could go thro an existing well written IRC bot in Python Download
Be explicit with what's in a row. Using 0, 1, 2...n is actually your bug, and it makes code very hard to read in the future for yourself or others. So let's use the handy tuple to show what we're expecting from a row. This sort of works like code as documentation
db = open("db.csv")
for line in db.readlines():
recipient, start_hour, end_hour = line.split(",")
nrt = []
etc...
This shows the reader of your code what you're expecting a line to contain, and it would have shown your bug to you the first time you ran it :)

Categories