Understanding Object Orientation Multiple Periods - object

I have a Object Oritentation quesation.
I have created the following Pandas series:-
import pandas as pd
my_series1 = pd.Series(data = [200,201,202,203], index = ["London", "New York", "London", "Sydney"], name = "Test")
my_series1 is an object from the Class series (I think)
my_series1 has access to methods and properties, one example of this is checking if all the values in the series are unique using the code:-
my_series1.is_unique
I am happy with the above code.
This is where things get confusing, I can check if the index values are also unique using the code:-
mmy_series1.index.is_unique
The code above does not make sense to me, I don't fully understand how the is_unique property can be applied to the index column - I have been assuming that once an object has been created you can access a method by calling the object name followed by a "." and then the name of the function.
This idea of multiple periods is confusing me as i cannot connect the is_unique back to how the class is created.
Also would it be correct to say the following:-
An object has attributes
An object has methods
But are properties of an object??, are object properties and methods the same thing?
Can anyone help?
Thank you.

Related

How to initialize object attributes from an array of strings in Python?

I am supposed to write a class which will allow the user of the script to define what attributes will it's objects have when initializing them by giving it an array of strings like this.
data = Database(tables=['distance', 'speed'])
Then it should be possible to call the class's methods like
data.distance.insert({1: 25, 2: 55})
data.speed.mean()
etc.
I have tried using setattr() this way
data = Database()
tables=['distance', 'speed']
for item in tables:
setattr(data, item, item)
which works, but isn't exactly what it should be.
Any ideas how to do it directly inside the class?

How to avoid duplication of class instances in Python?

What is a good way to avoid duplication of a class instance when it is created using the __init__() function.
This question is a result of this issue.
Context (using employee class example):
Lets say I have an employee class: __init__(self,name,dept)
I also have a method, employee.info(self) that prints out name and dept of any employee.
However a user could just add an employee by calling a=employee(args..). They could do it multiple times using the same instance variable a, but different employee names.
This will cause issues if they try to print a.info(), as each time a different employee name will be printed.
Is there a better way to do this? I know it is possible to have the __init__() "pass" and define a new method to create an instance.
Expect results:
>>Adam=employee('marketing')
>>Adam.info()
>>Adam works in marketing.
OR
>>a=employee('Adam','marketing')
>>a=employee('Mary','marketing')
>>Error: employee instance with identifier "a" already exists.
>>Use employee.update() method to modify existing record.
Is there a cleaner way of doing it? (as you might guess, I am still learning python).
Or is it good practice to write an explicit function (instead of a class method) to add new employees?
what you try is impossible, because in
a=employee('Adam','marketing')
a is not an object but a variable that points to the object employee('Adam','marketing').
When you do
a=employee('Mary','marketing')
you say to python that now, a must now not point to the object employee('Adam','marketing') but to the object employee('Mary','marketing'). And then, if you have no more variable to reference the object employee('Adam','marketing'), the garbage collector will destroy it.
You must consider that in python all is object, but not the variables that are only references to manipulate objects.
I have been racking my brains over the same problem and have finally managed to figure out a workaround :
Create a dictionary that stores the employee name and the related object like this :
total_emp_dict = {}
Add this inside the def __init__ of the class employee : total_emp_dict[name] = self. This will ensure to add each employee name as key and the object associated will be added as value.
Now create a new function outside & before the employee class is defined, let's call it create_new_emp. It will go like this :
#function to check and avoid duplicate assignment of instances
def create_new_emp(name, dept):
if name in total_emp_dict:
return total_emp_dict[name]
else:
return employee(name, dept)
When creating a any new employee, use this new function : a = create_new_emp("Adam", HR) instead of a = employee("Adam", HR)
Explanation : This function will ensure that duplicate assignment is not done. If "a" is already assigned to "Adam", this function will return object of "Adam" to "a", when called again. But if nothing is assigned to "a", then this function will handover to the attributes (name, dept) to employee class and create a new instance. This instance will then be assigned to "a".
I don't know if this is the best solution for this problem, but honestly this is the only solution I have found so far and it works great for me without much fuss / extra code space. Hope it works for you too! :)

How to convert a Hit into a Document with elasticsearch-dsl?

