Python tuples as keys and objects as values - python

My requirement is to have collection of device objects ( having capacity, manufacturer, bandwidth, cost, etc as features). I need to be able to find the device with maximum capacity. But since there could be multiple devices with same capacity from same or different manufacturer I can not use capacity as the key.
I thought of having tuple of capacity and model no as key but then I choose devices based on their capacities and not their model no.
class device:
def __init__(self):
self.manufacturer = ""
self.purchasecost = ""
self.capacity = "" # TB
self.power = "" # KWH
self.bandwidth = "" # MBPS
self.fail_rate = ""
self.powered_on = "" # %
self.lIOPS = ""
self.device_type = ""
self.moveincost = "" # % of purchasecost
self.moveoutcost = "" # % of purchasecost
self.datacentercost = ""
self.servicelife = ""
self.model = ""
pass
def setparam(self, device_param):
self.manufacturer = device_param["manufacturer"]
self.purchasecost = device_param["purchasecost"]
self.capacity = device_param["capacity"] # TB
self.power = device_param["power"] # KWH
self.bandwidth = device_param["bandwidth"] # MBPS
self.fail_rate = device_param["fail_rate"]
self.powered_on = device_param["powered_on"] # %
self.lIOPS = device_param["IOPS"]
self.device_type = device_param["device_type"]
self.moveincost = device_param["moveincost"] # % of purchasecost
self.moveoutcost = device_param["moveoutcost"] # % of purchasecost
self.datacentercost = device_param["datacentercost"]
self.servicelife = device_param["servicelife"]
self.model = device_param["model"]
In a different class I am creating objects and using them.
def available_devices(self):
hdd1 = self.createdisk1()
hdd2 = self.createdisk2()
ssd1 = self.createSSD1()
self.availabledevices[hdd1.model]=hdd1
print ( "Added HDD1 "+str(self.availabledevices[hdd1.model]))
self.availabledevices[hdd2.model]=hdd2
print ( "Added HDD2 "+str(self.availabledevices[hdd2.model]))
self.availabledevices[ssd1.model]=ssd1
def get_highest_capacity_device(self):
sorted_capacities = sorted(self.availabledevices.iterkeys())
highest_capacity = sorted_capacities[len(sorted_capacities) -1]
highest_capacity_device = self.availabledevices[highest_capacity]
return highest_capacity_device
This code currently use capacity as the key but it obviously does not work when there are multiple devices with same capacity. My question is what should I use as key so that
- I can sort my devices based on their capacities
- I can get all devices having a certain capacity

Why do you use a dictionary anyway? There is no benefit in contrast to a simple list:
availabledevices = [ hdd1, hdd2, ssd ]
highest_capacity_device = max(availabledevices, key=lambda x: x.capacity)

Related

can't adapt type 'data'

