Where do I add in an re.search in this python code? - python

I have some python code to change the severities of incoming SNMP traps on the NMS I am using.
The incoming SNMP traps contain objects that are ranges of numbers for a given severity level. The below code works if the the incoming object numbers are singular, 1,2,3,4,5 etc. But it doesnt work for the below when trying to match a regex number range.
## This gets the alarmTrapSeverity function and creates a variable called Severity to hold the value
if getattr(evt, 'alarmTrapSeverity', None) is not None:
Severity = getattr(evt, 'alarmTrapSeverity')
## This part runs through the Severity to assign the correct value
if str(Severity) == '0':
evt.severity = 0
elif str(Severity) == '([1-9]|1[0-9])':
evt.severity = 1
Please could you advise the correct way to do this. My regex skills are still developing.

If I am understanding this correctly, in the else-if statement you would like to perform a regular expression search in order to confirm a match. My approach would look like this,
## This gets the alarmTrapSeverity function and creates a variable called
Severity to hold the value
if getattr(evt, 'alarmTrapSeverity', None) is not None:
Severity = getattr(evt, 'alarmTrapSeverity')
regex = re.compile(r'([1-9]|1[0-9])')
## This part runs through the Severity to assign the correct value
if str(Severity) == '0':
evt.severity = 0
elif regex.search(str(Severity)) != None:
evt.severity = 1
This would search the str(Severity) variable for a matching substring, which in this case would be the string containing numbers between 1-19. Then as long as it finds a match, sets evt.severity = 1.
Also, looking back at your question, if you were having issues with finding numbers between 1-19 with that regex, another example which works might be,
"10|1?[1-9]"

Related

Same input gives different output for a program

Novice programmer here. I am trying to write a program wherein it will take UIDs from user and validate them based on certain rules. The rules are:
It must contain at least 2 uppercase English alphabet characters.
It must contain at least 3 digits ( 0-9 ).
3.It should only contain alphanumeric characters (A -Z ,a -z & 0 -9 ).
No character should repeat.
There must be exactly characters in a valid UID.
I am putting in the code. Also apologies for this big code (I am a newbie)
# UID Validation
n=int(input()) #for iterations
uid=[]
# char=[]
valid=1
upper=0
numeric=0
# take input first of everycase
for x in range (0,n):
num=input()
uid.append(num)
# print (uid)
for i in uid:
# print (i)
# to count each word and number
count={}
for char in i:
count[char]=count.get(char,0)+1
for j in i:
if j.isupper():
upper=upper+1
elif j.isnumeric():
numeric=numeric+1
# print('numeric =', numeric)
# print('upper =', upper)
# Check conditions
while valid==1:
if len(i)!= 10:
valid= 0
# print('invalid for word count')
elif i.isalnum()== False: #alphanumeric
valid=0
# print('invalid for alnum')
elif upper<2: #minimum alphabet and numbers
valid=0
# print('invalid for min alphabet')
elif numeric<3:
valid=0
# print('invalid for min numeric')
else:
for k,v in count.items(): #no repitation
if v>1:
valid=0
# to check if given UID is valid or not
if valid==1:
print ('Valid')
elif valid==0:
print('Invalid')
valid=1
break
I have written the code but it seems that I am facing problem on one input only that is to check UID tag: 2TB1YVIGNM
It is an invalid tag. My program shows the same when is I run it alone or first in a batch of many. But, Lets say I run the program and input 2 tags, with "2TB1YVIGNM" being second one, it will show is as "Valid". Mind you, this is only happening in this particular tag
There are several other tags which run fine. Some of them are mentioned here:
77yS77UXtS
d72MJ4Rerf
OA778K96P2
2TB1YVIGNM "EXCEPT THIS TAG"
9JC86fM1L7
3w2F84OSw5
GOeGU49JDw
8428COZZ9C
WOPOX413H2
1h5dS6K3X8
Fq6FN44C6P
The output should be:
Invalid
Valid
Invalid
Invalid
Valid
Invalid
Invalid
Invalid
Invalid
Valid
Invalid
My output is this:
Invalid
Valid
Invalid
Valid
Valid
Invalid
Invalid
Invalid
Invalid
Valid
Invalid
To solve your problem you need to set upper and numeric back to 0 for each uid:
for i in uid:
upper = 0
numeric = 0
count={}
P.S: As for you newbie I would suggest you to read PEP 8 it will make your code more readable and prettier
P.S.S: There is no need to count manually how many times each character meet in string, such operation already implemented in Python look at the Counter for more details
And I agree with comment that for such type of tasks it is better to use regex
You could extract pieces of logic into functions and call them:
#It must contain at least 2 uppercase English alphabet characters.
def has_at_least_two_uppercase(potential_uid):
return sum([char.upper() == char for char in potential_uid])>= 2
#No character should repeat.
def has_unique_chars(potential_uid):
return len(set(potential_uid)) == len(potential_uid)
#There must be exactly characters in a valid UID.
def is_proper_length(potential_uid:str, proper_length:int = 10)-> bool:
return len(potential_uid) == proper_length
#It must contain at least 3 digits ( 0-9 ).
def has_three_digits(potential_uid):
return sum([char.isnumeric() for char in potential_uid])>=3
#It should only contain alphanumeric characters (A -Z ,a -z & 0 -9 )
# Defining a function for this may be an overkill to be honest
def is_alphanumeric(potential_uid):
return potential_uid.isalnum()
def is_valid_uid(potential_uid):
if has_at_least_two_uppercase(potential_uid) is False:
return False
if has_unique_chars(potential_uid) is False:
return False
if is_proper_length(potential_uid) is False:
return False
if has_three_digits(potential_uid) is False:
return False
if is_alphanumeric(potential_uid) is False:
return False
return True
Side notes:
use is to check for True/False
use True/False and not 1/0 for boolean conditions (like valid variable)
[OPTIONAL / homework]
use docstrings instead of comments
add add type hints (see is_proper_length as an example)
you can use all() and pass all the calls into it, but the ifs will short circuit from the function without checking all the conditions (all depends on a problem, like number of conditions, length of the UID, number of UIDs to be checked etc.) and you can play around with order of the checks e.g. if the length is not right there's no need to check the rest (but it's a pre-optimization in a way, which is discouraged in general)
parametrize your functions further if need be, define params for number of upper to check, numeric and so on