Consider the following mapping for a document in ES.
class MyDoc(elasticseach_dsl.Document):
id_info = Object(IdInfo)
class IdInfo(elasticseach_dsl.InnerDoc):
id = Keyword()
type = Keyword()
Using elasticsearch-dsl, there are 2 ways of retrieving a document (that I am interested in):
Using MyDoc.search().query().execute(), that yields Hit objects
Using MyDoc.get(), that yields a MyDoc object
Here is the issue I am experiencing:
When I retrieve the same document from ES, and that document is missing, for example, the type field, I get different behaviours:
When using search(): doc being a Hit object, accessing doc.type raises a KeyError
When using get(): doc being a MyDoc object, accessing doc.type simply returns None
To workaround this discrepancy, I would like to convert a Hit instance to a MyDoc instance, so that I can always use the doc.type syntax without any errors being raised.
How can I do that?
Alternatively, is there a way that I could access Hit instances with the same behaviour as MyDoc instances?
dict_hit = hit.to_dict()
doc = YourDocument(**dict_hit)
doc.property1 # you can access the property here
I know it is a bit awkward and annoying, it used to work with versions below 6.
I found a workaround, if you take the dictionary coming out from elasticsearch response you can then ask the document class to interpret it like the following.
query = MyDoc.search()
response = query.execute()
my_doc = MyDoc.from_es(response.hits.hits[0])
We were facing this situation. In our case, is was due to the index name in the Index subclass to configure Document indices. Our model looked more or les like this:
class MyDoc(Document):
my_field = Keyword()
class Index:
name = "my-doc-v1-*"
This way, when querying for documents in indexes that match that name (for example "my-doc-v1-2022-07"), hits are automatically instantianted as MyDoc objects.
Now we have started to generate 'v2' indices, named like "my-doc-v2--000001", and then hits were not being populated as MyDoc objects.
For that to happen, we had to change Index.name to my-doc-*. That way, documents from both 'v1' and 'v2' indices are always populated automatically by the library, since they match the Index.name expression.

In Spotfire, how to trellis a SummaryTable using IronPython script

I am trying to "trellis" a summary table using a script. The TrellisVisualization is not available for the SummaryTable class. Using the GUI, I can trellis a summary table by assigning a specific column to the Categorization property under Columns Properties. However, while using the IronPython script, I don't see any property named Categorization for the SummaryTable object. So, I tried assigning the column to the CategoryAxis as follows:
mySummaryTable.CategoryAxis = "<[myColumn]>"
But this throws an error:
AttributeError: 'SummaryTable' object has no attribute 'CategoryAxis'
I also tried using Axis or CategoricalAxisBase etc. as properties, but these options did not work out. If anyone has more ideas on this, please let me know. Thanks.
RD
The key issue here is that the CategoryAxis property underneath the Summary Table class is a GET of this visual's object of the GroupByAxis class. You can see this by using the print command and getting information about the object:
print mySummaryTable.CategoryAxis
results in my Spotfire example:
<Spotfire.Dxp.Application.Visuals.GroupByAxis object at 0x000000000000002C [Spotfire.Dxp.Application.Visuals.GroupByAxis]>
You were actually quite close though. In order to set the CategoryAxis you need to set the Expression property of the CategoryAxis like so:
from Spotfire.Dxp.Application.Visuals import SummaryTable
mySummaryTable = myVisual.As[SummaryTable]()
mySummaryTable.CategoryAxis.Expression = "<[COLUMN]>"
If you need to pass an actual column name into that rather than hardcoded, I would concatenate the expression syntax and set the Expression equal to that variable:
myColumnExp = "<[" + myColumnName + "]>"
mySummaryTable.CategoryAxis.Expression = myColumnExp
Please let me know if you need any clarity regarding this. My Spotfire version for this answer is v6.5.2.26 and my API information from https://docs.tibco.com/pub/doc_remote/spotfire/6.5.0/api/Index.aspx

Retrieving Properties from DbSqlQuery

Background: Project is a Data Import utility for importing data from tsv files into a EF5 DB through DbContext.
Problem: I need to do a lookup for ForeignKeys while doing the import. I have a way to do that but the retrieval if the ID is not functioning.
So I have a TSV file example will be
Code Name MyFKTableId
codevalue namevalue select * from MyFKTable where Code = 'SE'
So when I process the file and Find a '...Id' column I know I need to do a lookup to find the FK The '...' is always the entity type so this is super simple. The problem I have is that I don't have access to the properties of the results of foundEntity
string childEntity = column.Substring(0, column.Length - 2);
DbEntityEntry recordType = myContext.Entry(childEntity.GetEntityOfReflectedType());
DbSqlQuery foundEntity = myContext.Set(recordType.Entity.GetType()).SqlQuery(dr[column])
Any suggestion would be appreciated. I need to keep this generic so we can't use known type casting. The Id Property accessible from IBaseEntity so I can cast that, but all other entity types must be not be fixed
Note: The SQL in the MyFKTableId value is not a requirement. If there is a better option allowing to get away from SqlQuery() I would be open to suggestions.
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();
SOLVED:
Ok What I did was create a Class called IdClass that only has a Guid Property for Id. Modified my sql to only return the Id. Then implemented the SqlQuery(sql) call on the Database rather than the Set([Type]).SqlQuery(sql) like so.
IdClass x = ImportFactory.AuthoringContext.Database.SqlQuery<IdClass>(sql).FirstOrDefault();

Resources