How to fix 'AttributeError: 'dict' object has no attribute 'code' - python

I am trying to parse all plugin tags from an XML file and build a dict using a Plugin class I created. I really do not understand the error and the context of the error.
.append() does not seem to work when I try to initialize the plugin_dict as a list. Also when I try to call __init__() function like plugin = Plugin(), I get an error that Plugin needs at least 1 argument when I have already implemented a __init__(self) function which requires no arguments.
Here is the code from main.py
from plugin import Plugin
from bs4 import BeautifulSoup
def parse():
file = open('../data/windows.xml')
soup = BeautifulSoup(file, 'xml')
plugins = soup.find_all('plugin')
plugin_dict = []
for plugin in plugins:
plugin_dict.append(Plugin(plugin))
return plugin_dict
where plugin.py is:
class Plugin(object):
__name = 'Unknown'
__vendor = {}
__vendor_name = 'Unknown, Inc.'
__vendor_producturl = 'http://www.example.com/product'
__vendor = [__vendor_name, __vendor_producturl]
__version = {}
__version_code = '0.0.0.0'
__version_release_date = '01-01-1970'
__version = [__version_code, __version_release_date]
__properties = {}
__beta = False
__vst3 = False
__x64 = False
__category = 'synth/effect'
__properties = {__beta, __vst3, __x64, __category}
__magnet_uri = {}
__iss_links = {}
__download_uri = {}
__downloads = {}
__downloads = [__magnet_uri, __iss_links, __download_uri]
def __init__(self):
'''Create an empty instance for later use'''
self.name = str(__name)
self.version = {}
self.version.code = str(__version[0])
self.version.releasedate = str(__version[1])
self.version = [self.version.code, self.version.releasedate]
self.vendor = {}
self.vendor.name = str(__vendor_name)
self.vendor.producturl = str(__vendor_producturl)
self.vendor = [self.vendor.name, self.vendor.producturl]
self.properties = {}
self.properties.beta = bool(__properties[0])
self.properties.vst3 = bool(__properties[1])
self.properties.x64 = bool(__properties[2])
self.properties.category = str(__properties[3])
self.properties = [self.properties.beta, self.properties.vst3, self.properties.x64, self.properties.category]
self.magneturi = list(__magnet_uri)
self.isslinks = list(__iss_links)
self.downloaduri = list(__download_uri)
self.downloads = {}
self.downloads = [self.magneturi, self.isslinks, self.downloaduri]
self.product_dict = {}
self.product_dict = [self.name, self.vendor, self.properties, self.downloads]
return self.product_dict
def __init__(self, plugin):
self.name = plugin['name']
self.version = {}
self.version.code = plugin.version.code.string
self.version.releasedate = plugin.version.releasedate.string
self.version = [self.version.code, self.version.releasedate]
self.vendor= {}
self.vendor.name = plugin.vendor.string
self.vendor.producturl = plugin.vendor['url']
self.vendor = [self.vendor.name, self.vendor.producturl]
self.properties = {}
self.properties.beta = plugin['beta']
self.properties.vst3 = plugin['vst3']
self.properties.x64 = plugin['x64']
self.properties.category = plugin['category']
self.properties = [self.properties.beta, self.properties.vst3, self.properties.x64, self.properties.category]
magnet_uri_dict = {}
magnet_uri_dict = plugin.find_all('magnet')
for magnet_uri in magnet_uri_dict:
self.magneturi.append[magnet_uri.name, magnet_uri.string]
iss_link_dict = {}
iss_link_dict = plugin.find_all('iss/*')
for iss_link in iss_link_dict:
self.isslinks.append(iss_link.string)
download_uri_dict = {}
download_uri_dict = plugin.find_all('download-uri/*')
for download_uri in download_uri_dict:
self.downloaduri.append(download_uri.string)
self.downloads = {}
self.downloads = [self.magneturi, self.isslinks, self.downloaduri]
self.product_dict = {}
self.product_dict = [self.name, self.vendor, self.properties, self.downloads]
return self.product_dict
and a plugin tag in windows.xml looks like:
<plugin name="Serum" vst3="false" beta="false" x64="true" category="synth">
<vendor url="">Xfer Records</vendor>
<version>
<code>1.248</code>
<release-date>13-03-2019</release-date>
</version>
<download-uri>
<zippy>PLACEHOLDER</zippy>
<openload>PLACEHOLDER</openload>
<sr-files>PLACEHOLDER</sr-files>
</download-uri>
<iss>
<mirror1>PLACEHOLDER</mirror1>
<mirror2>PLACEHOLDER</mirror2>
<mirror3>PLACEHOLDER</mirror3>
</iss>
<magnet type="default"></magnet>
</plugin>
I think I am going wrong with defining self.version.something; I never saw an example like that. I just used it for better classification of the XML into an object
If you think that I should mark this as python-3.x also then please tell

