4

I have a dictionary as follows (dict is named channel_info):

{'flume02': u'98.94420000000001', 'flume03': u'32.562999999999995', 'flume01': u'2.15'}

Im trying to loop through the dictionary and report back the values a warning or critical. I have to arguments to the program

parser.add_argument('-w', '--warning', type=int, help='Warning threshold', default=85)
parser.add_argument('-c', '--critical', type=int, help='Critical threshold', default=95)

so basically when i run the program like myprog.py -w 80 -c 90, i want flume02 as critical( in this case that would be the only output). If any other key had a value greater than 80 or 90 they would be reported as warning or critical respectively.

However this is not the case and I get all the values under critical.

Relevant code:

    if args.warning and not args.critical:
        for each in channel_info.items():
            if float(each[1]) > float(args.warning):
                print 'WARNING | {} is {} percent full'.format(*each)
        exit(1)

    if args.critical and not args.warning:
        for each in channel_info.items():
            if float(each[1]) > float(args.critical):
                print 'CRITICAL | {} is {} percent full'.format(*each)
        exit(2)

    if args.warning and args.critical:
        for each in channel_info.items():
            if float(args.warning) < each[1] < float(args.critical):
                print 'WARNING | {} is {} percent full'.format(*each)
            elif each[1] > float(args.critical):
                print 'CRITICAL | {} is {} percent full'.format(*each)

Output:

CRITICAL | flume02 is 99.9892 percent full
CRITICAL | flume03 is 51.4497 percent full
CRITICAL | flume01 is 7.95 percent full

I put if the last if condition (if args.warning and args.critical) so to make sure that the program is able to run with either 1 ( -w or -c) or both arguments. Any help with what im doing wrong will be greatly appreciated

letsc
  • 2,515
  • 5
  • 35
  • 54
  • just a clarification. do you have problems only with the warning/critical combo **-w 80 -c 90**, i,e. the 3rd branch? do **-w 80** and **-c 90** by themselves work correctly? also, fwiw, you can take the float(args) out of the loop - faster, and also gives you the opportunity to print what is ending up in it – JL Peyret Aug 12 '15 at 17:11
  • We don't know what `channel_info` looks like so it's hard to tell. My question is why do you always compare to `each[1]`? I don't think you are iterating through your data properly. Add a couple prints of the values you are testing to be sure... – pedwards Aug 12 '15 at 17:13
  • if i do just -w 80 I get all the values which are above 80. However if i do -c 80, the values are still tagged as warning – letsc Aug 12 '15 at 17:13
  • @pedwards - channel_info is the dict is posted at the start of the question – letsc Aug 12 '15 at 17:14
  • What's bothering me is you are using `print` as in python2 but iterate through dict as if you are using python3. Which version are you using? – Lim H. Aug 12 '15 at 17:22
  • @letsc okay in python2 you should be using `iteritems` instead of `items` to iterate over a dict. – Lim H. Aug 12 '15 at 17:35
  • @Lim. What are you talking about? items works perfectly well, whether you need an iterator or not depends on data volume, not on 2.x. Just like the print vs print() thingy & 2x vs 3x is immaterial to his code not working. Python 2x and 3x are not very different at all - the syntaxical incompatibility on some items makes it seem that way, but they have the same apis 95%+ of the time and the same behavior 99%+ of the time when the apis match. – JL Peyret Aug 12 '15 at 17:39
  • @JLPeyret well that's fair enough. What I'm saying is I hardly see python2 code with `.items` when consuming a dictionary content without the intention to preserve the value. But yes you are right; it's highly irrelevant in this case. I don't know why it jumped out for me on first reading. – Lim H. Aug 12 '15 at 17:43
  • @LimH. Sorry to get on your case. It's just that... I am still on 2.7 myself and a bit leery to go to 3 till a lot more of the various 3rd party libraries work on 3. Anything that makes 3 look too much of a leap from 2 is therefore a bit against my interests (and, yes, I realize I am myself part of the problem). Thankfully, I've come to realize that, with things like using print(x) in 2.7 and various small adjustments then it is **not** such a big deal, most of the time. A number of packages now work on 2 and 3, Django among others. – JL Peyret Aug 12 '15 at 18:10
  • speaking of the above 2vs3 concerns, I wonder if SO would benefit from a Python2vs3 or somesuch **tag**. We have all sorts of Python-xyz tags, we have a Python-2.7, Python-3x tags. Wouldn't it be nice to have a tag specifically concerning 2.7-vs-3x considerations? For example, for folks who want to use a common codeline to support both? More exactly, would Python, rather than SO proper, benefit from that? – JL Peyret Aug 12 '15 at 18:17

2 Answers2

1

I think you forgot the float(each[1]) on branch #3. i.e. comparing string to float.

All the more reason to format your comparison values only once rather than do a float(xyz) each time.

threshold_crit = 90.0
threshold_warn = 80.0

for each in channel_info.items():
    # value = float(each[1])
    value = each[1]

    if threshold_crit < value < threshold_warn:
        print 'WARNING | {} is {} percent full'.format(*each)
    elif value > threshold_crit:
        print 'CRITICAL | {} is {} percent full'.format(*each)

output:

 CRITICAL | flume02 is 98.94420000000001 percent full
 CRITICAL | flume03 is 32.562999999999995 percent full
 CRITICAL | flume01 is 2.15 percent full

change code to:

    value = float(each[1])
    #value = each[1]

output:

 CRITICAL | flume02 is 98.94420000000001 percent full
JL Peyret
  • 10,917
  • 2
  • 54
  • 73
0

Solved it. Turns out there were two issues

  1. as JL Peyret pinted out I was missing the float.
  2. however the main issue of -c not working stand alone was the fact that both arguments had default values and when i used only -c , the fist if statement was being executed (because there IS a value and it was amounting to true) and all values were being tagged as warning
Community
  • 1
  • 1
letsc
  • 2,515
  • 5
  • 35
  • 54
  • 1
    you know, you can also probably simplify your logic by using argparse/optparse to assign a very high default value to crit and warning. like, i dunno, 99999999.99. that way, the checks will always go fail unless you actually enter the option. it would also make sense to check critical > warning. and do a **continue** on the 3rd branch if you hit critical - that way you don't also flag the entry as warning. – JL Peyret Aug 12 '15 at 17:27
  • Yeah ive just added the check to exit out if warn > crit – letsc Aug 12 '15 at 17:31