Meaning Use of Curly Brackets in ArcPy?

3047
10
Jump to solution
06-26-2017 01:45 PM
NealBanerjee
Occasional Contributor

Hello - in a number of P Stand Alone Python examples associated with a number of geoprocessing tools (e.g. Add Feature Class to Terrain), there is some syntax that uses curly brackets that I dont understand and dont see documentation.  In general Python I understand curly brackets are used to define "dictionaries", however use in geoprocessing tools with ArcPy seems different.  Can anyone explain their use or point me to documentation?

Below is example from a tool example that uses curly brackets

Thanks

Neal

Add Feature Class To Terrain (3D Analyst)

# Create the file gdb that will store the feature dataset    
arcpy.management.CreateFileGDB(gdbLocation, gdbName)    
gdb = '{0}/{1}'.format(gdbLocation, gdbName)    
# Obtain spatial reference from TIN    
SR = arcpy.Describe(tin).spatialReference    
# Create the feature dataset that will store the terrain    
arcpy.management.CreateFeatureDataset(gdb, fdName, SR)    
fd = '{0}/{1}'.format(gdb, fdName)    
(...)
0 Kudos
1 Solution

Accepted Solutions
RebeccaStrauch__GISP
MVP Emeritus

Once you get used to it, it makes it much easier to read vs the %s formatting and easier to modify.  For example, some simple samples. 


one = 'one'
two = 'two'
three = 'three'
four = 'four'

print("give me numbers in order: {}, {}, {}, {}".format(one, two, three, four))
# or below....remember a first variable will alwasy be  {0}
print("give me numbers in order: {0}, {1}, {2}, {3}".format(one, two, three, four))
# in reverse without changing order in format first variable is still 'one'
#  but now at the end of the string
print("give me numbers in reverse order: {3}, {2}, {1}, {0}".format(one, two, three, four))
#  to add another variable myNewVar with value zero at the begining of the list
myNewVar = 'zero'
print("give me numbers in order: {4}, {0}, {1}, {2}, {3}".format(one, two, three, four, myNewVar))
# and if you want to mix it up with a numeric variable, the format will make it easier
aNumericVar = 42

print("give me numbers in order: {4}, {0}, {1}, {2}, {3} and a number: {5}".format(one, two, three, four, myNewVar, aNumericVar))

# ## the print statements above return.....

#give me numbers in order: one, two, three, four
#give me numbers in order: one, two, three, four
#give me numbers in reverse order: four, three, two, one
#give me numbers in order: zero, one, two, three, four
#give me numbers in order: zero, one, two, three, four and a number: 42

And as mentioned before, you can repeat the same variable in a message or comment.  I could should you some more complex ways I use it in command, and do that later if you want, but can't right now.  Just let me know.

View solution in original post

10 Replies
DanPatterson_Retired
MVP Emeritus

Neal...

Your script needs to be formatted properly.... but this...

msgs = "ArcPy ERRORS:\n {0}\n".format(arcpy.GetMessages(2))

is an example of the newer python formatting and doesn't make reference to curly brackets use in dictionaries.

Formatting link

and for code formatting

XanderBakker
Esri Esteemed Contributor

In addition to what Dan Patterson  correctly mentions, there are several uses of the curly brackets in your script. Many of those or to create a valid path to a featureclass. Although the use of:

fd = '{0}/{1}'.format(gdb, fdName)

... will create the correct result, it is better to make use of os. See the example below:

import os
fd = os.path.join(gdb, fdName)
RebeccaStrauch__GISP
MVP Emeritus

Check out https://community.esri.com/people/curtvprice/blog/2014/09/25/posting-code-blocks-in-the-new-geonet?s...‌  to maintain the proper spacing and indentation of codes....very importating for Python code and makes it easier for other to comment/answer questions.

If you are talking about the { }  in a line like

fd = '{0}/{1}'.format(gdb, fdName)
the {0} will get the value of the gdb variable, and the {1} will get the value of fdName Although the 0, 1,... are option, I like to use them to get in the visual of how they match up, and it you want to reuse a value you can repeat it's use.  For example, at the end of all my scripts I use
print("\n{0}\n  !!! Success !!!\n{0}\n".format("*" * 19))
to print out

*******************
  !!! Success !!!
*******************

the \n are newline, the {0}   is the value of  the    * character repeated 19 times.

If I wanted to set a variable for the text, and print it out..  I could do this with the same result

myText = "!!! Success !!!"
print("\n{0}\n  {1}\n{0}\n".format(("*" * 19), myText))

Check out Dan Patterson‌  blogs  /blogs/dan_patterson/2016/05/09/the-links?sr=search&searchId=975736be-e0d6-4bc6-b80d-badea240af2a&se...

edit:...pasted the wrong sample...fixed.   Also, Dan beat me to the pucnh....I get too wordy sometimes.

NealBanerjee
Occasional Contributor

Ok - thank you Rebecca and Dan for explanation - that helps with use of curly brackets when coupled with formatting.  But looks like it may also have another use (where not coupled with formatting) in the example. Below is an excerpt from same 'AddFeatureClasstoTerrain' tool where curly brackets may have another meaning/use?  This tool accepts multi-variable parameter (i.e. more than one feature class can be added to terrain).  Maybe it is just a row index or something, but not clear why it is used or if it is necessary.  Any additional thoughts would be greatly appreciated

          inFeatures = "{0} Shape softclip 1 0 10 true false boundary_embed <None> "\

             "false; {1} Shape masspoints 1 0 50 true false points_embed "\              "<None> false; {2} Shape softline 1 0 25 false false lines_embed "\              "<None> false".format(boundary, masspoints, breaklines)

Thanks again!

Neal

  

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

For some reason, you pasted code is still not formatiing correctly....so I'm trying a cut and paste into a quote window

inFeatures = "{0} Shape softclip 1 0 10 true false boundary_embed <None> "\

             "false; {1} Shape masspoints 1 0 50 true false points_embed "\
              "<None> false; {2} Shape softline 1 0 25 false false lines_embed "\  
            "<None> false".format(boundary, masspoints, breaklines)

it is the same priciple.  if you look at eh last line in the command. the

.format(boundary, masspoints, breaklines)

{0}  = value of boundary variable

{1} = masspoints

{2} = breaklines

So, still a formatting issue, just formatting the value for inFeatures

Does that make sense now?

NealBanerjee
Occasional Contributor

Yes!  I had overlooked the format part, but now see is same idea.  Still not totally clear what the value/benefit of doing things this way are, but this helps understand.

Many thanks!

0 Kudos
DanPatterson_Retired
MVP Emeritus

Neal, the benefit is that you don't need to convert/cast inputs to strings as you had to do with other formatting methods.  This approach was backported to python 2.7 some time ago and is referred to as the formatting mini-language which is now supplemented with f- strings

Details for python 3.6 (since 2.7 is 8 years old now) are here 

a = "{} {} {}".format(1, "two", '3')     # without position specification

b = "{2} {1} {0}".format(1, "two", '3')  # with position specification

print(a)
1 two 3

print(b)
3 two 1
RebeccaStrauch__GISP
MVP Emeritus

Once you get used to it, it makes it much easier to read vs the %s formatting and easier to modify.  For example, some simple samples. 


one = 'one'
two = 'two'
three = 'three'
four = 'four'

print("give me numbers in order: {}, {}, {}, {}".format(one, two, three, four))
# or below....remember a first variable will alwasy be  {0}
print("give me numbers in order: {0}, {1}, {2}, {3}".format(one, two, three, four))
# in reverse without changing order in format first variable is still 'one'
#  but now at the end of the string
print("give me numbers in reverse order: {3}, {2}, {1}, {0}".format(one, two, three, four))
#  to add another variable myNewVar with value zero at the begining of the list
myNewVar = 'zero'
print("give me numbers in order: {4}, {0}, {1}, {2}, {3}".format(one, two, three, four, myNewVar))
# and if you want to mix it up with a numeric variable, the format will make it easier
aNumericVar = 42

print("give me numbers in order: {4}, {0}, {1}, {2}, {3} and a number: {5}".format(one, two, three, four, myNewVar, aNumericVar))

# ## the print statements above return.....

#give me numbers in order: one, two, three, four
#give me numbers in order: one, two, three, four
#give me numbers in reverse order: four, three, two, one
#give me numbers in order: zero, one, two, three, four
#give me numbers in order: zero, one, two, three, four and a number: 42

And as mentioned before, you can repeat the same variable in a message or comment.  I could should you some more complex ways I use it in command, and do that later if you want, but can't right now.  Just let me know.

NealBanerjee
Occasional Contributor

That makes sense now - thank you for the prompt and insightful replies!

0 Kudos