You are trying to set an attribute on a dictionary
self.version = {}
self.version.code = plugin.version.code.string # This won't work
If you would like to set a key on the dictionary you need to use the following syntax
self.version['code'] = plugin.version.code.string
You have redefined the __init__ method of your class, python does not support this. In your code you have replaced the first definition with the second. Plugin() would fail with a message saying there was a missing required parameter "plugin"

Related

How to access data from custom_export in Otree?

I am trying to use ExtraModel and custom_export to export data from live_pages. However, when I go on devserver and check the data tab, it is nowhere to be found. If I download the excel (bottom right of the page) the new variables are not included in the data.
Where can I find the data from the custom export? Or am I defining the function wrong? Any help greatly appreciated.
See MWE below
from otree.api import *
import random
doc = """
Your app description
"""
class C(BaseConstants):
NAME_IN_URL = 'mwe_export'
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 1
NUM_EMPLOYERS = 3
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
class Player(BasePlayer):
pass
class Offer(ExtraModel):
group = models.Link(Group)
sender = models.Link(Player)
wage = models.IntegerField()
effort = models.IntegerField()
job_id = models.IntegerField()
information_type = models.StringField()
# FUNCTIONS
def to_dict(offer: Offer):
return dict(sender=offer.sender.id_in_group,
wage=offer.wage,
effort=offer.effort,
job_id=offer.job_id,
information_type=offer.information_type)
# PAGES
class MyPage(Page):
#staticmethod
def js_vars(player: Player):
return dict(my_id=player.id_in_group)
#staticmethod
def live_method(player: Player, data):
print(data)
group = player.group
job_id = random.randint(1, 1000)
wage = data['wage']
effort = data['effort']
information_type = data['information_type']
if data['information_type'] == 'offer':
offer = Offer.create(group=group,
sender=player,
job_id=job_id,
wage=wage,
effort=effort,
information_type=information_type)
print(offer)
print(to_dict(offer))
return {0: to_dict(offer)}
page_sequence = [MyPage]
def custom_export(players):
yield ['session.code', 'participant_code', 'id_in_session']
offers = Offer.filter()
for offer in offers:
player = offer.sender
participant = player.participant
yield [participant.code, participant.id_in_session, offer.job_id, offer.wage, offer.effort]
In the menu at the top of the admin page there is also a "Data" item. The custom export for your app should be available there under the heading "Per-app".

SqlAlchemy db.Enum: How to detect it and retrieve the values

I have a function to add a column to a model:
def col(_type, label = "", **kwargs):
c = db.Column(_type, **kwargs)
c.info = {"label":label, "type":""}
return c
I use it like:
# Job Type
class JTEnum(enum.Enum):
full = "ﺖﻣﺎﻣ ﻮﻘﺗ"
part_time = "ﻦﯿﻤﻫ ﻮﻘﺗ"
project = "ﭖﺭﻭﮋﻫ ﺎﯾ"
jobtype = col(db.Enum(JTEnum), "ﻥﻮﻋ ﺶﻐﻟ", unique=False,
nullable=False,
default=JTEnum.full.name)
jobtype.info["choices"] = [(i.name, i.value) for i in JTEnum]
I call the col function for various columns. I would like to put the last line inside this function and it can be called on Enum type and fill the choices something like:
def col(_type, label = "", **kwargs):
c = db.Column(_type, **kwargs)
c.info = {"label":label, "type":""}
if isinstance(_type, db.Enum):
c.info["choices"] = [(i.name, i.value) for i in _type]
return c
However, it gives the error:
TypeError: 'Enum' object is not iterable
The first issue I'm seeing in your code is that you default to JTEnum.full.name, which should be the Enum element not its name, then you need to iterate the underlying Enum class of the SQLAlchemy Enum.
import enum
import sqlalchemy as db
class JTEnum(enum.Enum):
full = "ﺖﻣﺎﻣ ﻮﻘﺗ"
part_time = "ﻦﯿﻤﻫ ﻮﻘﺗ"
project = "ﭖﺭﻭﮋﻫ ﺎﯾ"
def col(_type, label="", **kwargs):
c = db.Column(_type, **kwargs)
c.info = {"label": label, "type": ""}
if isinstance(_type, db.Enum):
c.info["choices"] = [(i.name, i.value) for i in _type.enum_class]
return c
c = col(
db.Enum(JTEnum),
"ﻥﻮﻋ ﺶﻐﻟ",
unique=False,
nullable=False,
default=JTEnum.full,
)
print(c.info)
# {'label': 'ﻥﻮﻋ ﺶﻐﻟ',
# 'type': '',
# 'choices': [('full', 'ﺖﻣﺎﻣ ﻮﻘﺗ'),
# ('part_time', 'ﻦﯿﻤﻫ ﻮﻘﺗ'),
# ('project', 'ﭖﺭﻭﮋﻫ ﺎﯾ')]}
_type which is db.Enum is not iterable. You may refer to _type.enum_class like that:
def col(_type, label = "", **kwargs):
c = db.Column(_type, **kwargs)
c.info = {"label":label, "type":""}
if isinstance(_type, db.Enum):
c.info["choices"] = [(i.name, i.value) for i in _type.enum_class]
return c

