• tonight's work....it ain't perfect, and probably not the best way to do this... but it is good practice doing if/elif etc! tried to add a few arguments to catch silly entries like multiple spaces, special chars etc

    (I know I could validate against OS codepoint table, but that's not the point)

    print('This tool breaks down UK postcodes to their component parts')
    exit=False
    while exit is False:
    	postcode=input('Please enter your postcode (0 to exit): ').upper()
    	if (' ' in postcode)==True:
    		postcode=' '.join(postcode.split())
    	elif (' ' in postcode)==False:
    		if len(postcode)==5:
    			postcode=postcode[:2]+' '+postcode[2:]
    		elif len(postcode)==6:
    			postcode=postcode[:3]+' '+postcode[3:]
    		elif len(postcode)==7:
    			postcode=postcode[:4]+' '+postcode[4:]
    	if (len(postcode)>8 and str(postcode)!='0') and set('[~!@#$%^&*()_+{}":;\']+$').intersection(postcode):
    		print('Your postcode is too long and contains an illegal special character, please try again')
    	elif (len(postcode)<6 and str(postcode)!='0') and set('[~!@#$%^&*()_+{}":;\']+$').intersection(postcode):
    		print('Your postcode is too short and contains an illegal special character, please try again')
    	elif len(postcode)>8 and str(postcode)!='0':
    		print('Your postcode is too long, please try again')
    		exit=False
    	elif len(postcode)<6 and str(postcode)!='0':
    		print('Your postcode is too short, please try again')
    		exit=False
    	elif set('[~!@#$%^&*()_+{}":;\']+$').intersection(postcode):
    		print('Your postcode contains an illegal special character, please try again')
    		exit=False
    	elif str(postcode)=='0':
    		print('Goodbye')
    		exit=True
    	elif len(postcode)>=6 and len(postcode)<=8:
    		length=len(postcode)
    		outward_code=postcode.split(' ')[0]
    		
    		if len(outward_code)==2:
    			postcode_area=outward_code[:1]
    			postcode_district=outward_code[1:2]
    		elif len(outward_code)==3 and outward_code[1:2].isdigit():
    			postcode_area=outward_code[:1]
    			postcode_district=outward_code[1:3]
    		elif len(outward_code)==3 and not outward_code[1:2].isdigit():
    			postcode_area=outward_code[:2]
    			postcode_district=outward_code[2:3]
    		elif len(outward_code)==4:
    			postcode_area=outward_code[:2]
    			postcode_district=outward_code[2:4]
    		inward_code=postcode.split(' ')[1]
    		postcode_sector=inward_code[:1]
    		postcode_unit=inward_code[1:3]
    		print('')
    		print(postcode+' breaks down to:')
    		print('Outward Code: '+outward_code)
    		print('Postcode Area: '+postcode_area)
    		print('Postcode District: '+postcode_district)
    		print('Inward Code: '+inward_code)
    		print('Postcode Sector: '+postcode_sector)
    		print('Postcode Unit: '+postcode_unit)
    		print('')
    		exit=False
    
  • I'd remove the spaces before you break down the postcode.

    If I put in 'A B123XY'
    then the breakdown isn't right.

    But it's trivial to fix someone putting a space in the wrong place since every postcode has a space before the last 3 characters, regardless of whether it's 5, 6 or 7 characters long.

    As to the order of statements, you would put the most restrictive first.
    Or you could check everyone and set a flag somewhere.

    But I'd avoid putting every combination of error messages in.
    You've only got 3 things to check for.
    Too long, too short, bad characters. So it's manageable to put the combinations in (e.g. too long and bad characters). But consider if you had a dozen things to check for. You'd have a screen full of elifs and nested crap. Easier to check one thing at a time and potentially just have two error messages.
    "Too long"
    "Bad characters"

    isValid = true
    if length < 6: isValid = false
    if length > 8: isValid = false
    if set('[~!@#$%^&*()_+{}":;\']+$').intersec­tion(postcode): isValid = false
    
    if isValid == false: print "something's wrong with the postcode"
    

    etc.

    Can simplify the stuff where you're working out the parts of the postcode too

    print('This tool breaks down UK postcodes to their component parts')
    
    exit=False
    while not(exit):
        postcode=input('Please enter your postcode (0 to exit): ')
        postcode=str(postcode).upper().replace(" ", "")
        valid_postcode = True
        
        if str(postcode) == '0':
            print('Goodbye')
            exit = True
        
        else:
            if set('[~!@#$%^&*()_+{}":;\']+$').intersection(postcode):
                print('Your postcode contains an illegal special character, please try again')
                valid_postcode = False
    
            if len(postcode) < 5:
                print('Your postcode is too short, please try again')
                valid_postcode = False
    
            
            if len(postcode) > 7:
                print('Your postcode is too long, please try again')
                valid_postcode = False
            
            outward_code = postcode[:-3]
            inward_code = postcode[-3:]
                
            postcode_area=outward_code[:-2]
            postcode_district=outward_code[-2:]
            
            postcode_sector=inward_code[:1]
            postcode_unit=inward_code[1:]
            
            if valid_postcode:
                print('')
                print(outward_code+' '+inward_code+' breaks down to:')
                print('Outward Code: '+outward_code)
                print('Postcode Area: '+postcode_area)
                print('Postcode District: '+postcode_district)
                print('Inward Code: '+inward_code)
                print('Postcode Sector: '+postcode_sector)
                print('Postcode Unit: '+postcode_unit)
                print('')
    

    (caveat - I probably have just as many bad habits as you, I've only been messing about in Python for a few weeks too)

  • thanks, a lot of that makes sense. I don't think I can avoid all the ifs, as postcodes like n1 1ab and sw1w 1ab are treated differently, but it is definitely neater!

    Is there a way to measure performance as with SQL summary statistics and execution plans?

    (caveat - I probably have just as many bad habits as you, I've only been messing about in Python for a few weeks too)

    hence me posting.. i don't want them to become habits!

    had you never done Python before going on the course?

    Going on a 3 day course end of this month/early may which should be good. I think the main focus will be pandas and numpy

About

Avatar for duncs @duncs started