1

My script is terribly underdeveloped, I am trying to select cities within a country and then order these cities by their "POP_RANK" = population rank. I am not sure whether to use a searchcursor or just select the features and then use a sort function.

import arcpy
from arcpy import mapping
#set workspace
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
#set the dataframe
fc = ("N:\Lab13\cities.shp")
cities = arcpy.mapping.ListLayers(mxd, "Cities")[0]
cities.showLabels = True
def countryname():
    country = arcpy.GetParameterAsText(0)
    country_layer = arcpy.MakeFeatureLayer_management(fc, "country_lyr")
    arcpy.SelectLayerByAttribute_management(cities, "NEW_SELECTION", "CNTRY_NAME = '{}' ".format(country))
    arcpy.mapping.ListDataFrames(mxd)[0].zoomToSelectedFeatures()
    arcpy.RefreshActiveView()
    arcpy.Delete_management("country_lyr")
try:
    in_dataset = "CNTRY_NAME"
    out_dataset = "country_sort"
    sort_fields = [["POP_RANK", "ASCENDING"]]
    arcpy.Sort_management(in_dataset, out_dataset, sort_fields)
    arcpy.AddMessage("IT WORKED")
2
  • You don't say where the output needs to appear. If it is in a new feature class that appears as a new layer in the map and shows the order through a table view then the Sort tool works best. If it is in a MessageBox then the search cursor works best. Other outputs are also possible. So what is the goal for interacting with the user? May 3, 2016 at 20:14
  • The end goal is the user puts a country in the getparameter within an arcmap tool, then it is supposed to zoom to the country, and gives the user the Median population rank for that country. Some how I have to sort the POP_RANK then calculate the median.
    – lying_hard
    May 3, 2016 at 20:18

1 Answer 1

2

To get the median of the POP_RANK you should use a searchCursor and use list comprehension. The list can then be fed to method that determines the median. I got the method here

Edit: You have created confusion by creating two versions of the cities layer in your code. I have removed the country_layer and instead only use the cities layer, since that is the layer you are actually selecting features from. By eliminating the useless country_layer the code will now produce the expected median.

import arcpy

def median(lst):
    lst = sorted(lst)
    if len(lst) < 1:
            return None
    if len(lst) %2 == 1:
            return lst[((len(lst)+1)/2)-1]
    else:
            return float(sum(lst[(len(lst)/2)-1:(len(lst)/2)+1]))/2.0

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd,"Layers")[0]
#set the dataframe
cities = arcpy.mapping.ListLayers(mxd, "Cities")[0]
cities.showLabels = True
country = arcpy.GetParameterAsText(0)
arcpy.SelectLayerByAttribute_management(cities, "NEW_SELECTION", "CNTRY_NAME = '{}' ".format(country))
arcpy.mapping.ListDataFrames(mxd)[0].zoomToSelectedFeatures()
arcpy.RefreshActiveView()
field = "POP_RANK"
values = [row[0] for row in arcpy.da.SearchCursor(cities, field)]
mid = median(values)
# do something with mid like print it, message box, etc.
2
  • I ran the script and it works, but every outcome I get for the countries is 5. This is not correct because I hand calculated some of them. Can you think of any reason it would do this? Is it calculating the mean for the selected country?
    – lying_hard
    May 3, 2016 at 21:40
  • 1
    I fixed the code. I had based my code on the code you had designed and you had set up 2 city layers, but only selected features in one of them. I had used the wrong layer. I have eliminated the useless layer from the code so that now there is only one layer. The code will work correctly now. May 3, 2016 at 22:56

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.