1

Doing a course in my own time called GeoPython 2018 and am heavily stuck on Lesson 3, Exercise 3.

The content so far has been conditional statements, loops and lists (no dictionaries).

THE PROBLEM:

We are asked to take a list of weather station names, a list of latitudes and a list of longitudes and divide them up into 4 regions (NE, NW, SE, SW) defined by the cutoffs.

# Station names
stations = ['Hanko Russarö', 'Heinola Asemantaus', 'Helsinki Kaisaniemi', 
        'Helsinki Malmi airfield', 'Hyvinkää Hyvinkäänkylä', 'Joutsa Savenaho', 
        'Juuka Niemelä', 'Jyväskylä airport', 'Kaarina Yltöinen', 'Kauhava airfield', 
        'Kemi Kemi-Tornio airport', 'Kotka Rankki', 'Kouvola Anjala', 
        'Kouvola Utti airport', 'Kuopio Maaninka', 'Kuusamo airport', 
        'Lieksa Lampela', 'Mustasaari Valassaaret', 'Parainen Utö', 'Pori airport', 
        'Rovaniemi Apukka', 'Salo Kärkkä', 'Savonlinna Punkaharju Laukansaari', 
        'Seinäjoki Pelmaa', 'Siikajoki Ruukki', 'Siilinjärvi Kuopio airport', 
        'Tohmajärvi Kemie', 'Utsjoki Nuorgam', 'Vaala Pelso', 'Vaasa airport', 
        'Vesanto Sonkari', 'Vieremä Kaarakkala', 'Vihti Maasoja', 'Ylitornio Meltosjärvi']

# Latitude coordinates of Weather stations  
lats = [59.77, 61.2, 60.18, 60.25, 60.6, 61.88, 63.23, 62.4,
   60.39, 63.12, 65.78, 60.38, 60.7, 60.9, 63.14, 65.99,
   63.32, 63.44, 59.78, 61.47, 66.58, 60.37, 61.8, 62.94,
   64.68, 63.01, 62.24, 70.08, 64.5, 63.06, 62.92, 63.84,
   60.42, 66.53]

 # Longitude coordinates of Weather stations 
lons = [22.95, 26.05, 24.94, 25.05, 24.8, 26.09, 29.23, 25.67, 
   22.55, 23.04, 24.58, 26.96, 26.81, 26.95, 27.31, 29.23, 
   30.05, 21.07, 21.37, 21.79, 26.01, 23.11, 29.32, 22.49, 
   25.09, 27.8, 30.35, 27.9, 26.42, 21.75, 26.42, 27.22, 
   24.4, 24.65]

# Cutoff values that correspond to the centroid of Finnish mainland
# North - South
north_south_cutoff = 64.5

# East-West
east_west_cutoff = 26.3

The end result is to populate the following lists with station names that are correctly assigned:

north_west = []
north_east = []
south_west = []
south_east = []

I have been at this for maybe 3-4 hours with no progress, have tried to use dictionaries

data = [{'station':stat, 'latitude': lat, 'longitude': lon}
    for stat, lat, lon in zip(stations, lats, lons)
   ]

But am not getting any further, additionally I get the impression the course organisers want people to focus on iterations and conditionals.

Any advice or nudge in a direction would be helpful. This is also my first post so apologise if there is a lack of clarity.