I have data class:
class data:
def __init__(self, ReadTime, Concentration_PM10, Concentration_SO2, Concentration_O3, Concentration_NO2, Concentration_CO, AQI_PM10,
AQI_SO2,AQI_O3, AQI_NO2, AQI_CO, AQI_AQIIndex, AQI_ContaminantParameter, AQI_State, AQI_Color ):
self.ReadTime = ReadTime
self.Concentration_PM10 = Concentration_PM10
self.Concentration_SO2 = Concentration_SO2
self.Concentration_O3 = Concentration_O3
self.Concentration_NO2 = Concentration_NO2
self.Concentration_CO = Concentration_CO
self.AQI_PM10 = AQI_PM10
self.AQI_SO2 = AQI_SO2
self.AQI_O3 = AQI_O3
self.AQI_NO2 = AQI_NO2
self.AQI_CO = AQI_CO
self.AQI_AQIIndex = AQI_AQIIndex
self.AQI_ContaminantParameter = AQI_ContaminantParameter
self.AQI_State = AQI_State
self.AQI_Color = AQI_Color
I'm sending a request to an api and populating the variables into a list.:
list = []
for i in result:
list.append( data(i['ReadTime'], i['Concentration']['PM10'], i['Concentration']['SO2'],i['Concentration']['O3'],
i['Concentration']['NO2'],i['Concentration']['CO'],i['AQI']['PM10'],
i['AQI']['SO2'],i['AQI']['O3'],i['AQI']['NO2'],i['AQI']['CO'],i['AQI']['AQIIndex'],i['AQI']['ContaminantParameter'],
i['AQI']['State'],i['AQI']['Color']))
then I want to insert this list into a table in PostgreSQL but I get error "can't adapt type 'data'"
list_record = ", ".join(["%s"] * len(list))
query_insert= (f"INSERT INTO hava_kalitesi (ReadTime, Concentration_PM10, Concentration_SO2, Concentration_O3, Concentration_NO2, Concentration_CO, AQI_PM10, AQI_SO2, AQI_O3, AQI_NO2, AQI_CO, AQI_AQIIndex, AQI_ContaminantParameter,AQI_State,AQI_Color) VALUES {list_record}"
)
cursor.execute(query_insert,list)

Generalize Getting Data From SQL Server to Python

I'm studying on a task that I have to get data from SQL Server, and because I'm running time series analysis, I need to specify a date field that can change every table or query. Also I can read a simple query or a stored procedure. I want to generalize my below code which is a field and database specific. I thought that I can define an empty dictionary in class and then I can call it in below dataread method. But I am conflicted.
class DataPrep:
def __init__(self,conn):
self.df = pd.DataFrame()
self.mega_projects = set()
self.mega_project_to_df = {}
self.mega_project_to_df_pvt = {}
self.conn={}
def read_data(self):
self.conn=pyodbc.connect({'driver':None, 'server':None, 'database':None, 'uid':None, 'pwd':None})
self.df = pd.read_sql_query('''exec [dbo].[ML_WorkLoad]''', self.conn, parse_dates={'CreatedDate': '%d/%m/%Y %H.%M.%S'})
#self.df = self.df[['EstimateManDay', 'CreatedDate', 'MegaProject', 'ProjectName']]
self.df['month'] = pd.DatetimeIndex(self.df['CreatedDate']).month
self.df['year'] = pd.DatetimeIndex(self.df['CreatedDate']).year
self.df['quarter'] = pd.DatetimeIndex(self.df['CreatedDate']).quarter
self.df['week'] = pd.DatetimeIndex(self.df['CreatedDate']).week
self.df['dayorg'] = pd.DatetimeIndex(self.df['CreatedDate']).day
self.df['day'] = 1
self.df['year_quarter'] = self.df['year'].astype(str) + "_" + self.df[
'quarter'].astype(str)
self.df['year_month'] = self.df['year'].astype(str) + "_" + self.df[
'month'].astype(str)
self.df['year_week'] = self.df['year'].astype(str) + "_" + self.df['week'].astype(
str)
self.df['date'] = pd.to_datetime(self.df[['year', 'month', 'day']])
self.df = self.df[self.df['CreatedDate'] <= datetime.strptime("2020-01-01", "%Y-%m-%d")]

How to get big amount of data as fast as possible

