Creating Object With A For Loop - python

Firstly, I do apologise as I'm not quite sure how to word this query within the Python syntax. I've just started learning it today having come from a predominantly PowerShell-based background.
I'm presently trying to obtain a list of projects within our organisation within Google Cloud. I want to display this information in two columns: project name and project number - essentially an object. I then want to be able to query the object to say: where project name is "X", give me the project number.
However, I'm rather having difficulty in creating said object. My code is as follows:
import os
from pprint import pprint
from googleapiclient import discovery
from oauth2client.client import GoogleCredentials
credentials = GoogleCredentials.get_application_default()
service = discovery.build('cloudresourcemanager', 'v1', credentials=credentials)
request = service.projects().list()
response = request.execute()
projects = response.get('projects')
The 'projects' variable then seems to be a list, rather than an object I can explore and run queries against. I've tried running things like:
pprint(projects.name)
projects.get('name')
Both of which return the error:
"AttributeError: 'list' object has no attribute 'name'"
I looked into creating a Class within a For loop as well, which nearly gave me what I wanted, but only displayed one project name and project number at a time, rather than the entire collection I can query against:
projects=[]
for project in response.get('projects', []):
class ProjectClass:
name = project['name']
projectNumber = project['projectNumber']
projects.append(ProjectClass.name)
projects.append(ProjectClass.projectNumber)
I thought if I stored each class in a list it might work, but alas, no such joy! Perhaps I need to have the For loop within the class variables?
Any help with this would be greatly appreciated!