Detecting value has returned to below threshold before allowing value change

I'm trying to design is a system that takes user input (from a continuously variable analogue potentiometer 0-100) and uses that input to set a value and I'm looking for a good method to handle a failure case.
I need to handle an error in the system that once detected sets the value to zero and requires the input to be brought back to a low value below a threshold before the user can again increase the value as required. I would also be fine for the value to return to zero if it allowed for simpler logic.
This seems like quite a common piece software safety logic however I have struggled to find any information about this problem on the internet. (I was thinking it might share some logic with a Schmitt trigger?)
If you have ideas about this problem or know of its name/ a good set of resources that would be much appreciated.
I have developed a simple python program as an example to perform this however I'm sure that is not the most robust or efficient method to solve this problem.
# check value has returned to below 5% before allowing
# increase after failure case
value = 0
user_command = 0
failure_case = True
while True:
## get input
raw_input = input()
if (raw_input == 'e'):
# if input is 'e'
# enter failure case
failure_case = True
else:
try:
# if input is a number
user_command = int(raw_input)
except:
pass
if (failure_case):
# a failure has been detected
print("Waiting for value to return to below 5")
# set value to zero
value = 0
# only remove the error flag once the
# input value is below 5
if (user_command < 5):
failure_case = False
else:
# no error thus set value to the user input
value = user_command
# print the accepted value
print(value);
Any help would be much appreciated.
Thanks.

How to jump out the current while loop and run the next loop whenever meeting a certain condition?