nkrh
  • 45
  • 5
  • You already found the [How to iterate through two lists in parallel?](//stackoverflow.com/q/1663807) question, so all you have to do is put the names into 4 buckets based on their lon, lat pair in relationship to your cut-off values. Have you worked out yet how to categorise **one** station? Then just apply that knowledge to *all* stations. – Martijn Pieters Mar 09 '19 at 16:27

4 Answers4

0

Here is one of them (apologies if west is lower longitude, then switch > to < ):

north_west = [ a["station"] for a in data if a["latitude"] > north_south_cutoff and a["longitude"] > east_west_cutoff ]
Christian Sloper
  • 7,440
  • 3
  • 15
  • 28
0

The course you are following is quite generous with hints, and they include instructions on what you should accomplish with this exercise:

  1. Create four lists for geographical zones in Finland (i.e. nort_west, north_east, south_west, south_east)
  2. Iterate over values and determine to which geographical zone the station belongs
    1. Hint: You should create a loop that iterates N -number of times. Create a variable N that should contain the number of stations we have here.
    2. You should use a conditional statement to find out if the latitude coordinate of a station is either North or South of the center point of Finland (26.3, 64.5) AND if the longitude location is West or East from that center point.
    3. You should insert the name of the station into the correct geographical zone list (step 1)
  3. Print out the names of stations at each geographical zone

You covered point 1, and found a more efficient method to accomplish point 2.1 (looping over the 3 lists). To accomplish point 2.2, look at those hints I linked to at the start, specifically the Nested if statements section. If that doesn't quite help you solve this, you want to re-reach the conditional statements chapter.

The basic structure of what they you want to do is this:

north_west = []
north_east = []
south_west = []
south_east = []

N = len(stations)

for i in range(N):
    station = stations[i]
    lat = lats[i]
    lon = lons[i]

    if <<test to see if lon is east of 26.3>>:
        if <<test to see if lat is north of 64.5>>:
            # add station to the north_east list
        else:  # south or at 64.5
            # add station to the south_east list
    else:  # west or at 26.3
        if <<test to see if lat is north of 64.5>>:
            # add station to the north_west list
        else:  # south or at 64.5
            # add station to the south_west list

then print the names in each of the four lists. Note that I left out the actual conditions for you to fill in here.

There are more efficient and 'clever' ways of achieving the above, you found one, were for i in range(N): and 3 separate assignments can be replaced by for station, lat, lon in zip(....):. However, I'd stick to the above pattern for now. I've included a different approach below, hidden as a spoiler block so as not to distract you too much:

If you wanted to be super-clever, you could create a mapping from (boolean, boolean) tuples to those 4 lists to select each list: regions = { # north?, east? (False, False): south_west, (False, True ): south_east, (True, False): north_west, (True, True ): north_east, } for station, lon, lat in zip(stations, lons, lats): regions[lat > 64.5, lon > 26.3].append(station) but that's definitely beyond the course requirements. :-)

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks Martijn I really appreciate the time you took for this answer! I think I was getting hung up on what code would iterate through the index of all 3 lists but looking at your answer and going through the materials it really is quite clear. Cheers again! – nkrh Mar 09 '19 at 20:24
0

The advice is to use enumerate build-in function to get an index and a value (station name) from the first list. Then you use the index to get two more values (latitude and longitude) and check these value to determine what region they belong to. Then add this name to result list station_list[quatrant].append(name)

Here is the solution:

# Cutoff values that correspond to the centroid of Finnish mainland
# North - South
north_south_cutoff = 64.5

# East-West
east_west_cutoff = 26.3

# Station names
stations = ['Hanko Russarö', 'Heinola Asemantaus', 'Helsinki Kaisaniemi',
        'Helsinki Malmi airfield', 'Hyvinkää Hyvinkäänkylä', 'Joutsa Savenaho',
        'Juuka Niemelä', 'Jyväskylä airport', 'Kaarina Yltöinen', 'Kauhava airfield',
        'Kemi Kemi-Tornio airport', 'Kotka Rankki', 'Kouvola Anjala',
        'Kouvola Utti airport', 'Kuopio Maaninka', 'Kuusamo airport',
        'Lieksa Lampela', 'Mustasaari Valassaaret', 'Parainen Utö', 'Pori airport',
        'Rovaniemi Apukka', 'Salo Kärkkä', 'Savonlinna Punkaharju Laukansaari',
        'Seinäjoki Pelmaa', 'Siikajoki Ruukki', 'Siilinjärvi Kuopio airport',
        'Tohmajärvi Kemie', 'Utsjoki Nuorgam', 'Vaala Pelso', 'Vaasa airport',
        'Vesanto Sonkari', 'Vieremä Kaarakkala', 'Vihti Maasoja', 'Ylitornio Meltosjärvi']

# Latitude coordinates of Weather stations
lats = [59.77, 61.2, 60.18, 60.25, 60.6, 61.88, 63.23, 62.4,
   60.39, 63.12, 65.78, 60.38, 60.7, 60.9, 63.14, 65.99,
   63.32, 63.44, 59.78, 61.47, 66.58, 60.37, 61.8, 62.94,
   64.68, 63.01, 62.24, 70.08, 64.5, 63.06, 62.92, 63.84,
   60.42, 66.53]

 # Longitude coordinates of Weather stations
lons = [22.95, 26.05, 24.94, 25.05, 24.8, 26.09, 29.23, 25.67,
   22.55, 23.04, 24.58, 26.96, 26.81, 26.95, 27.31, 29.23,
   30.05, 21.07, 21.37, 21.79, 26.01, 23.11, 29.32, 22.49,
   25.09, 27.8, 30.35, 27.9, 26.42, 21.75, 26.42, 27.22,
   24.4, 24.65]

region_name = ['North-West', 'North East', 'South West', 'South East']

NW = 0
NE = 1
SW = 2
SE = 3

def divide_station(stations, lats, lons):
    station_list = [[] for _ in range(SE+1)]
    for index, name in enumerate(stations):
        if lats[index] > north_south_cutoff:
            quatrant = NE if lons[index] > east_west_cutoff else NW
        else:
            quatrant = SE if lons[index] > east_west_cutoff else SW
        station_list[quatrant].append(name)
    return station_list

north_west, north_east, south_west, south_east = divide_station(stations, lats, lons)

station_list = [north_west, north_east, south_west, south_east]

for index, region in enumerate(station_list):
    print('\nRegion:', region_name[index])
    for number, name in enumerate(region):
        print('%2d. %s' % (number+1, name))

Output:

Region: North-West
 1. Kemi Kemi-Tornio airport
 2. Rovaniemi Apukka
 3. Siikajoki Ruukki
 4. Ylitornio Meltosjärvi

Region: North East
 1. Kuusamo airport
 2. Utsjoki Nuorgam

Region: South West
 1. Hanko Russarö
 2. Heinola Asemantaus
 3. Helsinki Kaisaniemi
 4. Helsinki Malmi airfield
 5. Hyvinkää Hyvinkäänkylä
 6. Joutsa Savenaho
 7. Jyväskylä airport
 8. Kaarina Yltöinen
 9. Kauhava airfield
10. Mustasaari Valassaaret
11. Parainen Utö
12. Pori airport
13. Salo Kärkkä
14. Seinäjoki Pelmaa
15. Vaasa airport
16. Vihti Maasoja

Region: South East
 1. Juuka Niemelä
 2. Kotka Rankki
 3. Kouvola Anjala
 4. Kouvola Utti airport
 5. Kuopio Maaninka
 6. Lieksa Lampela
 7. Savonlinna Punkaharju Laukansaari
 8. Siilinjärvi Kuopio airport
 9. Tohmajärvi Kemie
10. Vaala Pelso
11. Vesanto Sonkari
12. Vieremä Kaarakkala
Alex Lopatin
  • 682
  • 4
  • 8
-1

You could use a while loop to iterate through all these latitude and longitude values and then checking the conditions for

NW (lat>NWcutoff&lon<EWcutoff)

NE (lat>NWcutoff&lon>EWcutoff)

SW (lat<NWcutoff&lon<EWcutoff)

SE (lat<NWcutoff&lon>EWcutoff)

And then appending the station name to the respective list.

So the complete, simple and clean code would look like :

    stations = ['Hanko Russarö', 'Heinola Asemantaus', 'Helsinki Kaisaniemi', 'Helsinki Malmi airfield', 'Hyvinkää Hyvinkäänkylä', 'Joutsa Savenaho', 'Juuka Niemelä', 'Jyväskylä airport', 'Kaarina Yltöinen', 'Kauhava airfield', 'Kemi Kemi-Tornio airport', 'Kotka Rankki', 'Kouvola Anjala', 'Kouvola Utti airport', 'Kuopio Maaninka', 'Kuusamo airport', 'Lieksa Lampela', 'Mustasaari Valassaaret', 'Parainen Utö', 'Pori airport', 'Rovaniemi Apukka', 'Salo Kärkkä', 'Savonlinna Punkaharju Laukansaari', 'Seinäjoki Pelmaa', 'Siikajoki Ruukki', 'Siilinjärvi Kuopio airport', 'Tohmajärvi Kemie', 'Utsjoki Nuorgam', 'Vaala Pelso', 'Vaasa airport', 'Vesanto Sonkari', 'Vieremä Kaarakkala', 'Vihti Maasoja', 'Ylitornio Meltosjärvi']

    lats = [59.77, 61.2, 60.18, 60.25, 60.6, 61.88, 63.23, 62.4, 60.39, 63.12, 65.78, 60.38, 60.7, 60.9, 63.14, 65.99, 63.32, 63.44, 59.78, 61.47, 66.58, 60.37, 61.8, 62.94, 64.68, 63.01, 62.24, 70.08, 64.5, 63.06, 62.92, 63.84, 60.42, 66.53]

    lons = [22.95, 26.05, 24.94, 25.05, 24.8, 26.09, 29.23, 25.67, 22.55, 23.04, 24.58, 26.96, 26.81, 26.95, 27.31, 29.23, 30.05, 21.07, 21.37, 21.79, 26.01, 23.11, 29.32, 22.49, 25.09, 27.8, 30.35, 27.9, 26.42, 21.75, 26.42, 27.22, 24.4, 24.65]
    i=0
    north_south_cutoff = 64.5
    east_west_cutoff = 26.3
    north_east=[]
    north_west=[]
    south_east=[]
    south_west=[]
    for i in range(0,len(stations)):
            if lats[i]>north_south_cutoff and lons[i]>east_west_cutoff:
                      north_east.append(str(stations[i]))
            elif lats[i]<north_south_cutoff and lons[i]>east_west_cutoff:
                      south_east.append(str(stations[i]))
            elif lats[i]>north_south_cutoff and lons[i]<east_west_cutoff:
                      north_west.append(str(stations[i]))
            elif lats[i]<north_south_cutoff and lons[i]<east_west_cutoff:
                      south_west.append(str(stations[i]))
    print(north_east)
    print(north_west)
    print(south_east)
    print(south_west)

This will put all stations in respective lists after comparing longitudes and latitudes on basis of off-set.

Avinash Karhana
  • 659
  • 4
  • 16
  • Python [has no `++` increment operator](https://stackoverflow.com/questions/1485841/behaviour-of-increment-and-decrement-operators-in-python), the code you posted does not work. Python idiom for a loop like this is to use a `for` loop with a `range()` object, or better, over the `zip()` iterator. – Martijn Pieters Mar 09 '19 at 22:29