As #Code-Apprentice mentioned in a comment, I think you are missing a critical understanding of object-oriented programming, namely the difference between a class and an object. Think of a class as a "blueprint" for creating objects. I.E. your class ProjectClass tells python that objects of type ProjectClass will have two fields, name and projectNumber. However, ProjectClass itself is just the blueprint, not an object. You then need to create an instance of ProjectClass, which you would do like so:
project_class_1 = ProjectClass()
Great, now you have an object of type ProjectClass, and it will have fields name and projectNumber, which you can reference like so:
project_class_1.name
project_class_1.projectNumber
However, you will notice that all instances of the class that you create will have the same value for name and projectNumber, this just won't do! We need to be able to specify values when we create each instance. Enter init(), a special python method colloquially referred to as the constructor. This function is called by python automatically when we create a new instance of our class as above, and is responsible for setting up all the fields of that class. Another powerful feature of classes and objects is that you can define a collection of different functions that can be called at will.
class ProjectClass:
def __init__(self, name, projectNumber):
self.name = name
self.projectNumber = projectNumber
Much better. But wait, what's that self variable? Well, just as before we were able reference the fields of our instance via the "project_class_1" variable name, we need a way to access the fields of our instance when we're running functions that are a part of that instance, right? Enter self. Self is another python builtin parameter that contains a reference to the current instance of the ProjectClass that is being accessed. That way, we can set fields on the instance of the class that will persist, but not be shared or overwritten by other instances of the ProjectClass. It's important to remember that the first argument passed to any function defined on a class will always be self (except for some edge-cases you don't need to worry about now).
So restructuring your code, you would have something like this:
class ProjectClass:
def __init__(self, name, projectNumber):
self.name = name
self.projectNumber = projectNumber
projects = []
for project in response.get('projects', []):
projects.append(ProjectClass(project["name"], project["projectNumber"])
Hopefully I've explained this well and given you a complete answer on how all these pieces fit together. The hope is for you to be able to write that code on your own and not just give you the answer!

Related

Drawbacks of executing code in an SQLAlchemy managed session and if so why?

I have seen different "patterns" in handling this case so I am wondering if one has any drawbacks comapred to the other.
So lets assume that we wish to create a new object of class MyClass and add it to the database. We can do the following:
class MyClass:
pass
def builder_method_for_myclass():
# A lot of code here..
return MyClass()
my_object=builder_method_for_myclass()
with db.managed_session() as s:
s.add(my_object)
which seems that only keeps the session open for adding the new object but I have also seen cases where the entire builder method is called and executed within the managed session like so:
class MyClass:
pass
def builder_method_for_myclass():
# A lot of code here..
return MyClass()
with db.managed_session() as s:
my_object=builder_method_for_myclass()
are there any downsides in either of these methods and if yes what are they? Cant find something specific about this in the documentation.
When you build objects depending on objects fetched from a session you have to be in a session. So a factory function can only execute outside a session for the simplest cases. Usually you have to pass the session around or make it available on a thread local.
For example in this case to build a product I need to fetch the product category from the database into the session. So my product factory function depends on the session instance. The new product is created and added to the same session that the category is also in. An implicit commit should also occur when the session ends, ie the context manager completes.
def build_product(session, category_name):
category = session.query(ProductCategory).where(
ProductCategory.name == category_name).first()
return Product(category=category)
with db.managed_session() as s:
my_product = build_product(s, "clothing")
s.add(my_product)

What is the best way to access other class's variable in python?

Learning class in python, using below github(https://github.com/gurupratap-matharu/Bike-Rental-System), I cloned it and I try to add database class. I did it and it works. But I don't think I did it correctly (pythonically or object oriented correctly). Can someone please do a code review? ( https://github.com/isolveditalready/PLAYGROUND ) I am espescailly not sure if using another class's variable in another class( in dbAction.py, line 15)
Basically, I needed to access another class's variable(From class BikeRental class, variable named stock) from dbActionMe class and I didn't know how so I just passed that variable into dbActionMe class.
If code review is not possible, can someone please review below to see what I could have done differently?
db = dbActionMe()
numOfBikes = db.dbRead()
shop = BikeRental(numOfBikes)
customer = Customer()
...
db.dbUpdate(shop.stock)

Reset sync_reasoner inferences

I am using the owlready2 python module on a local ontology.
I have connected an API endpoint, to submit queries on this ontology.
I need to submit some queries on the original ontology and some other on the updated (with the inferences) ontology.
When I use the sync_reasoner() function, the ontology is updated with the inferences made by HermiT (i.e. the default reasoner).
My issue is, that the inferences made by the reasoner persist among different calls to the attached function.
Is there a workaround to force reset the inferred properties?
def function():
onto = get_ontology("file:///path/file.owl").load()
namespace = onto.get_namespace("http://namespace")
do_operations_with_original_ontology()
with namespace:
sync_reasoner()
do_operations_with_UPDATED_ontology()
return None
Thank you for considering my question,
Argyris
Though I did not use extensively the reasoner functionalities of owlready2 I believe this is the same as for any ontology update using owlready2.
Basically in owlready2, to separate different ontologies or different versions of the same ontology (potentially making use of different namespaces) you need to put them in different "worlds". The syntax is described here.
Here is some code based on the documentation examples to give you an idea of the syntax
from owlready2 import *
world = World()
onto = world.get_ontology("http://test.org/onto.owl")
with onto:
class Drug(Thing):
pass
class ActivePrinciple(Thing):
pass
class has_for_active_principle(Drug >> ActivePrinciple):
pass
class someActivePrinciple(ActivePrinciple):
pass
class MyDrug(Drug):
has_for_active_principle = [someActivePrinciple] #this one has some property restriction
# let's separate the worlds
world2 = World()
onto2 = world2.get_ontology("http://test.org/onto.owl")
with onto2:
class Drug(Thing):
pass
class ActivePrinciple(Thing):
pass
class has_for_active_principle(Drug >> ActivePrinciple):
pass
class someActivePrinciple(ActivePrinciple):
pass
class MyDrug(Thing): # not a subClass of Drug
pass # missing the has_for_active_principle restriction
# now we can save without mixing the ontologies
onto.save(file=r"c:\temp\owlready.rdf", format="rdfxml")
onto2.save(file=r"c:\temp\owlready2.rdf", format="rdfxml")
Note that there is currently a bug which prevents from directly saving the "worlds", only the ontology can be saved, but the bug was already corrected in the development version. See the owlready forum relevant discussion

python load from shelve - can I retain the variable name?

I'm teaching myself how to write a basic game in python (text based - not using pygame). (Note: I haven't actually gotten to the "game" part per-se, because I wanted to make sure I have the basic core structure figured out first.)
I'm at the point where I'm trying to figure out how I might implement a save/load scenario so a game session could persist beyond a signle running of the program. I did a bit of searching and everything seems to point to pickling or shelving as the best solutions.
My test scenario is for saving and loading a single instance of a class. Specifically, I have a class called Characters(), and (for testing's sake) a sigle instance of that class assigned to a variable called pc. Instances of the Character class have an attribute called name which is originally set to "DEFAULT", but will be updated based on user input at the initial setup of a new game. For ex:
class Characters(object):
def __init__(self):
self.name = "DEFAULT"
pc = Characters()
pc.name = "Bob"
I also have (or will have) a large number of functions that refer to various instances using the variables they are asigned to. For example, a made up one as a simplified example might be:
def print_name(character):
print character.name
def run():
print_name(pc)
run()
I plan to have a save function that will pack up the pc instance (among other info) with their current info (ex: with the updated name). I also will have a load function that would allow a user to play a saved game instead of starting a new one. From what I read, the load could work something like this:
*assuming info was saved to a file called "save1"
*assuming the pc instance was shelved with "pc" as the key
import shelve
mysave = shelve.open("save1")
pc = mysave["pc"]
My question is, is there a way for the shelve load to "remember" the variable name assotiated with the instance, and automatically do that << pc = mysave["pc"] >> step? Or a way for me to store that variable name as a string (ex as the key) and somehow use that string to create the variable with the correct name (pc)?
I will need to "save" a LOT of instances, and can automate that process with a loop, but I don't know how to automate the unloading to specific variable names. Do I really have to re-asign each one individually and explicitly? I need to asign the instances back to the apropriate variable names bc I have a bunch of core functions that refer to specific instances using variable names (like the example I gave above).
Ideas? Is this possible, or is there an entirely different solution that I'm not seeing?
Thanks!
~ribs
Sure, it's possible to do something like that. Since a shelf itself is like a dictionary, just save all the character instances in a real dictionary instance inside it using their variable's name as the key. For example:
class Character(object):
def __init__(self, name="DEFAULT"):
self.name = name
pc = Character("Bob")
def print_name(character):
print character.name
def run():
print_name(pc)
run()
import shelve
mysave = shelve.open("save1")
# save all Character instances without the default name
mysave["all characters"] = {varname:value for varname,value in
globals().iteritems() if
isinstance(value, Character) and
value.name != "DEFAULT"}
mysave.close()
del pc
mysave = shelve.open("save1")
globals().update(mysave["all characters"])
mysave.close()
run()

Get field value within Flask-MongoAlchemy Document

I've looked at documentation, and have searched Google extensively, and haven't found a solution to my problem.
This is my readRSS function (note that 'get' is a method of Kenneth Reitz's requests module):
def readRSS(name, loc):
linkList = []
linkTitles = list(ElementTree.fromstring(get(loc).content).iter('title'))
linkLocs = list(ElementTree.fromstring(get(loc).content).iter('link'))
for title, loc in zip(linkTitles, linkLocs):
linkList.append((title.text, loc.text))
return {name: linkList}
This is one of my MongoAlchemy classes:
class Feed(db.Document):
feedname = db.StringField(max_length=80)
location = db.StringField(max_length=240)
lastupdated = datetime.utcnow()
def __dict__(self):
return readRSS(self.feedname, self.location)
As you can see, I had to call the readRSS function within a function of the class, so I could pass self, because it's dependent on the fields feedname and location.
I want to know if there's a different way of doing this, so I can save the readRSS return value to a field in the Feed document. I've tried assigning the readRSS function's return value to a variable within the function __dict__ -- that didn't work either.
I have the functionality working in my app, but I want to save the results to the Document to lessen the load on the server (the one I am getting my RSS feed from).
Is there a way of doing what I intend to do or am I going about this all wrong?
I found out the answer. I needed to make use of a computed_field decorator, where the first argument was the structure of my return value and deps was a set which contained the fields that this field was dependent on. I then passed the dependent fields into a function's arguments and there you have it.
#fields.computed_field(db.KVField(db.StringField(), db.ListField(db.TupleField(db.StringField()))), deps=[feedname, location])
def getFeedContent(a=[feedname, location]):
return readRSS(a['feedname'], a['location'])
Thanks anyway, everyone.

Categories