The Python script that I am using is not exactly as below, but I just want to show the logic. Let me explain what I am trying to do: I have a database, and I want to fetch one population (a number A) a time from the database until all numbers are fetched. Each time fetching a number, it does some calculations (A to B) and store the result in C. After all fetched, the database will be updated with C. The while condition just works like a 'switch'.
The thing is that I don't want to fetch a negative number, so when it does fetch one, I want to immediately jump out the current loop and get a next number, until it is not a negative number. I am a beginner of Python. The following script is what I could write, but clearly it doesn't work. I think something like continue, break or try+except should be used here, but I have no idea.
for _ in range(db_size):
condition = True
while condition:
# Get a number from the database
A = db.get_new_number()
# Regenerate a new number if A is negative
if A < 0:
A = db.get_new_number()
B = myfunc1(A)
if B is None:
continue
C=myfunc2(B)
db.update(C)
Use a while loop that repeats until the condition is met.
for _ in range(db_size):
condition = True
while condition:
# Get a number from the database
while True:
A = db.get_new_number()
if A is None:
raise Exception("Ran out of numbers!")
# Regenerate a new number if A is negative
if A >= 0:
break
B = myfunc1(A)
if B is None:
continue
C=myfunc2(B)
db.update(C)
My code assumes that db.get_new_number() returns None when it runs out. Another possibility would be for it to raise an exception itself, then you don't need that check here.

Need help my python script showing index error

From below configuration, i need to pull hostname and Group-name neighbor x.x.x.x information,
#
-set system host-name devicename_ABC
-set protocols bgp group Group-name type internal
-set protocols bgp group Group-name neighbor x.x.x.x
-set protocols bgp group Group-name neighbor z.z.z.z
#
I wrote below python script but it showing index error. please help me to solve this problem.
Python script :
reDeviceName = re.compile(r'#\s*\n\s*host (\S*)\s*',re.DOTALL)
deviceName = reDeviceName.findall(allText)
regBbpGroup = re.compile(r'\s*bgp group (\S*)\s*',re.DOTALL)
bpGroupList = regBbpGroup.findall(allText)
numBbpGroup = len(bpGroupList)
i = 0
def temp(x):
return x
while i < numBbpGroup:
requiredInfo = list(map(temp,bpGroupList[i]))
requiredInfo.insert(0,deviceName[0]) (index error showing for this line)
bpGroupList = str(requiredInfo[2])
i = i + 1
numBbpGroup = len(bpGroupList) - 1
Use this and it will work fine for you. Length function in python starts counting from 1 and array indexing starts at 0
Edit: This is not the cause of your current IndexError, however if you only fix your device name string regex expression, you will get another IndexError when you try to access bpGroupList[i] when i = len(bpGroupList).
Change your while loop into for loop. Another answer suggested subtracting 1 from your numBbpGroup variable, but then the name of the variable would be misleading. The range function is designed to operate in this minus 1 fashion. So instead of saying
while i < numBbpGroup:
...
i = i + 1
you can say
for i in range(numBbpGroup):
...
and it will work fine. i will go from 1 up to numBbpGroup - 1 that you don't need to increment i in the for-loop version.
Edit: I have a feeling your device name variable is an empty string, which is what's causing the index error you see.
Can you try this positive look-behind regular expression instead? I'm assuming you want the test after the string host-name.
reDeviceName = re.compile(r'(?<=host-name).*')

How to check if variable matches, then do something

I have a script that pulls some data from a network device, strips off some crap and returns a value via a re.search.
the end result is i have two variables that contain a numerical value, say file1 contains one line with '10', file2 contains one line with '20'. i've put these into variables
oldnumber = 10
newnumber = 20
what i need to do is check to see if the numbers are the same value. if the numbers are the same, do nothing. if they aren't the same, then do something else - ie. send a mail to myself (smtplib works for me).
i'm new to python and finding my way, not sure how to code this?
i suppose the simplest way to describe this is if oldnumber = newnumber, then send mail, else do nothing.
If I remember well you're right
just do
if oldnumber!=newnumber;
do what you want
http://www.tutorialspoint.com/python/python_if_else.htm
almost right.
if oldnumber != newnumber:
# do something
# and then proceed..
Or:
if oldnumber == newnumber:
# do this
else:
# do that
# and then proceed..

Categories