1

I have only been using python for a few months and I am trying to blend my hobby (skating all the london postcodes) with learning to code.

I found the following data https://github.com/radiac/UK-Postcodes/blob/master/postcodes.csv

and was able to write the following code which picks a random london postcode

import csv
import random 


ran  =  (random.randint(0,3))
ran_pc = str(random.randint(1,10))
post_code_signs = ('N','S','E','W',)

# Open the CSV file
with open('postcodes.csv', newline='', encoding='utf-8') as file:
    reader = csv.reader(file)
    
    # Loop through each row in the CSV file
    for row in reader:
        londonpostcode = row[0]
        for ldn in londonpostcode:
            if londonpostcode[0] == post_code_signs [ran] and londonpostcode[1] == ran_pc:
                lnfive = londonpostcode+ (" ") + row [5]
    print (lnfive)

This does give me random postcodes but I have several problems , it sometimes gives me a sheffield postcode as it starts with an 'S' at the moment I dont know how to include the other London postcode variations such as 'SE','SW' as this only takes the first slice.

Holistically I would like this to go onto a website I am building and get people to pick a random London postcode . Once I have figured this out I would like to see if I can get people to select their region and then pick a postcode based on that.

GO EASY ON THE NEW GUY !!! but thanks in advance for any assistance

Wanted it to return on London postcodes starting with N,S,E,W and got random sheffield postcodes . The codes also runs into random errors

11
  • 2
    You cannot use just the first letter to select London postcodes as that classhes with outher parts of the country. One way you could work it is to check the town or region columns to see if they include the word "London". As to your random errors, you need to explain exactly what the error(s) are, and where they occur in your code. Commented Mar 7 at 12:12
  • why not use londonpostcode.startswith("SE") instead of checking only one char. Commented Mar 7 at 12:56
  • @furas because some London postcodes start with just S followed by 1 or two digits, others are SW etc. Postcodes in the UK are a bit like Topsy. Commented Mar 7 at 13:07
  • 1
    @furas See my first comment above. But even then it will need more filtering as some Greater London postcodes start with other letters. The issue is not really a Python problem, more deciding how to create a subset of postcodes that are relevant to the user's requirements. Commented Mar 7 at 13:55
  • 1
    Some of the relevant regions don't include the word "London" (e.g. "Westminster"). However, there's only eight postcodes for London proper (as opposed to Greater London), so a simple regexp should do the job - i.e. something like re.fullmatch(r'(?:E|EC|N|NW|SE|SW|W|WC)\d\w?', 'WC1R'). Commented Mar 7 at 15:21

3 Answers 3

1

You might also want to consider something like the pandas library.

import pandas as pd

df = pd.read_csv("postcodes.csv")
postcode_list = df.postcode.tolist()

The above will happily load the csv, and because of the known column name you can get it straight into a list. That list is of course all the postcodes, which doesn't help. However, a line like this will get you the Greater London and Central London only postcodes.

london_postcode_list = df[df["region"].isin(["Greater London", "Central London"])].postcode.tolist()

The [df["region"].isin(["Greater London", "Central London"])] between the initial df and .postcode limits the selection to just those regions, so you can choose a random entry from london_postcode_list and get just a random postcode in London. Changing to other regions is as simple as changing the content of the isin list.

I appreciate this may look scary, and pandas will require an install of some kind (look for some pip install instructions if that is also new to you), but it can make for cleaner code, and will make your future plans easier to implement. This is just a different way of building your list to get your random choice, with some help from the people who created the library in use.

Sign up to request clarification or add additional context in comments.

Comments

1

Thanks to @ekhumoro for the RE, I made the following script which will extract all the London post codes for you.

import re
import csv

# Open the CSV file
pattern = r'(?:E|EC|N|NW|SE|SW|W|WC)\d\w?'
with open('postcodes.csv', encoding='utf-8') as file:
    reader = csv.reader(file)
    for line in reader:
        match = re.fullmatch(pattern, line[0])
        if match != None:
            print(line)

If you capture the output to a file you will then have a set that you can use in your random selector program.

4 Comments

This looks good, but you could go one step further and show how to print a random postcode. This only requires a few changes: create a list to hold the postcodes (postcodes = []); append the matches in the loop (postcodes.append(f'{line[0]} ({line[5] or line[6]})')); print a random choice (print(f'Random London Postcode: {random.choice(postcodes)}')). You could of course capture the output to file as well - but I think that should be in the form a of a new csv which allowed the user to record which postcodes had already been skated (and then randomly choose from the ones that hadn't).
@ekhumoro Thank you, and yes I could have provided the complete solution. But I always feel it is better for newbies to have to think a bit for themselves. If he comes back and asks for more then I will happily help him.
Thank you all this looks great , a further question would be is it possible to get the user to select the region and then get the code to pick a random postcode from that region so for example pick 'aberdeen' and then it will pick a random code in that area. This would be via html on a website I am making
@Premature_Python In theory yes, you can do anything you like. All you need to do is to keep the postcodes in your webserver which you can then display for any user. What I would suggest is that you extract all the data from the .csv file and reformat it into a database (SQLite would be a good choice) so that you can access it more efficiently.
0

If you check the "region" column you can determine if the postcode relates to Greater London.

Build a list of postcodes filtered in that manner.

Choose a random postcode from that list.

Something like this:

import csv
from pathlib import Path
import random

CSVFILE = Path("/Volumes/Spare/postcodes.csv")

def is_london(row: dict) -> str | None:
    if row["region"] in {"Greater London", "City of London", "Westminster"}:
        if (postcode := row["postcode"])[0] in "NSEW":
            return postcode
    return None

with CSVFILE.open(mode="r", newline="") as data:
    postcodes = []
    for row in csv.DictReader(data):
        if postcode := is_london(row):
            postcodes.append(postcode)
    print(random.choice(postcodes))

4 Comments

How about City of London and Westminster?
@AdrianKlaver I didn't examine the CSV in detail - I was just trying to give the general idea. However, if it helps you I've edited the answer to account for 2 regions and the "town" of Westminster. FWIW the input file is not a good source of reference as not all London postcodes are included
1) There is no region of 'Central London', there is 'City of London'. 2) There is no town named 'Westminster', there is a region by that name though.
@AdrianKlaver You're right. I missed the fact that where Westminster is indicated as a "region" there is no corresponding "town'. The whole issue here is moot anyway because the data are incomplete / flawed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.