I used the exec() function and the for loop to create various class objects and store them in variables.
I think the variables were created successfully as shown in the vs code log, but when I try to access it to change the value or print it, I get this error (name 'membro_1' is not defined) as if it's not defined
What did i do wrong here? how can i access those variables? Is there another better way to create all these objects?
see the variables defined at left
the code from image
class Membros:
def __init__(self, tag, pontos=0) -> None:
self.tag = tag
self.pontos = pontos
# war_cla_member have a len() of 47
war_cla_members = ['#VYQPR', '#82PP2LL20', '#LP0RVCPLV', '#LUVQQ2G2', '#PRP20LUL', '#8GUY0V92R',
'#Y02UVP0UV', '#9U0J8GVJL', '#9P2GGVR9Y', '#20QRJLVU8', '#QRYPRQGP9', '#8GRVUG8', '#PCJYUP2L8', '#22VJPRQRL', '#RJQ8JQ8QR', '#2CVR9C2U9', '#PG2UGPJP', '#L0QG9CG2U', '#9R0PR9Q0U', '#2G8VGQ208', '#8GJ8PGY0C', '#9QLLPJQ90', '#C9PGG8JC', '#8YG8RJV90', '#9YLLQLJGU', '#2GQQ2PU92', '#2PYU080Q', '#22QCRQCPG', '#C9JRU9U2', '#9JQLPGLJJ', '#8RR8QVR09', '#9QY2CLVJR', '#U0V0G2YY', '#28PR280CJ', '#P2RC2G9CL', '#9QVVY2P8', '#CVUGYPCP', '#9PVYQP080', '#29P2V8GLJ', '#YUJ88YRU', '#2RU0UGCUU', '#Y08LY8GJY', '#9R00QQU20', '#P08UJ920', '#2C00L02RU', '#YYQP9JGVC', '#YLULUC8L']
for idx, val in enumerate(war_cla_members):
exec(f'membro_{idx} = Membros("{val}")')
for idx, _ in enumerate(war_cla_members):
if current_river_race['clan']['participants'][idx]['tag'] in war_cla_members: #current_river_race is the return of the clashroyale api request. (https://developer.clashroyale.com/#/documentation)
membro_1.pontos = current_river_race['clan']['participants'][idx]['decksUsedToday']
Related
I am using a Python package which read some type of data. From the data, it creates attributes to easily access meta-information related to the data.
How can create a short name to an attribute?
Basically let's assume the package name is read_data and it has an attribute named data_header_infomation_x_location
import read_data
my_data = read_data(file_path)
How can I instead create a short name to this attribute?
x = "data_header_infomation_x_location"
my_data[1].x gives an error no attribute
Here is a full example from my case
from obspy.io.segy.core import _read_segy
file_path = "some_file_in_my_pc)
sgy = _read_segy(file_path, unpack_trace_headers=True)
sgy[1].stats.segy.trace_header.x_coordinate_of_ensemble_position_of_this_trace
The last line gives a number. e.g., x location
what I want is to rename all this long nested attribute stats.segy.trace_header.x_coordinate_of_ensemble_position_of_this_trace with a short name.
trying for example
attribute = "stats.segy.trace_header.x_coordinate_of_ensemble_position_of_this_trace"
getattr(sgy[1], attribute )
does not work
how about:
from obspy.io.segy.core import _read_segy
attribute_tree_x = ['stats', 'segy', 'trace_header', 'x_coordinate_of_ensemble_position_of_this_trace']
def get_nested_attribute(obj, attribute_tree):
for attr in attribute_tree:
obj = getattr(obj, attr)
return obj
file_path = "some_file_in_my_pc"
sgy = _read_segy(file_path, unpack_trace_headers=True)
sgy[1].stats.segy.trace_header.x_coordinate_of_ensemble_position_of_this_trace
x = get_nested_attribute(sgy[1], attribute_tree_x) # should be the same as the line above
You cannot request the attribute of the attribute in one go, but this loops through the layers to obtain the final value you are looking for.
I first wrote the necessary code to get the information I wanted from the internet, and it works. But now I'm trying to make the code look a bit nicer, therefore I want to put it into functions that are in a class. But I'm a bit confused when it comes to the usages of self and _init_. Currently, the code isn't working as I want, meaning it isn't adding the information to my dictionary.
As I have understood, you have to add self as a parameter in every function you create in a class. But I don't think I'm using the _init_ in a correct way.
from bs4 import BeautifulSoup
import requests
# Importing data from Nasdaq
page_link = "https://www.nasdaq.com/symbol/aapl/financials?query=balance-sheet"
page_response = requests.get(page_link, timeout=1000)
page_content = BeautifulSoup(page_response.content, "lxml")
# Creating class that gather essential stock information
class CompanySheet:
# creating dictionary to store stock information
def __init__(self):
self.stockInfo = {
"ticker": "",
"sharePrice": "",
"assets": "",
"liabilities": "",
"shareholderEquity": ""
}
def ticker(self):
# Finding ticker
self.tickerSymbol = page_content.find("div", attrs={"class":"qbreadcrumb"})
self.a_TickerList = self.tickerSymbol.findAll("a")
self.a_TickerList = (self.a_TickerList[2].text)
# Adding ticker to dictionary
self.stockInfo["ticker"] = self.a_TickerList
print(self.a_TickerList)
def share(self):
# Finding share price
self.sharePrice = page_content.findAll("div", attrs={"id":"qwidget_lastsale"})
self.aSharePrice = (self.sharePrice[0].text)
# Transforming share price to desired format
self.aSharePrice = str(self.aSharePrice[1:]).replace( ',' , '' )
self.aSharePrice = float(self.aSharePrice)
# Adding results to dictionary
self.stockInfo["sharePrice"] = self.aSharePrice
"""
def assets(self):
# Finding total assets
totalAssets = page_content.findAll("tr", attrs={"class":"net"})[1]
td_assetList = totalAssets.findAll("td")
tdAssets = (td_assetList[22].text)
# Transforming share price to desired format
tdAssets = str(tdAssets[1:]).replace( ',' , '' )
tdAssets = float(tdAssets)
# Adding results to dictionary
self.stockInfo["assets"] = tdAssets
def liabilites(self):
# Finding total liabilities
totalLiabilities = page_content.findAll("tr", attrs={"class":"net"})[3]
td_liabilityList = totalLiabilities.findAll("td")
tdLiabilities = (td_liabilityList[24].text)
# Transforming share price to desired format
tdLiabilities = str(tdLiabilities[1:]).replace( ',' , '' )
tdLiabilities = float(tdLiabilities)
# Adding results to dictionary
self.stockInfo["liabilities"] = tdLiabilities
def equity(self):
# Finding shareholder equity
netEquity = page_content.findAll("tr", attrs={"class":"net"})[4]
td_equityList = netEquity.findAll("td")
tdShareholderEquity = (td_equityList[24].text)
# Transforming shareholder equity to desired format
tdShareholderEquity = str(tdShareholderEquity[1:]).replace( ',' , '' )
tdShareholderEquity = float(tdShareholderEquity)
# Adding results to dictionary
self.stockInfo["shareholderEquity"] = tdShareholderEquity
"""
companySheet = CompanySheet()
print(companySheet.stockInfo)
All I want the code to do is for each function to parse it's information to my dictionary. I then want to access it outside of the class. Can someone help to clarify how I can use _init_ in this scenario, or do I even have to use it?
init is a constructor, which is called along with the creation of the class object. Whereas, self is an instance of the class, which is used accessing methods and attributes of a python class.
In your code, firstly change:
_init_(self) to __init__(self)
Then, in the methods:
def share(self):
# Finding share price
sharePrice = page_content.findAll("div", attrs={"id":"qwidget_lastsale"})
self.aSharePrice = (sharePrice[0].text)
# Transforming share price to desired format
self.aSharePrice = str(aSharePrice[1:]).replace( ',' , '' )
self.aSharePrice = float(aSharePrice)
# Adding results to dictionary
self.stockInfo["sharePrice"] = self.aSharePrice
Similarly, in all the remaining methods, access the variable through the self keyword.
Now, you also need to call the methods which are updating your dictionary.
So, after you have created the object, call the methods through the object and then print the dictionary, like this:
companySheet = CompanySheet()
companySheet.share()
print(companySheet.stockInfo)
Probably it would work!
I am attempting to query all rows for a column called show_id. I would then like to compare each potential item to be added to the DB with the results. Now the simplest way I can think of doing that is by checking if each show is in the results. If so pass etc. However the results from the below snippet are returned as objects. So this check fails.
Is there a better way to create the query to achieve this?
shows_inDB = Show.query.filter(Show.show_id).all()
print(shows_inDB)
Results:
<app.models.user.Show object at 0x10c2c5fd0>,
<app.models.user.Show object at 0x10c2da080>,
<app.models.user.Show object at 0x10c2da0f0>
Code for the entire function:
def save_changes_show(show_details):
"""
Save the changes to the database
"""
try:
shows_inDB = Show.query.filter(Show.show_id).all()
print(shows_inDB)
for show in show_details:
#Check the show isnt already in the DB
if show['id'] in shows_inDB:
print(str(show['id']) + ' Already Present')
else:
#Add show to DB
tv_show = Show(
show_id = show['id'],
seriesName = str(show['seriesName']).encode(),
aliases = str(show['aliases']).encode(),
banner = str(show['banner']).encode(),
seriesId = str(show['seriesId']).encode(),
status = str(show['status']).encode(),
firstAired = str(show['firstAired']).encode(),
network = str(show['network']).encode(),
networkId = str(show['networkId']).encode(),
runtime = str(show['runtime']).encode(),
genre = str(show['genre']).encode(),
overview = str(show['overview']).encode(),
lastUpdated = str(show['lastUpdated']).encode(),
airsDayOfWeek = str(show['airsDayOfWeek']).encode(),
airsTime = str(show['airsTime']).encode(),
rating = str(show['rating']).encode(),
imdbId = str(show['imdbId']).encode(),
zap2itId = str(show['zap2itId']).encode(),
added = str(show['added']).encode(),
addedBy = str(show['addedBy']).encode(),
siteRating = str(show['siteRating']).encode(),
siteRatingCount = str(show['siteRatingCount']).encode(),
slug = str(show['slug']).encode()
)
db.session.add(tv_show)
db.session.commit()
except Exception:
print(traceback.print_exc())
I have decided to use the method above and extract the data I wanted into a list, comparing each show to the list.
show_compare = []
shows_inDB = Show.query.filter().all()
for item in shows_inDB:
show_compare.append(item.show_id)
for show in show_details:
#Check the show isnt already in the DB
if show['id'] in show_compare:
print(str(show['id']) + ' Already Present')
else:
#Add show to DB
For querying a specific column value, have a look at this question: Flask SQLAlchemy query, specify column names. This is the example code given in the top answer there:
result = SomeModel.query.with_entities(SomeModel.col1, SomeModel.col2)
The crux of your problem is that you want to create a new Show instance if that show doesn't already exist in the database.
Querying the database for all shows and looping through the result for each potential new show might become very inefficient if you end up with a lot of shows in the database, and finding an object by identity is what an RDBMS does best!
This function will check to see if an object exists, and create it if not. Inspired by this answer:
def add_if_not_exists(model, **kwargs):
if not model.query.filter_by(**kwargs).first():
instance = model(**kwargs)
db.session.add(instance)
So your example would look like:
def add_if_not_exists(model, **kwargs):
if not model.query.filter_by(**kwargs).first():
instance = model(**kwargs)
db.session.add(instance)
for show in show_details:
add_if_not_exists(Show, id=show['id'])
If you really want to query all shows upfront, instead of putting all of the id's into a list, you could use a set instead of a list which will speed up your inclusion test.
E.g:
show_compare = {item.show_id for item in Show.query.all()}
for show in show_details:
# ... same as your code
I am trying to write a class that will look for certain column types in a sqlalchemy reflected table and then do some operations for a subset of columns based on the data type.
I can correctly reflect the table and grab a list of the 'date' type columns as shown in the date_types list. However, when it gets to table[name] the function fails with the error:
*** TypeError: 'DeclarativeMeta' object is not subscriptable
If I use dot subscripts instead of square brackets i.e. table.col_name I can access the table column attribute but I don't see how I would iterate over the attribute list using that syntax.
Here is my class:
from pdb import set_trace
class dateRangeProfiler():
def __init__(self, session):
self.date_ranges = {}
self.date_types = [Date(), DateTime(), TIMESTAMP()]
self.session = session
print('date data types: ', str(self.date_types))
def __call__(self, table):
date_columns = self.getDateColumns(table)
print(date_columns)
date_column_profile = self.profileColumns(table, date_columns)
return date_column_profile
def getDateColumns(self, table):
columns = [(c.name, c.type) for c in table.__table__.columns if str(c.type) in [str(dt) for dt in self.date_types]]
return columns
def profileColumns(self, table, date_cols):
profile = {}
for (name, _) in date_cols:
set_trace()
print(name)
qry = self.session.query(func.max(table[name]).label("max_date"),
func.min(testTable[name]).label("min_date"),) # <-- fails here
res = qry.one()
max = res.max_date
min = res.min_date
profile.append({name: {'max':max, 'min':min}})
Here is how I call the profiler:
date_range_profiler = dateRangeProfiler(sess)
date_range_profiler(my_table)
And the error:
*** TypeError: 'DeclarativeMeta' object is not subscriptable
The issue doesn't have anything to do with the sqlalchemy module. When accesing attributes of object using variable references, use the getattr() base python function.
qry = self.session.query(func.max(getattr(table,name)).label("max_date"),
func.min(getattr(table,name)).label("min_date"),)
I am trying to get maya to check if the listed object is a blendshape node or not.
This is my code:
def bake(self, *args):
self.items["selection"] = cmds.ls(sl = True)
self.items["shapes"] = cmds.listRelatives(self.items["selection"], ad = True)
shapes = ()
for i in self.items["shapes"]:
bs = cmds.listConnections(i, type = "blendShape", exactType = True)
if cmds.objectType(bs, isType = "blendShape"):
print bs
It returns # Error: RuntimeError: file X:/Documents/maya/scripts\jtBakeCharacter.py line 16: No object name specified
Line 16 is: if cmds.objectType(bs, isType = "blendShape"):
Except that I AM specifying an object name, that object name is bs .. I have printed the result of bs and it has many objects listed. Many.
The code is redundant. You don't need most of the lines. The listConnections already ensures that you have only blendshapes. The exact problem is that you are calling something like:
cmds.objectType([])
for some of those extra shapes. And this is illegal. But mostly you code can be encapsulated as follows:
selected = cmds.ls(sl = True, dag=True ,shapes = True)
blends = cmds.listConnections(selected , type = "blendShape", exactType = True)
for item in blends:
print item
But this may not catch your intent perfectly, but shows how may extra steps you take. In reality you don't need the line if cmds.objectType(bs, isType = "blendShape"): for anything
Joojaa's answer is elegant, but you can get it down even shorter by using the default selection behavior:
blendshapes = cmds.ls(cmds.listHistory(pdo=True), type='blendShape') or []
for item in blendshapes:
print item
(In the quest to make it even shorter I'm not checking for the selection, so this one fails if nothing is selected).
PS: if you need to get to the blendshape from one of the upstream shapes, instead of the deformed shape, you can use listHistory (f=True)
You could try this:
from pymel.core import *
for obj in selected():
shapeNode = obj.getChildren()[0]
for output in shapeNode.outputs():
if nodeType(output) == "blendShape":
print obj, "is a blendshape"