How to create a Django dropdown form using forms.py without a model?

I need to create a simple presentation filter for a Django webpage. Since it's discarded without need for storage, I do not need to use Model overhead.
Here is my relevant views.py code:
#login_required()
def cards(request):
# form = CountryForm()
f_name = STAT_FILES / 'csv/segment_summary_quart.csv'
# pathname = os.path.abspath(os.path.dirname(__file__))
df = pd.read_csv(f_name, index_col=None)
pl_name = STAT_FILES / 'pickles/lbounds'
pu_name = STAT_FILES / 'pickles/ubounds'
lbounds = pickle.load(open(pl_name, "rb"))
ubounds = pickle.load(open(pu_name, "rb"))
filter_name = []
i = 0
max_i = len(ubounds)
while i < max_i:
filter_name.append(f'Personal best trophy range: {str(int(lbounds[i])).rjust(4," ")}-{str(int(ubounds[i])).rjust(4," ")}')
i += 1
sort_name = []
sort_name.append("Alphabetic Order")
sort_name.append("Most Popular")
sort_name.append("Least Popular")
sort_name.append("Highest Win Rate")
sort_name.append("Lowest Win Rate")
form = cardStatsForm(filter_name, sort_name)
Given that my values may change dynamically, I am trying to establish the cardStatsForm() object without initially knowing the values that will occur when publishing the page to the end user. The following code resides within forms.py:
from django import forms
class cardStatsForm(forms.Form):
def __init__(self, filter_opts, sortOrder, *args, **kwargs):
super(cardStatsForm, self).__init__(*args, **kwargs)
self.fields['filts'].choices = filter_opts
self.fields['sorts'].choices = sortOrder
filts = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=(), required=True)
sorts = forms.Select(choices=())
Unfortunately I haven't had to worry about the html side yet since I keep getting the following error with respect to my form class:
KeyError at /clashstats/cards/
'sorts'
Request Method: GET
Request URL: http://127.0.0.1:8000/clashstats/cards/
Django Version: 4.0
Exception Type: KeyError
Exception Value:
'sorts'
Exception Location: /Users/cooneycw/PycharmProjects/The6ix/clashstats/forms.py, line 8, in __init__
Python Executable: /Users/cooneycw/miniforge3/envs/The6ix/bin/python
I am more familiar with the flask framework and see that Django relies more heavily on objects which I am less familiar with. What am i doing incorrectly here?
The solution recommend by AMG above enabled me to move past this error. The next error related to the expectation for tuples for the choice listings. The following code modified to send zipped tuples for the list items now completes successfully:
forms.py
from django import forms
class cardStatsForm(forms.Form):
def __init__(self, filterList, sortList, *args, **kwargs):
super(cardStatsForm, self).__init__(*args, **kwargs)
self.filts = []
self.sorts = []
self.fields['filts'].choices = filterList
self.fields['sorts'].choices = sortList
filts = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=(), required=True)
sorts = forms.ChoiceField(choices=())
views.py
#login_required()
def cards(request):
# form = CountryForm()
f_name = STAT_FILES / 'csv/segment_summary_quart.csv'
# pathname = os.path.abspath(os.path.dirname(__file__))
df = pd.read_csv(f_name, index_col=None)
pl_name = STAT_FILES / 'pickles/lbounds'
pu_name = STAT_FILES / 'pickles/ubounds'
lbounds = pickle.load(open(pl_name, "rb"))
ubounds = pickle.load(open(pu_name, "rb"))
filter_name = []
i = 0
max_i = len(ubounds)
while i < max_i:
filter_name.append(f'Personal best trophy range: {str(int(lbounds[i])).rjust(4," ")}-{str(int(ubounds[i])).rjust(4," ")}')
i += 1
filter_id = range(len(filter_name))
filter_list = list(zip(filter_id, filter_name))
sort_name = []
sort_name.append("Alphabetic Order")
sort_name.append("Most Popular")
sort_name.append("Least Popular")
sort_name.append("Highest Win Rate")
sort_name.append("Lowest Win Rate")
sort_id = range(len(sort_name))
sort_list = list(zip(sort_id, sort_name))
form = cardStatsForm(filter_list, sort_list)
My thanks to https://stackoverflow.com/users/4872140/amg for his help to resolve this issue.