I am trying to return an array of constructed objects that are build on top of objects that I retrieve from some url plus another fields that I get from another url.
I have an array that consists of two arrays that each has about 8000 objects...
I have tried to make each object construction as a thread however it still takes a lot of time...
Any solution? Here is my code:
def get_all_players_full_data(ea_players_json):
all = []
ea_players_json = list(ea_players_json.values())
for i in range(len(ea_players_json)):
for player_obj in ea_players_json[i]:
all.append(player_obj)
for player_obj in range(len(all)):
all_data = []
with concurrent.futures.ThreadPoolExecutor(len(all)) as executor:
for player_data in all:
future = executor.submit(build_full_player_data_obj, player_data)
print(future.result())
all_data.append(future.result())
def build_full_player_data_obj(ea_player_data):
if ea_player_data.get("c") is not None:
player_full_name = ea_player_data.get("c")
else:
player_full_name = ea_player_data.get("f") + " " + ea_player_data.get("l")
player_id = ea_player_data.get("id")
# go to futhead to find all cards of that player
futhead_url_player_data = f'{FUTHEAD_PLAYER}{player_full_name}'
details_of_specific_player = json.loads(requests.get(futhead_url_player_data).content)
cards_from_the_same_id = []
for player_in_json_futhead in details_of_specific_player:
if player_in_json_futhead["player_id"] == player_id:
rating = player_in_json_futhead["rating"]
specific_card_id = player_in_json_futhead["def_id"]
revision = player_in_json_futhead["revision_type"]
name = player_in_json_futhead["full_name"]
nation = player_in_json_futhead["nation_name"]
position = player_in_json_futhead["position"]
club = player_in_json_futhead["club_name"]
cards_from_the_same_id.append(Player(specific_card_id, name, rating, revision, nation,
position, club))
return cards_from_the_same_id

counter method does not count well

I have a method that tells the times that a worker makes a sale, but it does not work because it only marks me that he has made 1 but has actually done 5. Next I leave an image and the code used to guide me.
**class Worker (models.Model):**
_name = 'project_rc.worker'
sales_counter = fields.Integer (string = "Sales made", compute = "get_sales_made")
document_ids = fields.One2many (comodel_name = 'project_rc.document',
inverse_name = 'worker_id', string = 'Invoice')
def get_sales_made (self):
count = self.env ['project_rc.type_movement']. search_count ([('type_movement', '=', 'sale')])
self.counter_sale = count
**class Document (models.Model):**
type_movement_id = fields.Many2one (comodel_name = 'project_rc.type_movement', string = "Movement type")
worker_id = fields.Many2one (asdel_name = 'project_rc.worker', string = "Worker")
**class Type_Movement (models.Model):**
type_movement = fields.Selection ([('purchase', 'Purchase'), ('sale', 'Sale'), ('merma', 'Merma')], string = "Movement type")
document_ids = fields.One2many (comodel_name = 'project_rc.document', inverse_name = 'type_movimiento_id', string = 'Document')
Sample picture: https://ibb.co/vs0dw5K
The problem came from your function get_sales_made
class Worker(models.Model):
_name = 'project_rc.worker'
sales_counter = fields.Integer(string="Sales made", compute="get_sales_made")
document_ids = fields.One2many('project_rc.document', 'worker_id', string='Invoice')
#api.depends('document_ids')
def get_sales_made(self):
for rec in self:
document = rec.document_ids.filtered(lambda r: r.type_movement_id and r.type_movement_id.type_movement == 'sale')
rec.sales_counter = len(document)
class Document(models.Model):
_name = 'project_rc.document'
type_movement_id = fields.Many2one('project_rc.type_movement', string="Movement type")
worker_id = fields.Many2one('project_rc.worker', string="Worker")
class Type_Movement(models.Model):
_name = 'project_rc.type_movement'
type_movement = fields.Selection([('purchase', 'Purchase'), ('sale', 'Sale'), ('merma', 'Merma')], string="Movement type")
document_ids = fields.One2many('project_rc.document', 'type_movement_id', string='Document')
You are searching in the wrong table it should be project_rc.document
self.env['project_rc.document'].search_count([('type_movement_id.type_movement', '=', 'sale')
('worker_id', '=', rec.id)
])
Or you can simply filter document_ids to count sales.

create and assign subcategories in revit using python

