Reputation: 1687
I wrote a script to pull down a list of aws tags and then read the last octect and tell me which one is the highest IP. For example. here is the list of tags that are returned:
['vlslabmc, 172.16.0.13/24', 'vlslabmc,172.16.0.5/24', 'vlslabmc,172.16.0.3/24', 'vlslabmc,172.16.0.12/24', 'vlslabmc,172.16.0.16/24', 'vlslabmc,172.16.0.6/24', 'vlslabmc,172.16.0.1/24', 'vlslabmc,172.16.0.11/24', 'vlslabmc,172.16.0.15/24', 'vlslabmc,172.16.0.17/24', 'vlslabmc,172.16.0.4/24', 'vlslabmc,172.16.0.7/24', 'vlslabmc,172.16.0.10/24', 'vlslabmc,172.16.0.9/24', 'vlslabmc,172.16.0.8/24', 'vlslabmc,172.16.0.2/24', 'vlslabmc,172.16.0.14/24']
Here's my code to workout the largest IP from the tagLis (note that the largest is 17, 172.16.0.17)
21 def findLargestIP():
22 for i in tagList:
23 #remove all the spacing in the tags
24 ec2Tags = i.strip()
25 #seperate any multiple tags
26 ec2SingleTag = ec2Tags.split(',')
27 #find the last octect of the ip address
28 fullIPTag = ec2SingleTag[1].split('.')
29 #remove the CIDR from ip to get the last octect
30 lastIPsTag = fullIPTag[3].split('/')
31 lastOctect = lastIPsTag[0]
32 ipList.append(lastOctect)
33 largestIP = int(ipList[0])
34 for latestIP in ipList:
35 if int(latestIP) > largestIP:
36 largestIP = latestIP
37 return largestIP
I'm not sure why.. but when I print the value of largestIP it always prints out 16. Ive gone through the code it should have worked (I'm avoiding using the max function as I'm just learning to code)
Any help as aways is greatly appreciated.
Thanks
Ok so thanks to a clue from cmarie I got it working the problem was mainly
33 largestIP = int(ipList[0])
Here's the code running before with an added print statement on the list append:
'13']
['13', '5']
['13', '5', '3']
['13', '5', '3', '12']
['13', '5', '3', '12', '16']
16
['13', '5', '3', '12', '16', '6']
16
['13', '5', '3', '12', '16', '6', '1']
16
['13', '5', '3', '12', '16', '6', '1', '11']
16
... ...
['13', '5', '3', '12', '16', '6', '1', '11', '15', '17', '4', '7', '10', '9', '8', '2']
16
['13', '5', '3', '12', '16', '6', '1', '11', '15', '17', '4', '7', '10', '9', '8', '2', '14']
16
Basically what was happening is that during this loop :
33 largestIP = int(ipList[0])
34 for latestIP in ipList:
35 if int(latestIP) > largestIP:
36 largestIP = latestIP
The loop stops at the 1st largest integer. in this case that is 16. *I'm not sure why it does but it does
Here's the working code:
19 def findLargestIP():
20 ipList =[]
21 for i in tagList:
22 #remove all the spacing in the tags
23 ec2Tags = i.strip()
24 #seperate any multiple tags
25 ec2SingleTag = ec2Tags.split(',')
26 #find the last octect of the ip address
27 fullIPTag = ec2SingleTag[1].split('.')
28 #remove the CIDR from ip to get the last octect
29 lastIPsTag = fullIPTag[3].split('/')
30 lastOctect = lastIPsTag[0]
31 ipList.append(int(lastOctect))
32 print ipList
33 largestIP = 0
34 for latestIP in ipList:
35 if latestIP > largestIP:
36 largestIP = latestIP
37 print latestIP
38 print largestIP
39 return largestIP
and the result:
[13, 5, 3, 12, 16]
13
16
[13, 5, 3, 12, 16, 6]
13
16
[13, 5, 3, 12, 16, 6, 1]
13
16
[13, 5, 3, 12, 16, 6, 1, 11]
13
16
[13, 5, 3, 12, 16, 6, 1, 11, 15]
13
16
[13, 5, 3, 12, 16, 6, 1, 11, 15, 17]
13
16
17
Note it found 17.
Upvotes: 1
Views: 1115
Reputation: 346
Although other people have already provide you some alternative ways to find the answer, if you want to keep using your program, here is some way of fixing it:
def findLargestIP():
ipList = []
for i in tagList:
#remove all the spacing in the tags
ec2Tags = i.strip()
#seperate any multiple tags
ec2SingleTag = ec2Tags.split(',')
#find the last octect of the ip address
fullIPTag = ec2SingleTag[1].split('.')
#remove the CIDR from ip to get the last octect
lastIPsTag = fullIPTag[3].split('/')
lastOctect = lastIPsTag[0]
ipList.append(int(lastOctect))
largestIP = 0
for latestIP in ipList:
if latestIP > largestIP:
largestIP = latestIP
return largestIP
The differences from this and your program are that here I:
ipList = []
largestIP = 0
, instead of taking the first number of the ipList (since you shouldn't assume the list is sorted)tagList
] - just for eliminating unnecessary iterationsIf I would do that task, however, I would try to use regular expressions. Here is a way to do it:
import re
def alternativeFindLargestIP():
ipList = re.findall(r'(?<=\.)\d+(?=/)', ' '.join(tagList))
ipList = [int(num) for num in ipList]
return max(ipList)
Upvotes: 2
Reputation: 114599
The code is quite convoluted (much more than needed) but the error is that ipList
gets filled with strings and then its elements are compared with an integer.
This in Python 2 was a silent source of problems (you got a nonsensical but stable True
/False
result when comparing different types instead of an error) and in Python 3 it became an error.
a much simpler implementation would in my opinion be:
return max(int(x.split(",")[1].split("/")[0].split(".")[-1])
for x in taglist)
with the meaning:
split(",")[1]
to take the part after the commasplit("/")[0]
to take the part before the slashsplit(".")[-1]
to take the last part of IP addressint(...)
to convert to integermax(... for x in taglist
to do this for all elements and keeping the maxor using a regexp with
return max(int(re.match(".*?([0-9]+)/", x).group(1))
for x in taglist)
Upvotes: 1
Reputation: 2121
So I had to refactor your code a little bit. I assumed ipList was an empty list. Are you sure you tested to see if it actually ran? Specifically your if statement
if int(latestIP) > largestIP:
largestIP = latestIP
would return a
TypeError: unorderable types: int() > str()
because you would be assigning a string to largestIP and then in the next iteration, you would compare a string with an int. Aside from that, your code seems functional. It returns 17 as the largest last octet for me which seems right.
If your intention is to return the largest last octet of your list of ip addresses, you might want to approach this a little bit differently.
Option 1: Accumulate list of IP Addresses first
Instead of nesting a for loop in your loop to iterate through all the tags, you can first just accumulate the tags and then go through and find the max. This way, you go through the tag list once, and then the ip list once, instead of going through your entire ip list each time you iterate through your tag list.
Option 2: Create a list of only the last octet
Similar to option 1, you would iterate through your tagList and accumulate all the last octets of the ip addresses casted to ints into a list, instead of the entire ip address. In a loop afterwards, you can call max on the list with the octets (I'm guessing you want to avoid this).
Option 3: Have a running greatest value
I think this is the best solution. As you're going through the tag list, you can keep a variable that will have the greatest last octet so far. This way you only need to loop through the tag list once, and still come out with the greatest last octet thus far.
If you want to grab the entire IP address, options 1 and 3 would still work, but for option 2, you might want to look into python dictionaries.
Upvotes: 0
Reputation: 15400
Why are doing this so complex. Here is oneliner for this
ip_list = ['vlslabmc, 172.16.0.13/24', 'vlslabmc,172.16.0.5/24', 'vlslabmc,172.16.0.3/24', 'vlslabmc,172.16.0.12/24', 'vlslabmc,172.16.0.16/24', 'vlslabmc,172.16.0.6/24', 'vlslabmc,172.16.0.1/24', 'vlslabmc,172.16.0.11/24', 'vlslabmc,172.16.0.15/24', 'vlslabmc,172.16.0.17/24', 'vlslabmc,172.16.0.4/24', 'vlslabmc,172.16.0.7/24', 'vlslabmc,172.16.0.10/24', 'vlslabmc,172.16.0.9/24', 'vlslabmc,172.16.0.8/24', 'vlslabmc,172.16.0.2/24', 'vlslabmc,172.16.0.14/24']
largestIP = max(ip_list, key=lambda i: int(i.split('/')[0].split('.')[-1]))
Upvotes: 1