Exporting data from python to text file using petl package in python

I am trying to extract raw data from a text file and after processing the raw data, I want to export it to another text file. Below is the python code I have written for this process. I am using the "petl" package in python 3 for this purpose. 'locations.txt' is the raw data file.
import glob, os
from petl import *
class ETL():
def __init__(self, input):
self.list = input
def parse_P(self):
personids = None
for term in self.list:
if term.startswith('P'):
personids = term[1:]
personid = personids.split(',')
return personid
def return_location(self):
location = None
for term in self.list:
if term.startswith('L'):
location = term[1:]
return location
def return_location_id(self, location):
location = self.return_location()
locationid = None
def return_country_id(self):
countryid = None
for term in self.list:
if term.startswith('C'):
countryid = term[1:]
return countryid
def return_region_id(self):
regionid = None
for term in self.list:
if term.startswith('R'):
regionid = term[1:]
return regionid
def return_city_id(self):
cityid = None
for term in self.list:
if term.startswith('I'):
cityid = term[1:]
return cityid
print (os.getcwd())
os.chdir("D:\ETL-IntroductionProject")
print (os.getcwd())
final_location = [['L','P', 'C', 'R', 'I']]
new_location = fromtext('locations.txt', encoding= 'Latin-1')
stored_list = []
for identifier in new_location:
if identifier[0].startswith('L'):
identifier = identifier[0]
info_list = identifier.split('_')
stored_list.append(info_list)
for lst in stored_list:
tabling = ETL(lst)
location = tabling.return_location()
country = tabling.return_country_id()
city = tabling.return_city_id()
region = tabling.return_region_id()
person_list = tabling.parse_P()
for person in person_list:
table_new = [location, person, country, region, city]
final_location.append(table_new)
totext(final_location, 'l1.txt')
However when I use "totext" function of petl, it throws me an "Assertion Error".
AssertionError: template is required
I am unable to understand what the fault is. Can some one please explain the problem I am facing and what I should be doing ?
The template parameter to the toext function is not optional there is no default format for how the rows are written in this case, you must provide a template. Check the doc for toext here for an example: https://petl.readthedocs.io/en/latest/io.html#text-files
The template describes the format of each row that it writes out using the field headers to describe things, you can optionally pass in a prologue to write the header too. A basic template in your case would be:
table_new_template = "{L} {P} {C} {R} {I}"
totext(final_location, 'l1.txt', template=table_new_template)

AttributeError: NoneType object has no attribute

I, as a python novice, get the following error message when executing a code which I have received by the author:
line 412, in add_family
mother_birth_ref = mother.get_birth_ref()
AttributeError: 'NoneType' object has no attribute 'get_birth_ref'
The relevant part of the code must be this one here:
def write_child_stats(self):
file = open("%s/intern/child-stats.txt" % self.dir_name, 'w')
def add_family(family, marriage_event, divorce_event):
father_handle = family.get_father_handle()
mother_handle = family.get_mother_handle()
father = self.database.get_person_from_handle(father_handle)
father_birth_ref = father.get_birth_ref()
father_birth = None
if father_birth_ref:
father_birth = self.database.get_event_from_handle(father_birth_ref.ref)
mother = self.database.get_person_from_handle(mother_handle)
mother_birth_ref = mother.get_birth_ref()
mother_birth = None
if mother_birth_ref:
mother_birth = self.database.get_event_from_handle(mother_birth_ref.ref)
children = []
child_refs = family.get_child_ref_list()
for child_handle in child_refs:
child = self.database.get_person_from_handle(child_handle.ref)
if child:
child_birth_ref = child.get_birth_ref()
if child_birth_ref:
child_birth = self.database.get_event_from_handle(child_birth_ref.ref)
children.append("%04d-%02d-%02d" % child_birth.get_date_object().get_ymd())
How can I fix the issue?
mother = self.database.get_person_from_handle(mother_handle)
This line is returning None. Check get_person_from_handle function.
Alternatively, you can add a check :
mother = self.database.get_person_from_handle(mother_handle)
mother_birth_ref = None
mother_birth = None
if mother:
mother_birth_ref = mother.get_birth_ref()
if mother_birth_ref:
mother_birth = self.database.get_event_from_handle(mother_birth_ref.ref)

Categories