I have a question for some of you who are familiar with the Revit API and python:
I’ve been using the spring nodes package in dynamo to create a rather large series of freeform objects each in their own family. The way that the FamilyInstance.ByGeometry works, it takes a list of solids and creates a family instance for each using a template family file. The result is quite good. (spring nodes can be found here: https://github.com/dimven/SpringNodes)
However, the drawback is that that now I have roughly 200 separate instances, so to make changes to each is rather painful. I thought at first it would be possible to use dynamo to create a new subcategory and set the solid inside each family instance to this new subcategory. Unfortunately, I realized this is not possible since dynamo cannot be open in two different Revit environments simultaneously (the project I am working in and each instance of the family). This leads me to look to see if I can do this using python.
I have used python in rhino and can get along pretty well, I am still learning the Revit API however. But basically my idea would be to:
1. select a series of family instances in the Revit project environment
2. loop through each instance
3. save it to a specified location
4. create a new subcategory in each family instances (the subcategory would the same for all the selected family instances)
5. select the solid in each in instance
6. set the solid to this newly created subcategory
7. close the family instance and save
My question for you is does this sound like it is achievable based on your knowledge of the Revit API?
Many thanks for your time and advice.
UPDATE:
I've found a section in the revit api that describes what i'm looking to do: http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-FBF9B994-ADCB-4679-B50B-2E9A1E09AA48
I've made a first pass at inserting this into the python code of the dynamo node. The rest of the code works fine except for the new section im adding (see below). Please excuse the variables, I am simply keeping with logic of the original author of the code i am hacking:
(Note: the variables come in are in arrays)
#set subcategory
try:
#create new sucategory
fam_subcat = famdoc.Settings.Categories.NewSubcategory(fam_cat, get_Item(subcat1.Name))
#assign the mataterial(fam_mat.Id) to the subcategory
fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
Any help or advice with this section of code would be much appreciated.
UPDATE:
See full code below for context of the section in question:
#Copyright(c) 2015, Dimitar Venkov
# #5devene, dimitar.ven#gmail.com
import clr
import System
from System.Collections.Generic import *
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
import sys
sys.path.append("%s\IronPython 2.7\Lib" %pf_path)
import traceback
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import StructuralType
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
def output1(l1):
if len(l1) == 1: return l1[0]
else: return l1
def PadLists(lists):
len1 = max([len(l) for l in lists])
for i in xrange(len(lists)):
if len(lists[i]) == len1:
continue
else:
len2 = len1 - len(lists[i])
for j in xrange(len2):
lists[i].append(lists[i][-1])
return lists
class FamOpt1(IFamilyLoadOptions):
def __init__(self):
pass
def OnFamilyFound(self,familyInUse, overwriteParameterValues):
return True
def OnSharedFamilyFound(self,familyInUse, source, overwriteParameterValues):
return True
geom = tolist(IN[0])
fam_path = IN[1]
names = tolist(IN[2])
category = tolist(IN[3])
material = tolist(IN[4])
isVoid = tolist(IN[5])
subcategory = tolist(IN[6])
isRvt2014 = False
if app.VersionName == "Autodesk Revit 2014": isRvt2014 = True
units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
factor = UnitUtils.ConvertToInternalUnits(1,units)
acceptable_views = ["ThreeD", "FloorPlan", "EngineeringPlan", "CeilingPlan", "Elevation", "Section"]
origin = XYZ(0,0,0)
str_typ = StructuralType.NonStructural
def NewForm_background(s1, name1, cat1, isVoid1, mat1, subcat1):
t1 = TransactionManager.Instance
TransactionManager.ForceCloseTransaction(t1)
famdoc = doc.Application.NewFamilyDocument(fam_path)
message = None
temp_path = System.IO.Path.GetTempPath()
sat_path = "%s%s.sat" % (temp_path, name1)
try:
if factor != 1:
s1 = s1.Scale(factor)
sat1 = Geometry.ExportToSAT(s1, sat_path)
satOpt = SATImportOptions()
satOpt.Placement = ImportPlacement.Origin
satOpt.Unit = ImportUnit.Foot
view_fec = FilteredElementCollector(famdoc).OfClass(View)
view1 = None
for v in view_fec:
if str(v.ViewType) in acceptable_views:
view1 = v
break
t1.EnsureInTransaction(famdoc)
satId = famdoc.Import(sat1, satOpt, view1)
opt1 = Options()
opt1.ComputeReferences = True
el1 = famdoc.GetElement(satId)
geom1 = el1.get_Geometry(opt1)
enum = geom1.GetEnumerator()
enum.MoveNext()
geom2 = enum.Current.GetInstanceGeometry()
enum2 = geom2.GetEnumerator()
enum2.MoveNext()
s1 = enum2.Current
famdoc.Delete(satId)
TransactionManager.ForceCloseTransaction(t1)
System.IO.File.Delete(sat_path)
except:
message = traceback.format_exc()
pass
if message == None:
try:
save_path = "%s%s.rfa" % (temp_path, name1)
SaveAsOpt = SaveAsOptions()
SaveAsOpt.OverwriteExistingFile = True
t1.EnsureInTransaction(famdoc)
#set the category
try:
fam_cat = famdoc.Settings.Categories.get_Item(cat1.Name)
famdoc.OwnerFamily.FamilyCategory = fam_cat
except: pass
s2 = FreeFormElement.Create(famdoc,s1)
if isVoid1:
void_par = s2.get_Parameter("Solid/Void")
void_par.Set(1)
void_par2 = famdoc.OwnerFamily.get_Parameter("Cut with Voids When Loaded")
void_par2.Set(1)
else: #voids do not have a material value
try:
mat_fec = FilteredElementCollector(famdoc).OfClass(Material)
for m in mat_fec:
if m.Name == mat1:
fam_mat = m
break
mat_par = s2.get_Parameter("Material")
mat_par.Set(fam_mat.Id)
except: pass
#set subcategory
try:
#create new sucategory
fam_subcat = document.Settings.Categories.NewSubcategory(document.OwnerFamily.FamilyCategory, get_Item(subcat1.Name))
#assign the mataterial(fam_mat.Id) to the subcategory
fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
TransactionManager.ForceCloseTransaction(t1)
famdoc.SaveAs(save_path, SaveAsOpt)
family1 = famdoc.LoadFamily(doc, FamOpt1())
famdoc.Close(False)
System.IO.File.Delete(save_path)
symbols = family1.Symbols.GetEnumerator()
symbols.MoveNext()
symbol1 = symbols.Current
t1.EnsureInTransaction(doc)
if not symbol1.IsActive: symbol1.Activate()
inst1 = doc.Create.NewFamilyInstance(origin, symbol1, str_typ)
TransactionManager.ForceCloseTransaction(t1)
return inst1.ToDSType(False), family1.ToDSType(False)
except:
message = traceback.format_exc()
return message
else:
return message
def NewForm_background_R16(s1, name1, cat1, isVoid1, mat1, subcat1):
t1 = TransactionManager.Instance
TransactionManager.ForceCloseTransaction(t1)
famdoc = doc.Application.NewFamilyDocument(fam_path)
message = None
temp_path = System.IO.Path.GetTempPath()
sat_path = "%s%s.sat" % (temp_path, name1)
try:
if factor != 1:
s1 = s1.Scale(factor)
sat1 = Geometry.ExportToSAT(s1, sat_path)
satOpt = SATImportOptions()
satOpt.Placement = ImportPlacement.Origin
satOpt.Unit = ImportUnit.Foot
view_fec = FilteredElementCollector(famdoc).OfClass(View)
view1 = None
for v in view_fec:
if str(v.ViewType) in acceptable_views:
view1 = v
break
t1.EnsureInTransaction(famdoc)
satId = famdoc.Import(sat1, satOpt, view1)
opt1 = Options()
opt1.ComputeReferences = True
el1 = famdoc.GetElement(satId)
geom1 = el1.get_Geometry(opt1)
enum = geom1.GetEnumerator()
enum.MoveNext()
geom2 = enum.Current.GetInstanceGeometry()
enum2 = geom2.GetEnumerator()
enum2.MoveNext()
s1 = enum2.Current
famdoc.Delete(satId)
TransactionManager.ForceCloseTransaction(t1)
System.IO.File.Delete(sat_path)
except:
message = traceback.format_exc()
pass
if message == None:
try:
save_path = "%s%s.rfa" % (temp_path, name1)
SaveAsOpt = SaveAsOptions()
SaveAsOpt.OverwriteExistingFile = True
t1.EnsureInTransaction(famdoc)
#set the category
try:
fam_cat = famdoc.Settings.Categories.get_Item(cat1.Name)
famdoc.OwnerFamily.FamilyCategory = fam_cat
except: pass
s2 = FreeFormElement.Create(famdoc,s1)
if isVoid1:
void_par = s2.LookupParameter("Solid/Void")
void_par.Set(1)
void_par2 = famdoc.OwnerFamily.LookupParameter("Cut with Voids When Loaded")
void_par2.Set(1)
else: #voids do not have a material value
try:
mat_fec = FilteredElementCollector(famdoc).OfClass(Material)
for m in mat_fec:
if m.Name == mat1:
fam_mat = m
break
mat_par = s2.LookupParameter("Material")
mat_par.Set(fam_mat.Id)
except: pass
#apply same subcategory code as before
#set subcategory
try:
#create new sucategory
fam_subcat = famdoc.Settings.Categories.NewSubcategory(fam_cat, get_Item(subcat1.Name))
#assign the mataterial(fam_mat.Id) to the subcategory
fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
TransactionManager.ForceCloseTransaction(t1)
famdoc.SaveAs(save_path, SaveAsOpt)
family1 = famdoc.LoadFamily(doc, FamOpt1())
famdoc.Close(False)
System.IO.File.Delete(save_path)
symbols = family1.GetFamilySymbolIds().GetEnumerator()
symbols.MoveNext()
symbol1 = doc.GetElement(symbols.Current)
t1.EnsureInTransaction(doc)
if not symbol1.IsActive: symbol1.Activate()
inst1 = doc.Create.NewFamilyInstance(origin, symbol1, str_typ)
TransactionManager.ForceCloseTransaction(t1)
return inst1.ToDSType(False), family1.ToDSType(False)
except:
message = traceback.format_exc()
return message
else:
return message
if len(geom) == len(names) == len(category) == len(isVoid) == len(material) == len(subcategory):
if isRvt2014:
OUT = output1(map(NewForm_background, geom, names, category, isVoid, material, subcategory))
else:
OUT = output1(map(NewForm_background_R16, geom, names, category, isVoid, material, subcategory))
elif len(geom) == len(names):
padded = PadLists((geom, category, isVoid, material, subcategory))
p_category = padded[1]
p_isVoid = padded[2]
p_material = padded[3]
p_subcategory = padded [4]
if isRvt2014:
OUT = output1(map(NewForm_background, geom, names, p_category, p_isVoid, p_material, p_subcategory))
else:
OUT = output1(map(NewForm_background_R16, geom, names, p_category, p_isVoid, p_material, subcategory))
else: OUT = "Make sure that each geometry\nobject has a unique family name."
Update:
Was able to get it working:
try:
#create new sucategory
fam_subcat = famdoc.Settings.Categories.NewSubcategory(famdoc.OwnerFamily.FamilyCategory, subcat1)
#assign the mataterial(fam_mat.Id) to the subcategory
#fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
As I answered on your initial query per email, what you are aiming for sounds perfectly feasible to me in the Revit API. Congratulations on getting as far as you have. Looking at the link to the Revit API help file and developer guide that you cite above, it seems that the code has to be executed in the family document while defining the family. The context in which you are trying to execute it is not clear. Have you used EditFamily to open the family definition document? What context are you executing in?

Categories