[Tutor] Alternative to for/while loop
Hello, I'm very new to python so please forgive what may be a beginner question. The book I'm working through hasn't covered using flow control yet so I'm thinking there should be a way to do this without the for loop I used, but I'm at a loss here. So far the book has covered: lists, strings, numerical types (float, integer, etc), methods, tuples, importing modules, boolean logic, and mathematical operators. The problem asks to receive an arbitrary list of numbers separated by commas and then find the average. If someone could point me in the right direction I'd appreciate it. I'm using Python3.5.1 on Fedora 24 Linux, though the book uses Python2.x. My code: nums = input('Enter some numbers separated by commas: ') nums = [float(i) for i in nums.split(', ')] print((sum(nums)) / len(nums)) Regards, Bryon ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Alternative to for/while loop
On 10/25/2016 4:19 AM, Alan Gauld via Tutor wrote: On 25/10/16 02:38, Bryon Adams wrote: question. The book I'm working through hasn't covered using flow control yet so I'm thinking there should be a way to do this without the for loop I used, but I'm at a loss here. Thee are ways to do it without using a for loop but they are all more advanced rather than simpler. (And they are less "good" than the simple program you have written in that they are unnecessarily complicated) So far the book has covered: lists, strings, numerical types (float, integer, etc), methods, tuples, importing modules, boolean logic, and mathematical operators. You used a list comprehension in your solution, was that covered as part of lists? If not how did you find it? nums = input('Enter some numbers separated by commas: ') nums = [float(i) for i in nums.split(', ')] print((sum(nums)) / len(nums)) That's about as simple as it gets except for the surplus of parens in the last line: print(sum(nums) / len(nums)) is sufficient. I had done a little bash, C, and Visual Basic so I figured a for loop would be a good way to do this (that's how I came to the idea of using 'for' anyway). This is my first effort since college to try and really learn some programming, was a hodge podge networking program and I didn't realise how useful or in demand some programming would be. If I remember correctly I was looking for how to do a for loop in python3 but I don't remember the terms I threw into DuckDuckGo (it definitely wasn't list comprehension). I believe I bookmarked it though. I ended up at a Stack Overflow page with instructions on how to do this. I'll have to skim through the chapter and see if I can find list comprehension, if not I'll check the back of the book for where it's mentioned. Wolfgang was on the money when suggesting the book was python2. Regards, Bryon ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Alternative to for/while loop
On 10/25/2016 4:31 AM, Wolfgang Maier wrote: On 25.10.2016 10:10, Ben Finney wrote: Bryon Adams writes: I'm very new to python so please forgive what may be a beginner question. Welcome! You are in the right place for asking beginner Python questions :-) I'm thinking there should be a way to do this without the for loop I used, but I'm at a loss here. Thank you for posting your code, and a specific question about it. Why do you think there “should be a way to do this without the for loop”? If you want to do something with a collection of items, a ‘for’ loop is quite a normal way to do that. (In fact you have not used a for loop, you have used a different syntax called a “list comprehension”. But the main question remains unchanged: Why would you expect to not need some kind of iteration like a ‘for’?) You cut off a relevant part of the orignal question: The book I'm working through hasn't covered using flow control yet ... and I agree that it would be a strange book that requires you to use for loops or comprehensions before they got introduced. A possible explanation is that, as you are saying, the book uses python2. In python2, input does not return a string, but evaluates the input from the user to produce different types of objects. So in Python2: nums = input('Enter some numbers separated by commas: ') Enter some numbers separated by commas: 1,2,3,4 nums (1,2,3,4) type(nums) So the task is actually easier in Python2, BUT: there is a good reason (safety) why that behavior of input got removed in Python3. In general, it is a really bad idea to evaluate arbitrary input as python code. Your solution using a comprehension (or a for loop) to convert string parts to float explicitly is far better and the recommended approach nowadays. Best, Wolfgang ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor I should have mentioned, yes the book does use python2. I've been using python3 however when I do the exercises, range() was another function that changed but I was able to figure that one out =). Thanks for the detailed explanation everyone, I appreciate it. I'll have to look up list comprehension, I'm not sure it was actually covered in the chapter to be honest and it sounds like the difference in python versions is why the author may not have covered it. I've got a bit of extra reading to do tonight! Regards, Bryon ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Question About the .format Method.
Hello, Working on a simple function to get an IP address and make it look pretty for the PyNet course. I'm wondering if there's way to evenly space text with the string.format() method similar to how I'm doing it with the % operator. The last two prints keep everything left aligned and 20 spaces wide. Is there a way to accomplish this with the .format() method that I use in the first print function? # Getting the IP address and putting it into list ip4 = input('Please enter a /24 network address: ') ip4 = ip4.split('.') # Split string into a list ip4 = ip4[:3]# Force list to be a /24 network address ip4.append('0') print('{}.{}.{}.{}'.format(ip4[0], ip4[1], ip4[2], ip4[3])) ip4_str = '.'.join(ip4) ip4_bin = bin(int(ip4[0])) ip4_hex = hex(int(ip4[0])) # Printing the table print('\n'+'-') print('%-20s %-20s %-20s' %('NETWORK_NUMBER', 'FIRST_OCTET_BINARY', 'FIRST_OCTET_HEX')) print('%-20s %-20s %-20s' %(ip4_str, ip4_bin, ip4_hex)) PS. I realise the first print can be simplified with a .join but I forgot about .join and left it to help illustrate my question. Thanks, Bryon ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Variable Question
Hello, Variable throwing me off in a script I'm running on Python3.5, on Fedora 24. I take four strings and create a list of them. In my below code, if I print out prefix and as_path, both give me the same (I included the output below). What causes this behavior? Is this just how Python is handling the variables in memory and I'm actually working on 'entries' each time? I fixed it already by changing how I assign prefix and as_path. # Given 'show ip bgp' entry1 = "* 1.0.192.0/18 157.130.10.233 0 701 38040 9737 i" entry2 = "* 1.1.1.0/24 157.130.10.233 0 701 1299 15169 i" entry3 = "* 1.1.42.0/24157.130.10.233 0 701 9505 17408 2.1465 i" entry4 = "* 1.0.192.0/19 157.130.10.233 0 701 6762 6762 6762 6762 38040 9737 i" entries = [entry1.split(), entry2.split(), entry3.split(), entry4.split()] prefix = entries as_path = entries n = 0 for i in prefix: prefix[n] = prefix[n][1] n += 1 print(prefix) print(as_path) [bryon@fedberry ~/pynet]$ python3 week3-2.py ['1.0.192.0/18', '1.1.1.0/24', '1.1.42.0/24', '1.0.192.0/19'] ['1.0.192.0/18', '1.1.1.0/24', '1.1.42.0/24', '1.0.192.0/19'] 192.0/1 1.0/2 42.0/2 192.0/1 Thanks, Bryon ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Variable Question
On 11/18/2016 08:16 PM, Alan Gauld via Tutor wrote: for index, item in enumerate(prefix): prefix[index] = item[1] I forgot about enumerate! That helped me clean up and actually finish my next exercise as I was having trouble working for my lists the way I was previously. Thank you very much =) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Parsing a String
Hello, I have written a script that pulls certain bits of information out of a Cisco router's 'show version' command. The output is given in the assignment and it does work on several different routers (I tested 3 different models from work). What I did seems a bit messy to me though, would I be able to get a second opinion here? Code in it's entirety is below. I did this using Python3.5.2 on Fedora 25. #!/usr/bin/env python3 # November 24, 2016# # Take the given string for 'show version' on a Cisco router # # and return the following information: # # vendor, model, os_version, uptime, serial number # # Code should be generic and work on other versions. # # # sh_ver = ''' Cisco IOS Software, C880 Software (C880DATA-UNIVERSALK9-M), Version 15.0(1)M4, RELEASE SOFTWARE (fc1) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2010 by Cisco Systems, Inc. Compiled Fri 29-Oct-10 00:02 by prod_rel_team ROM: System Bootstrap, Version 12.4(22r)YB5, RELEASE SOFTWARE (fc1) twb-sf-881 uptime is 7 weeks, 5 days, 19 hours, 23 minutes System returned to ROM by reload at 15:33:36 PST Fri Feb 28 2014 System restarted at 15:34:09 PST Fri Feb 28 2014 System image file is "flash:c880data-universalk9-mz.150-1.M4.bin" Last reload type: Normal Reload Last reload reason: Reload Command Cisco 881 (MPC8300) processor (revision 1.0) with 236544K/25600K bytes of memory. Processor board ID FTX138X 5 FastEthernet interfaces 1 Virtual Private Network (VPN) Module 256K bytes of non-volatile configuration memory. 126000K bytes of ATA CompactFlash (Read/Write) License Info: License UDI: - Device# PID SN - *0CISCO881-SEC-K9 FTX138X License Information for 'c880-data' License Level: advipservices Type: Permanent Next reboot license Level: advipservices Configuration register is 0x2102 ''' import sys # New empty dictionary to store information. router_dict = {} # Get vendor, although we know it's Cisco anyway. if 'Cisco' in sh_ver: router_dict['vendor'] = 'Cisco' else: sys.exit('This is not a Cisco device') # Split sh ver output to a list of lines lines = sh_ver.split('\n') # Get the IOS version, this parses for the string 'Cisco IOS Software', # in every line in 'lines.' It then splits the string stored in position # 0 and returns position 2 as the os version and strips off the leading # space. router_dict['os_ver'] = [i for i in lines if 'Cisco IOS Software' in i][0].split(',')[2][1:] # Get the model of router using the same logic as the IOS version. The line # doesn't have a nice split character so I rebuilt the string using spaces. router_dict['model'] = ' '.join([i for i in lines if 'bytes of memory' in i][0].split()[0:3]) # Get uptime using the same logic as 'model' router_dict['uptime'] = ' '.join([i for i in lines if 'uptime' in i][0].split()[3:]) # Get serial number using the logic from 'os_ver' router_dict['serial'] = [i for i in lines if 'Processor board ID' in i][0].split()[3] for i in router_dict: print('{:<10} {}'.format(i, router_dict.get(i))) Thanks, Bryon ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Parsing a String
On 11/25/2016 05:26 PM, Bryon Adams wrote: Hello, I have written a script that pulls certain bits of information out of a Cisco router's 'show version' command. The output is given in the assignment and it does work on several different routers (I tested 3 different models from work). What I did seems a bit messy to me though, would I be able to get a second opinion here? Code in it's entirety is below. I did this using Python3.5.2 on Fedora 25. #!/usr/bin/env python3 # November 24, 2016# # Take the given string for 'show version' on a Cisco router # # and return the following information: # # vendor, model, os_version, uptime, serial number # # Code should be generic and work on other versions. # # # sh_ver = ''' Cisco IOS Software, C880 Software (C880DATA-UNIVERSALK9-M), Version 15.0(1)M4, RELEASE SOFTWARE (fc1) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2010 by Cisco Systems, Inc. Compiled Fri 29-Oct-10 00:02 by prod_rel_team ROM: System Bootstrap, Version 12.4(22r)YB5, RELEASE SOFTWARE (fc1) twb-sf-881 uptime is 7 weeks, 5 days, 19 hours, 23 minutes System returned to ROM by reload at 15:33:36 PST Fri Feb 28 2014 System restarted at 15:34:09 PST Fri Feb 28 2014 System image file is "flash:c880data-universalk9-mz.150-1.M4.bin" Last reload type: Normal Reload Last reload reason: Reload Command Cisco 881 (MPC8300) processor (revision 1.0) with 236544K/25600K bytes of memory. Processor board ID FTX138X 5 FastEthernet interfaces 1 Virtual Private Network (VPN) Module 256K bytes of non-volatile configuration memory. 126000K bytes of ATA CompactFlash (Read/Write) License Info: License UDI: - Device# PID SN - *0CISCO881-SEC-K9 FTX138X License Information for 'c880-data' License Level: advipservices Type: Permanent Next reboot license Level: advipservices Configuration register is 0x2102 ''' import sys # New empty dictionary to store information. router_dict = {} # Get vendor, although we know it's Cisco anyway. if 'Cisco' in sh_ver: router_dict['vendor'] = 'Cisco' else: sys.exit('This is not a Cisco device') # Split sh ver output to a list of lines lines = sh_ver.split('\n') # Get the IOS version, this parses for the string 'Cisco IOS Software', # in every line in 'lines.' It then splits the string stored in position # 0 and returns position 2 as the os version and strips off the leading # space. router_dict['os_ver'] = [i for i in lines if 'Cisco IOS Software' in i][0].split(',')[2][1:] # Get the model of router using the same logic as the IOS version. The line # doesn't have a nice split character so I rebuilt the string using spaces. router_dict['model'] = ' '.join([i for i in lines if 'bytes of memory' in i][0].split()[0:3]) # Get uptime using the same logic as 'model' router_dict['uptime'] = ' '.join([i for i in lines if 'uptime' in i][0].split()[3:]) # Get serial number using the logic from 'os_ver' router_dict['serial'] = [i for i in lines if 'Processor board ID' in i][0].split()[3] for i in router_dict: print('{:<10} {}'.format(i, router_dict.get(i))) Thanks, Bryon So I checked out what the teacher had written. He wrapped everything in a for loop which makes what I have look a lot better. Relevant part below, nothing else changed other than I changed the name of a variable to make them easier to distinguish. ver_lines = sh_ver.split('\n') for line in ver_lines: if 'Cisco IOS Software' in line: router_dict['os_ver'] = line.split(',')[2][1:] if 'bytes of memory' in line: router_dict['model'] = ' '.join(line.split()[0:3]) if 'uptime' in line: router_dict['uptime'] = ' '.join(line.split()[3:]) if 'Processor board ID' in line: router_dict['serial'] = line.split()[3] ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Created Function, Need Argument to be a String
Is there a way to force my argument to always be a string before entering the function? Else, is there a better way to go about this? In whatever program I write, I could change what I want as input to be a string prior to tossing it into the function but I think it would make more sense for my function to already do it. The function otherwise works. This is on Python3.5 under Fedora 25 The only other thing I could think of would be to put exceptions in for syntax error and whatever else pops up as I go along, though to be honest it *should* always be a string that gets dumped into the function. Not sure how I'd put the exception together though since it's not making it into the function prior to failing. --- Error from interpreter: (looks like it's taking issue with it being a number it doesn't know how to deal with) >>> ip_checker(169.254.0.1) File "", line 1 ip_checker(169.254.0.1) ^ SyntaxError: invalid syntax --- My function: def ip_checker(ip_address): ''' Takes one IP address and checks whether it is valid or not. ''' # Try to convert to integers try: ip_addr = [int(i) for i in ip_address.split('.')] except ValueError: print('Invalid characters were entered or an octet is empty, please try again.') return False # Determine how many octets were entered if len(ip_addr) != 4: print('Incorrect number of octets, please try again.') return False # Determine validity of first octet if ((ip_addr[0] > 223) and (ip_addr[0] < 256)) or (ip_addr[0] == 0): print('First octet is reserved or zero.') return False # Determine if this is a loopback address if ip_addr[0] == 127: print('I think that was a loopback address, please try again.') return False # Determine if this is an APIPA address if (ip_addr[0] == 169) and (ip_addr[1] == 254): print('I think that was an APIPA address, please try again.') return False # Determine if the last three octets are between 0-255 for octet in (ip_addr[1], ip_addr[2], ip_addr[3]): if octet not in [i for i in range(0,256)]: print('Octet too large or too small, please try again.') return False else: print('The IP address {} is valid.'.format(ip_address)) return True ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor