NAME is not defined when defining class arcpy - arcpy

I am having an issue I have not had before creating a class with a method as below;
class Points:
def __init__(self, inFC, buffDist, sector): #Must have a set of points and a value to buffer these by. Also, sector.
self.inFC = inFC
self.buffDist = buffDist
self.sector = sector
def getCoords(self): #getting the coordinates of the points.
fc = self.inFC
fields = ['SHAPE#XY']
coordsList = []
with arcpy.da.SearchCursor(fc, fields) as rows:
coordsList = [r[0] for r in rows]
self.coordsList = coordsList
del coordsList
The class is created and the method called from this code at the end of my script;
if __name__ == '__main__':
inFC = arcpy.GetParameterAsText(0)
buffDist = arcpy.GetParameterAsText(1)
sector = arcpy.GetParameterAsText(2)
outFC_data = arcpy.GetParameterAsText(3)
fcName = outFC_data.rpartition("\\")[2]
fcPath = outFC_data.rpartition("\\")[0]
outFC = arcpy.CreateFeatureclass_management(fcPath, fcName, "POLYGON")
pointobject = Points(inFC, buffDist, sector)
pointobject.getCoords()
This returns the error "fc is not defined" at the line fc = self.inFC.
OR
if I remove "fc = self.InFC" and replace fc with self.inFC within SearchCursor then I get an error at the line "with arcpy.da.SearchCursor(self.inFC, fields)" that states "self.inFC is not defined".
I have tried pasting the class definition directly into the python interpreter (ArcCatalog->Geoprocessing->Python) but the errors remain the same, so I do not even get to the point of creating an instance of the class, the error is within the actual code of my class and method definition.
What is the error in my code or my approach?

The problem is your input parameter. Since I'm guessing that you're doing your debugging in ArcMap (don't do that btw, use PyScripter, PyCharm or at least IDLE) you can use arcpy.AddMessage(string) to view the value of that parameter in the geoprocessing results messages, which in the case of a feature class should look like a file path. I'd stick one of these before initializing the class, and once right before the point of failure as well. Let me know what happens!

Related

Is it possible to get the name of variable in Groovy?

I would like to know if it is possible to retrieve the name of a variable.
For example if I have a method:
def printSomething(def something){
//instead of having the literal String something, I want to be able to use the name of the variable that was passed
println('something is: ' + something)
}
If I call this method as follows:
def ordinary = 58
printSomething(ordinary)
I want to get:
ordinary is 58
On the other hand if I call this method like this:
def extraOrdinary = 67
printSomething(extraOrdinary)
I want to get:
extraOrdinary is 67
Edit
I need the variable name because I have this snippet of code which runs before each TestSuite in Katalon Studio, basically it gives you the flexibility of passing GlobalVariables using a katalon.features file. The idea is from: kazurayam/KatalonPropertiesDemo
#BeforeTestSuite
def sampleBeforeTestSuite(TestSuiteContext testSuiteContext) {
KatalonProperties props = new KatalonProperties()
// get appropriate value for GlobalVariable.hostname loaded from katalon.properties files
WebUI.comment(">>> GlobalVariable.G_Url default value: \'${GlobalVariable.G_Url}\'");
//gets the internal value of GlobalVariable.G_Url, if it's empty then use the one from katalon.features file
String preferedHostname = props.getProperty('GlobalVariable.G_Url')
if (preferedHostname != null) {
GlobalVariable.G_Url = preferedHostname;
WebUI.comment(">>> GlobalVariable.G_Url new value: \'${preferedHostname}\'");
} else {
WebUI.comment(">>> GlobalVariable.G_Url stays unchanged");
}
//doing the same for other variables is a lot of duplicate code
}
Now this only handles 1 variable value, if I do this for say 20 variables, that is a lot of duplicate code, so I wanted to create a helper function:
def setProperty(KatalonProperties props, GlobalVariable var){
WebUI.comment(">>> " + var.getName()" + default value: \'${var}\'");
//gets the internal value of var, if it's null then use the one from katalon.features file
GlobalVariable preferedVar = props.getProperty(var.getName())
if (preferedVar != null) {
var = preferedVar;
WebUI.comment(">>> " + var.getName() + " new value: \'${preferedVar}\'");
} else {
WebUI.comment(">>> " + var.getName() + " stays unchanged");
}
}
Here I just put var.getName() to explain what I am looking for, that is just a method I assume.
Yes, this is possible with ASTTransformations or with Macros (Groovy 2.5+).
I currently don't have a proper dev environment, but here are some pointers:
Not that both options are not trivial, are not what I would recommend a Groovy novice and you'll have to do some research. If I remember correctly either option requires a separate build/project from your calling code to work reliable. Also either of them might give you obscure and hard to debug compile time errors, for example when your code expects a variable as parameter but a literal or a method call is passed. So: there be dragons. That being said: I have worked a lot with these things and they can be really fun ;)
Groovy Documentation for Macros
If you are on Groovy 2.5+ you can use Macros. For your use-case take a look at the #Macro methods section. Your Method will have two parameters: MacroContext macroContext, MethodCallExpression callExpression the latter being the interesting one. The MethodCallExpression has the getArguments()-Methods, which allows you to access the Abstract Syntax Tree Nodes that where passed to the method as parameter. In your case that should be a VariableExpression which has the getName() method to give you the name that you're looking for.
Developing AST transformations
This is the more complicated version. You'll still get to the same VariableExpression as with the Macro-Method, but it'll be tedious to get there as you'll have to identify the correct MethodCallExpression yourself. You start from a ClassNode and work your way to the VariableExpression yourself. I would recommend to use a local transformation and create an Annotation. But identifying the correct MethodCallExpression is not trivial.
no. it's not possible.
however think about using map as a parameter and passing name and value of the property:
def printSomething(Map m){
println m
}
printSomething(ordinary:58)
printSomething(extraOrdinary:67)
printSomething(ordinary:11,extraOrdinary:22)
this will output
[ordinary:58]
[extraOrdinary:67]
[ordinary:11, extraOrdinary:22]

Find a value in a collection and assign top an variable using groovy

Hello Groovy Experts,
I am using the below command to get all the ODI Dataservers.
def PSchema=DServer.getPhysicalSchemas();
When I print the PSchema variable I getting the following values.
[oracle.odi.domain.topology.OdiPhysicalSchema ABC.X1, oracle.odi.domain.topology.OdiPhysicalSchema ABC.X2]
What I am trying to achieve here I will be passing X1 or X2 during runtime...
And then I want to validate this value with the PSchema result and the print the following value:
oracle.odi.domain.topology.OdiPhysicalSchema ABC.X2
I tried using the following options:
def PSchema44 = PSchema11.findIndexValues { it =~ /(X1)/ }
def pl=PSchema11.collect{if(it.contains ('X1)){return it}}
I tried for loop to check whether values are getting printed properly ..result is fine:
for (item in PSchema11 )
{
println item
}
Assuming 'X1' and 'X2' are the names for the physical schemas, you should be able to do something like this:
def phys = "X1"
def pSchemas = dServer.getPhysicalSchemas()
def schema = pSchemas.find{it.schemaName == phys}
also I guess you are new to Groovy, I suggest you read up on syntax and naming conventions. For example, variable names should always start with a lower case letter

Python use of class to create and manipulate a grid

Still trying to understand how to use class. I have now written the following:
`import random
class Grid():
def __init__(self, grid_row, grid_column):
self.__row = grid_row
self.__col = grid_column
self.__board=[]
def make_board(self):
for row in range(self.__row):
self.__board.append([])
for col in range(self.__col):
self.__board[row].append('0')
return self.__board
def change_tile(self):
choices = (0,1,2)
x = random.choice(choices)
y= random.choice(choices)
self.__board[x][y] = str(2)
def __repr__(self):
for row in self.__board:
print( " ".join(row))
g = Grid(3,3)
g.make_board()
g.change_tile()
print(g)
Firstly when I run this I get a grid printed followed by:
TypeError: __str__ returned non-string (type NoneType)
I don't understand why this happens. Second question. If I want to return the self.board, __str only returns the last row (0,0,0).With 'print' all three rows and columns are printed. Is there a way around the issue with 'return'?Is it an issue ( apart from the fact that I want to 'see' what I am doing)?
How would one call Grid(3,3) and get a grid with a randomly placed 2 without having to call each function separately as I have done in my example? Lastly why can I not use the integers 0 or 2, but have to convert everything to a string?. I hope that I have not exceeded the goodwill that exists on this forum by asking so many dumb questions!
The special methods __repr__ and __str__ are required to return a string. If there is no __str__ implementation given, the __repr__ will be used for the string conversion too.
Now in your case, __repr__ prints something instead of returning a string. It actually returns nothing, so None is implicitely returned. You have to change it to return a string. For example like this:
def __repr__(self):
return '\n'.join([' '.join(row) for row in self.__board])

Python:How can i make an instance of an class with a dictionary?

bare in mind please that i'm a beginner in programing.
I made the following piece of code and it doesn't work. I assume it has to do with the creation of the room1 instance of Locations.
Here's the code:
class Location:
def __init__ (self, name, description, location, **actions):
self.name = name
self.description = description
self.location = location
self.actions = actions
def test (self):
self.actions = actions
print (actions)
x = type(actions)
print (x)
room1 = Location("Bedroom","First Room",1,S="Search", M="Move")
room1.test()
You need to pass the dictionary as such:
Location("Bedroom", "First Room", 1, {"S":"Search", "M":"Move"})
EDIT:
Okay, so I see where things are going wrong for you.
You want to change your test method to look like:
def test (self):
print (self.actions)
x = type(self.actions)
print (x)
You don't need to reassign self.actions in the method, it's already been initialized.

lldb & synthetic provider: follow pointer

I have a custom class called Values that is a wrapper of arrays. For a given object vFoo of class Values, which contains an array of objects of class Foo, the var format -T vFoocommand returns the following structure:
(MyNameSpace::Values) vFoo = {
(void *) p = 0x0000000100204378
(size_t) n = 2
(MyNameSpace::ValueType) type = FOO
}
where vFoo.p is a pointer to the array<Foo> that contains 2 elements. I can access the array elements with the following command in the lldb prompt:
expression ((MyNameSpace::Foo*)vFoo.p)[0]
which returns
(MyNameSpace::Foo) $0 = "foo"
according to my summary provider.
I would like to write a synthetic child provider that returns something like:
(MyNameSpace::Values) vFoo = {
(MyNameSpace::Foo) vFoo.p[0] = "foo"
(MyNameSpace::Foo) vFoo.p[1] = "bar"
}
Unfortunately, I have no idea how to do that. I read the lldb data formatters page and try to follow the structure given at the end of the page. I have also had a look at the bitfield and libcxx examples, but I can't find my way to the solution. Any help would be deeply appreciated!
Many thanks in advance
You need to get the internal representation of the type Foo. You can get this from the SBModule using self.valobj.GetFrame().GetModule().FindFirstType("Foo"). Something like this will work with some poking around.
class Values_SynthProvider:
def __init__(self, valobj, dict):
self.valobj = valobj
self.num_elements = None
def update(self):
self.num_elements = self.valobj.GetChildMemberWithName('n').GetValueAsUnsigned(0)
def num_children(self):
return self.num_elements
def get_child_at_index(self,index):
# Here you could switch on the value of Values::type to get the right type name to search for
foo_type = self.valobj.GetFrame().GetModule().FindFirstType("Foo")
return self.valobj.GetChildMemberWithName('p').Cast(foo_type.GetPointerType()).GetChildAtIndex(index,0,True)
def get_child_index(self,name):
return int(name.lstrip('[').rstrip(']'))

Resources