def stns_near_lat_lon(latitude, longitude, year, N=20, id_filter=None):
    """
    latitude: float -> latitude of weather location
    longitude: negative float, coerced to negative if positive -> longitude of weather location
    year: int -> the year of desired weather data
    N: int -> number of desired results
    id_filter: function that returns station ids filtered on some condition

    displays information about the N closest stations to the given coordinates
    """
    latitude = float(latitude)
    longitude = float(longitude)
    if longitude > 0.:
        longitude = -1. * longitude
    lines = [" ".join(['   ', "Station ID".ljust(12), "Station Name".ljust(30), "    ", "Dist. (miles)"]) + "\n"]
    def show_stn(stn_id, rank):
        d = stns[stn_id]
        info_str = " ".join([(str(rank)+".").ljust(3),
                             stn_id.ljust(12),
                             stns[stn_id]['name'].ljust(30),
                             stns[stn_id]['state'].ljust(4),
                             str(round(haversine(latitude, longitude, stns[stn_id]['lat'], stns[stn_id]['lon']), 1))]) + "\n"
        return info_str
    stn_ids = [_id for _id in stns if int(stns[_id]['sd'].year) <= year and int(stns[_id]['ed'].year) >= year]
    # optionally filter station ids
    if id_filter:
        stn_ids = id_filter(stn_ids)
    _ids = sorted(stn_ids, key=lambda _id: haversine(latitude, longitude, stns[_id]['lat'], stns[_id]['lon']))[:N]
    lines += [show_stn(_id, j) for j, _id in enumerate(_ids)]
    if len(lines) > 1:
        print "".join(lines)
    else:
        print "No stations were found that matched these criteria."
 def show_stn(stn_id, rank):
     d = stns[stn_id]
     info_str = " ".join([(str(rank)+".").ljust(3),
                          stn_id.ljust(12),
                          stns[stn_id]['name'].ljust(30),
                          stns[stn_id]['state'].ljust(4),
                          str(round(haversine(latitude, longitude, stns[stn_id]['lat'], stns[stn_id]['lon']), 1))]) + "\n"
     return info_str
 def show_stn(stn_id, rank):
     d = stns[stn_id]
     info_str = " ".join(
         [(str(rank) + ".").ljust(3),
          stn_id.ljust(12), stns[stn_id]['name'].ljust(30),
          stns[stn_id]['state'].ljust(4),
          str(
              round(
                  haversine(latitude, longitude, stns[stn_id]['lat'],
                            stns[stn_id]['lon']), 1))]) + "\n"
     return info_str
def stns_near_lat_lon(latitude, longitude, year, N=20, id_filter=None):
    """
    latitude: float -> latitude of weather location
    longitude: negative float, coerced to negative if positive -> longitude of weather location
    year: int -> the year of desired weather data
    N: int -> number of desired results
    id_filter: function that returns station ids filtered on some condition

    displays information about the N closest stations to the given coordinates
    """
    latitude = float(latitude)
    longitude = float(longitude)
    if longitude > 0.:
        longitude = -1. * longitude
    lines = [
        " ".join([
            '   ', "Station ID".ljust(12), "Station Name".ljust(30), "    ",
            "Dist. (miles)"
        ]) + "\n"
    ]

    def show_stn(stn_id, rank):
        d = stns[stn_id]
        info_str = " ".join(
            [(str(rank) + ".").ljust(3),
             stn_id.ljust(12), stns[stn_id]['name'].ljust(30),
             stns[stn_id]['state'].ljust(4),
             str(
                 round(
                     haversine(latitude, longitude, stns[stn_id]['lat'],
                               stns[stn_id]['lon']), 1))]) + "\n"
        return info_str

    stn_ids = [
        _id for _id in stns if int(stns[_id]['sd'].year) <= year
        and int(stns[_id]['ed'].year) >= year
    ]
    # optionally filter station ids
    if id_filter:
        stn_ids = id_filter(stn_ids)
    _ids = sorted(stn_ids,
                  key=lambda _id: haversine(latitude, longitude, stns[_id][
                      'lat'], stns[_id]['lon']))[:N]
    lines += [show_stn(_id, j) for j, _id in enumerate(_ids)]
    if len(lines) > 1:
        print "".join(lines)
    else:
        print "No stations were found that matched these criteria."