Home > front end >  TypeError: '<' not supported between instances of 'str' and 'float'
TypeError: '<' not supported between instances of 'str' and 'float'

Time:05-23

I have a simple Python script that queries an API and parses the JSON data. Specifically, I am trying to find all ids that fall into a rectangle based on given latitude and longitude coordinates. I am having some data type issues since one is being returned as type str and the other as type float. The coordinates are: (37.769754, -122.427050) and, (37.748554, -122.404535).

Below is my code, sample JSON, and the trace.

Code:

import requests

def get_ids():
    url = "https://retro.umoiq.com/service/publicJSONFeed?command=vehicleLocations&a=sf-muni&t=0"
    response = requests.get(url).json()

    id_list = []

    for i in response['vehicle']:
        lat = i['lat']
        lon = i['lon'] 
        
        if (lat < 37.769754 and lon < -122.427050): 
            if (lat < 37.748554 and lon < -122.404535):
                id_list.append(i['id'])
    
    print(id_list)

def main():
    get_ids()

if __name__ == "__main__":
    main()

JSON:

{'lastTime': {'time': '1653259435728'}, 'copyright': 'All data copyright San Francisco Muni 2022.', 'vehicle': [{'routeTag': 'KT', 'predictable': 'true', 'heading': '218', 'speedKmHr': '0', 'lon': '-122.405464', 'id': '1462', 'dirTag': 'KT___O_F20', 'lat': '37.708099', 'secsSinceReport': '33', 'leadingVehicleId': '1487'}, {'routeTag': '33', 'predictable': 'true', 'heading': '165', 'speedKmHr': '35', 'lon': '-122.40744', 'id': '5817', 'dirTag': '33___O_F00', 'lat': '37.763451', 'secsSinceReport': '6'}, {'routeTag': '1', 'predictable': 'true', 'heading': '269', 'speedKmHr': '0', 'lon': '-122.492844', 'id': '5818', 'dirTag': '1____O_F00', 'lat': '37.77985', 'secsSinceReport': '33'}, {'routeTag': '1', 'predictable': 'true', 'heading': '219', 'speedKmHr': '0', 'lon': '-122.493156', 'id': '5819', 'lat': '37.779823', 'secsSinceReport': '6'}, {'routeTag': 'N', 'predictable': 'true', 'heading': '195', 'speedKmHr': '6', 'lon': '-122.457748', 'id': '1453', 'dirTag': 'N____O_F01', 'lat': '37.764671', 'secsSinceReport': '33'}, {'routeTag': '24', 'predictable': 'true', 'heading': '231', 'speedKmHr': '0', 'lon': '-122.412033', 'id': '5813', 'dirTag': '24___I_F00', 'lat': '37.739773', 'secsSinceReport': '20'}, {'routeTag': '1', 'predictable': 'true', 'heading': '80', 'speedKmHr': '0', 'lon': '-122.397522', 'id': '5815', 'dirTag': '1____I_F00', 'lat': '37.795418', 'secsSinceReport': '46'}, {'routeTag': '1', 'predictable': 'true', 'heading': '87', 'speedKmHr': '0', 'lon': '-122.472931', 'id': '5827', 'dirTag': '1____I_F00', 'lat': '37.78437', 'secsSinceReport': '6'}, {'routeTag': 'KT', 'predictable': 'true', 'heading': '330', 'speedKmHr': '32', 'lon': '-122.468117', 'id': '1469', 'dirTag': 'KT___I_F20', 'lat': '37.7290149', 'secsSinceReport': '6'}, {'routeTag': '33', 'predictable': 'true', 'heading': '77', 'speedKmHr': '0', 'lon': '-122.456421', 'id': '5828', 'dirTag': '33___O_F00', 'lat': '37.786957', 'secsSinceReport': '6'}, {'routeTag': '45', 'predictable': 'true', 'heading': '165', 'speedKmHr': '21', 'lon': '-122.406647', 'id': '5829', 'dirTag': '45___I_F00', 'lat': '37.78756', 'secsSinceReport': '6'}
etc...

Trace:

Traceback (most recent call last):
  File "/main.py", line 51, in <module>
    main()
  File "/main.py", line 48, in main
    get_ids()
  File "/main.py", line 41, in get_ids
    if (lat < 37.769754 and lon < -122.427050): 
TypeError: '<' not supported between instances of 'str' and 'float'

CodePudding user response:

Try converting the data to floats like so:

lat = float(i['lat'])
lon = float(i['lon'])

This will allow the comparison operators to work correctly when comparing 2 floats.

Keep in mind the operators themselves are wrong (long -179 and lat -179 would fit inside your rectangle).


I took the liberty to improve some of your code and fix the comparison operators:

import requests

VEHICLE_LOCATIONS_URL = "https://retro.umoiq.com/service/publicJSONFeed?command=vehicleLocations&a=sf-muni&t=0"
# (min_lat, max_lat), (min_long, max_long)
BOUNDARIES = ((37.748554, 37.769754), (-122.427050, -122.404535))

def get_ids_in_boundry():
    response = requests.get(VEHICLE_LOCATIONS_URL).json()

    id_list = []

    for vehicle in response['vehicle']:
        lat, long = float(vehicle['lat']), float(vehicle['lon'])

        if ((BOUNDARIES[0][0] <= lat <= BOUNDARIES[0][1])
            and (BOUNDARIES[1][0] <= long <= BOUNDARIES[1][1])):
            id_list.append(vehicle['id'])

    return id_list

def main():
    print(get_ids_in_boundry())

if __name__ == "__main__":
    main()

I've changed the URL to be a const, so as the boundaries, and returned the id_list outside of the function. Many other improvements can be added such as asking for boundaries in the function parameter or splitting doing the request and checking the boundaries into 2 different functions.

CodePudding user response:

If I understood everything correctly the aswer is to convert the variables lat and lon to floats.

To do that just modify this in your code

lat = float(i['lat'])
lon = float(i['lon'])
  • Related