Printing lists with Mako template (Django Join tag) - mako

In this article Django templates like this
{% for i in mylist %}
<tr>
<td>{{i.replist|join:"</td><td>" }}</td>
</tr>
{% endfor %}
prints the list mylist which is an object. Can this be done in Mako? Thanks.
EDIT
class Rep(db.Model):
author = db.UserProperty()
replist = db.ListProperty(str)
unique = db.ListProperty(str)
date = db.DateTimeProperty(auto_now_add=True)
class MainPage(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
greeting = None
if user:
greeting = ("Welcome, %s! (sign out)" %
(user.nickname(), users.create_logout_url("/")))
else:
greeting = ("Sign in or register." %
users.create_login_url("/"))
L = []
s = self.request.get('sentence')
L.append(s)
L = L[0].split('\r\n')
def f2(L):
checked = []
for e in L:
if e not in checked:
checked.append(e)
return checked
Rep().replist = L
Rep().put()
mylist = Rep().all().fetch(10)
leng = len(mylist)
T = type(mylist)
self.response.out.write("Ttttt")
print [i for i in mylist]
L2 = f2(L)
x = len(L)
y = len(L2)
delta = x - y
for i in range(delta):
L2.append('')
q = Rep().all()
results = q.fetch(10)
db.delete(results)
template_values = {"s": s,
"L": L,
"L2": L2,
"x": x,
"y": y,
"greeting": greeting,
"mylist": mylist,
"leng": leng,
"T": T,
}
path = os.path.join(os.path.dirname(__file__), 'main.mako')
templ = Template(filename=path)
self.response.out.write(templ.render(**template_values))

http://www.makotemplates.org/docs/syntax.html#syntax_control
EDIT:
I would suggest using an ordered list or named tuple instead of a dictionary so you can focus on your output instead of your data.
% for entry in mylist:
<tr>
% for key, value in entry:
<td>${value}</td>
% endfor
</tr>
% endfor
You can nest these if you need to output many <td>s. To do the join part, just use a nested loop.

Related

Creating a menu, adding the input to a list or csv file and display

I am trying to create a programme that allows me to add, remove, amend and display details. I have created a general class and an additional class, that allowed me to hold an empty list and add/remove details.
I am now struggling with my menu and how to add further details and display these. Can anyone help, please?
from AircraftInspection_2 import AircraftInspection_2
from RoutineInspection import RoutineInspection
inspection = RoutineInspection()
end_of_add_String = "X to return to main menu\n"
def display_inspection_inventory():
#if inspection.number_of_aircrafts == 0
#return
print (f'{"SN":>3} {"TN":<7} {"AFhrs":<7} {"Zone":<3} {"Corrosion":<3} {"Component":<8} {"Fault":<8} {"Actionalbe":<5}')
for count aircraft in enumerate(inspection.aircrafts):
print(f'{count + 1:>3} {aircraft.Serial_Number:>3} {aircraft.Tail_No:<7} {aircraft.AF_hrs:<7} {aircraft.Zone:<3} {aircraft.Corrosion:<3} {aircraft.Component:<8} {aircraft.Fault:<8} {aircraft.Actionable:<5}')
def menu_options():
print("Menu: ")
print("Key A - Add details.")
print("Key R - Remove details.")
print("Key C - Change details.")
print("Key D - Display details.")
print("Key X - Exit the programme")
print(" ")
menu_options()
def menu_choice():
letters = {"a", "r", "c", "d", "x"}
select = input()
while any(letter in letters for letter in select) and len(select) == 1:
pass
return select
#menu_choice()
def add_aircraft():
aircraft = get_aircraft_details()
try:
routineinspection.add(aircraft)
except ValueError as e:
print(f"{str(e)}")
def get_aircraft_details():
Tail_No = input("Please enter tailnumber: ")
AF_hours = int(input("Enter airframe hours: "))
Zone = input("Enter inspected zone: ")
Corrosion = int(input("Enter corrosion level: "))
Component = input("Enter inspected component: ")
Fault = input("Enter type of fault: ")
Actionable = bool(input("Enter 1 if actionable, 0 if not: "))
aircraft = Aircraft(Tail_No = Tail_No, AF_hours = AF_hours, Zone = Zone, Corrosion = Corrosion, Component = Component, Fault = Fault, Actionable = Actionable)
return aircraft
def remove_aircraft():
routineinspection.remove(aircraft)
while True:
display_inspection_inventory()
menu_options()
menu_choice()
option = menu_choice().upper()
if option == "A":
add_aircraft()
elif option == "R":
remove_aircraft()
#elif option =="C":
#amend_aircraft()
elif option == "X":
confirm = input("Do you want to quit the programme, y or n?").lower()
if confirm == "y":
break
else:
pass
print("See you again soon.")

How to turn csv file data into a list WITHOUT the 'import csv'

So what I'm trying to do is, I'm trying to read the data in the CSV file into the empty lists I've defined at the top.
How can I do
this without the 'csv import'
L = []
F = []
G = []
A = []
class client ():
fh = open('fit_clinic_20.csv', 'r')
for line in fh:
data = fh.readlines()
L, F, G, A = fh.split(',')
I would try:
L = []
F = []
G = []
A = []
fh = open('fit_clinic_20.csv', 'r')
# first: you read lines
data = fh.readlines()
for line in data:
# you split every line into values
L_value, F_value, G_value, A_value = line.split(',')
# you append values to lists
L.append(L_value)
F.append(F_value)
G.append(G_value)
A.append(A_value)
Surely, there are more compact ways to do this, but I think that this way is well understandable.

Scrapy - Getting duplicated items when appending items using for loop

I am crawling the data from JSON response. Extracting data into item using for loop and all i get, is a last record rewriting all the previous records made by this loop.
Here is my code:
def parse_centers_and_ambulances(self, response):
json_response = json.loads(response.body_as_unicode())
facility = MedFacilityItem()
facility["name"] = "Med Facility #1"
centers = []
med_centers = MedCenterItem()
for center in json_response:
if center["name"].startswith("Center"):
med_centers["response_url"] = center["product_id"]
med_centers["name"] = center["name"]
med_centers["address"] = center["name_short"] + "." +
center["adr_name"] + " " +
center["adr_dom"]
med_centers["lat"] = center["latitude"]
med_centers["lon"] = center["longitude"]
med_centers["phoneInfo"] = [{"number": center["tel1"],
"description": center["tel1_descr"]},
{"number": center["tel2"],
"description": center["tel2_descr"]}]
centers.append(med_centers)
facility["facility_type"] = centers
return facility
What i am missing?
Since Scrapy items basically behave like dicts, I'm going to use dicts for the following examples. Consider this:
In [1]: dict_list = []
...: d = {}
...: for i in range(3):
...: d['i'] = i
...: dict_list.append(d)
...: print dict_list
...: print [id(e) for e in dict_list]
...:
[{'i': 2}, {'i': 2}, {'i': 2}]
[4557722520, 4557722520, 4557722520]
Dicts are mutable objects, and in this case you are appending the same dict instance multiple times to a list. The resulting list does not contain different items, only several references to the same dict object. The following example shows the same behaviour, appending the same dict three times to a list and then setting a value for it:
In [2]: dict_list = []
...: d = {}
...: for i in range(3):
...: dict_list.append(d)
...: d['some'] = 'value'
...: print dict_list
...:
[{'some': 'value'}, {'some': 'value'}, {'some': 'value'}]
What you need to do is create different dicts by initializing them inside the for loop, as follows:
In [3]: dict_list = []
...: for i in range(3):
...: d = {}
...: d['i'] = i
...: dict_list.append(d)
...: print dict_list
...: print [id(e) for e in dict_list]
...:
[{'i': 0}, {'i': 1}, {'i': 2}]
[4557901904, 4557724760, 4557843264]
You can try defining your item inside of the loop, instead outside of it.
def parse_centers_and_ambulances(self, response):
json_response = json.loads(response.body_as_unicode())
facility = MedFacilityItem()
facility["name"] = "Med Facility #1"
centers = []
# med_centers = MedCenterItem() <-- this
for center in json_response:
if center["name"].startswith("Center"):
med_centers = MedCenterItem() <-- should be here
med_centers["response_url"] = center["product_id"]
med_centers["name"] = center["name"]
med_centers["address"] = center["name_short"] + "." +
center["adr_name"] + " " +
center["adr_dom"]
med_centers["lat"] = center["latitude"]
med_centers["lon"] = center["longitude"]
med_centers["phoneInfo"] = [{"number": center["tel1"],
"description": center["tel1_descr"]},
{"number": center["tel2"],
"description": center["tel2_descr"]}]
centers.append(med_centers)
facility["facility_type"] = centers
return facility

PyMC3 how to implement latent dirichlet allocation?

I am trying to implement lda using PyMC3.
However, when defining the last part of the model in which words are sampled based on their topics, I keep getting the error: TypeError: list indices must be integers, not TensorVariable
How to tackle the problem?
The code is as follows:
## Data Preparation
K = 2 # number of topics
N = 4 # number of words
D = 3 # number of documents
import numpy as np
data = np.array([[1, 1, 1, 1], [1, 1, 1, 1], [0, 0, 0, 0]])
Wd = [len(doc) for doc in data] # length of each document
## Model Specification
from pymc3 import Model, Normal, HalfNormal, Dirichlet, Categorical, constant
lda_model = Model()
with lda_model:
# Priors for unknown model parameters
alpha = HalfNormal('alpha', sd=1)
eta = HalfNormal('eta', sd=1)
a1 = eta*np.ones(shape=N)
a2 = alpha*np.ones(shape=K)
beta = [Dirichlet('beta_%i' % i, a1, shape=N) for i in range(K)]
theta = [Dirichlet('theta_%s' % i, a2, shape=K) for i in range(D)]
z = [Categorical('z_%i' % d, p = theta[d], shape=Wd[d]) for d in range(D)]
# That's when you get the error. It is caused by: beta[z[d][w]]
w = [Categorical('w_%i_%i' % (d, w), p = beta[z[d][w]], observed = data[i,j]) for d in range(D) for w in range(Wd[d])]
Any help would be much appreciated!
beta[z[d][w]] is naturally incorrect because z[d][w] is a variable stored by PyMC instead of being an fixed index.
In pymc2 it is solved by lambda function
p=pm.Lambda("phi_z_%s_%s" % (d,i),
lambda z=z[d][w], beta=beta: beta[z])
In pymc3 it is suppose to be solved by
#theano.compile.ops.as_op
def your_function
But there is a problem here that it seems like Theano doesn't allow sending a python list of pymc variable. t.lvector baisically don't work.
More discussion is in this question:
Unable to create lambda function in hierarchical pymc3 model
The following code was adapted from what has been referenced by #Hanan. I've somehow made it work with pymc3.
import numpy as np
import pymc3 as pm
def get_word_dict(collection):
vocab_list = list({word for doc in collection for word in doc})
idx_list = [i for i in range(len(vocab_list))]
return dict(zip(vocab_list,idx_list))
def word_to_idx(dict_vocab_idx, collection):
return [[dict_vocab_idx[word] for word in doc] for doc in collection]
docs = [["sepak","bola","sepak","bola","bola","bola","sepak"],
["uang","ekonomi","uang","uang","uang","ekonomi","ekonomi"],
["sepak","bola","sepak","bola","sepak","sepak"],
["ekonomi","ekonomi","uang","uang"],
["sepak","uang","ekonomi"],
["komputer","komputer","teknologi","teknologi","komputer","teknologi"],
["teknologi","komputer","teknologi"]]
dict_vocab_idx = get_word_dict(docs)
idxed_collection = word_to_idx(dict_vocab_idx, docs)
n_topics = 3
n_vocab = len(dict_vocab_idx)
n_docs = len(idxed_collection)
length_docs = [len(doc) for doc in idxed_collection]
alpha = np.ones([n_docs, n_topics])
beta = np.ones([n_topics, n_vocab])
with pm.Model() as model:
theta = pm.distributions.Dirichlet('theta', a=alpha, shape=(n_docs, n_topics))
phi = pm.distributions.Dirichlet('phi', a=beta, shape=(n_topics, n_vocab))
zs = [pm.Categorical("z_d{}".format(d), p=theta[d], shape=length_docs[d]) for d in range(n_docs)]
ws = [pm.Categorical("w_{}_{}".format(d,i), p=phi[zs[d][i]], observed=idxed_collection[d][i])
for d in range(n_docs) for i in range(length_docs[d])]
trace = pm.sample(2000)
for d in range(n_docs):
value_z=trace.get_values("z_d{}".format(d))
print(value_z[1999])
check out this blog post. I haven't tested it.
import numpy as np
import pymc as pc
def wordDict(collection):
word_id = {}
idCounter = 0
for d in collection:
for w in d:
if (w not in word_id):
word_id[w] = idCounter
idCounter+=1
return word_id
def toNpArray(word_id, collection):
ds = []
for d in collection:
ws = []
for w in d:
ws.append(word_id.get(w,0))
ds.append(ws)
return np.array(ds)
###################################################
#doc1, doc2, ..., doc7
docs = [["sepak","bola","sepak","bola","bola","bola","sepak"],
["uang","ekonomi","uang","uang","uang","ekonomi","ekonomi"],
["sepak","bola","sepak","bola","sepak","sepak"],
["ekonomi","ekonomi","uang","uang"],
["sepak","uang","ekonomi"],
["komputer","komputer","teknologi","teknologi","komputer","teknologi"],
["teknologi","komputer","teknologi"]]
word_dict = wordDict(docs)
collection = toNpArray(word_dict,docs)
#number of topics
K = 3
#number of words (vocab)
V = len(word_dict)
#number of documents
D = len(collection)
#array([1, 1, 1, ..., 1]) K times
alpha = np.ones(K)
#array([1, 1, 1, ..., 1]) V times
beta = np.ones(V)
#array containing the information about doc length in our collection
Nd = [len(doc) for doc in collection]
######################## LDA model ##################################
#topic distribution per-document
theta = pc.Container([pc.CompletedDirichlet("theta_%s" % i,
pc.Dirichlet("ptheta_%s"%i, theta=alpha))
for i in range(D)])
#word distribution per-topic
phi = pc.Container([pc.CompletedDirichlet("phi_%s" % j,
pc.Dirichlet("pphi_%s" % j, theta=beta))
for j in range(K)])
#Please note that this is the tricky part :)
z = pc.Container([pc.Categorical("z_%i" % d,
p = theta[d],
size = Nd[d],
value = np.random.randint(K, size=Nd[d]))
for d in range(D)])
#word generated from phi, given a topic z
w = pc.Container([pc.Categorical("w_%i_%i" % (d,i),
p = pc.Lambda("phi_z_%i_%i" % (d,i),
lambda z=z[d][i], phi=phi : phi[z]),
value=collection[d][i],
observed=True)
for d in range(D) for i in range(Nd[d])])
####################################################################
model = pc.Model([theta, phi, z, w])
mcmc = pc.MCMC(model)
mcmc.sample(iter=5000, burn=1000)
#show the topic assignment for each word, using the last trace
for d in range(D):
print(mcmc.trace('z_%i'%d)[3999])

Easier way to create a JSON object from an SQLObject

EDIT -- took the code from below and made it so it can handle ForiegnKeys, Decimal numbers (although i'm doing a very forced float conversion). It returns a dict now so it can be recursive.
from sqlobject import SQLObject
from decimal import Decimal
def sqlobject_to_dict(obj):
json_dict = {}
cls_name = type(obj)
for attr in vars(cls_name):
if isinstance(getattr(cls_name, attr), property):
attr_value = getattr(obj, attr)
attr_class = type(attr_value)
attr_parent = attr_class.__bases__[0]
if isinstance(getattr(obj, attr), Decimal):
json_dict[attr] = float(getattr(obj, attr))
elif attr_parent == SQLObject:
json_dict[attr] = sqlobject_to_dict(getattr(obj, attr))
else:
json_dict[attr] = getattr(obj, attr)
return json_dict
EDIT -- changed to add the actual data model -- there are generated values that need to be accessed and Decimal() columns that need dealing with as well.
So I've seen this: return SQL table as JSON in python but it's not really what I'm looking for -- that's "brute force" -- you need to know the names of the attributes of the object in order to generate the JSON response.
What I'd like to do is something like this (the name of the class and it's attributes are not-important)
class BJCPStyle(SQLObject):
name = UnicodeCol(length=128, default=None)
beer_type = UnicodeCol(length=5, default=None)
category = ForeignKey('BJCPCategory')
subcategory = UnicodeCol(length=1, default=None)
aroma = UnicodeCol(default=None)
appearance = UnicodeCol(default=None)
flavor = UnicodeCol(default=None)
mouthfeel = UnicodeCol(default=None)
impression = UnicodeCol(default=None)
comments = UnicodeCol(default=None)
examples = UnicodeCol(default=None)
og_low = SGCol(default=None)
og_high = SGCol(default=None)
fg_low = SGCol(default=None)
fg_high = SGCol(default=None)
ibu_low = IBUCol(default=None)
ibu_high = IBUCol(default=None)
srm_low = SRMCol(default=None)
srm_high = SRMCol(default=None)
abv_low = DecimalCol(size=3, precision=1, default=None)
abv_high = DecimalCol(size=3, precision=1, default=None)
versions = Versioning()
def _get_combined_category_id(self):
return "%s%s" % (self.category.category_id, self.subcategory)
def _get_og_range(self):
low = self._SO_get_og_low()
high = self._SO_get_og_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.3f - %.3f" % (low, high)
def _get_fg_range(self):
low = self._SO_get_fg_low()
high = self._SO_get_fg_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.3f - %.3f" % (low, high)
def _get_srm_range(self):
low = self._SO_get_srm_low()
high = self._SO_get_srm_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.1f - %.1f" % (low, high)
def _get_abv_range(self):
low = self._SO_get_abv_low()
high = self._SO_get_abv_high()
if low == 0 and high == 0:
return "varies"
else:
return "%.2f%% - %.2f%%" % (low, high)
def _get_ibu_range(self):
low = self._SO_get_ibu_low()
high = self._SO_get_ibu_high()
if low == 0 and high == 0:
return "varies"
else:
return "%i - %i" % (low, high)
Is there an easy way, pythonic way to write that magic to_json() function?
You can use the python json module with the SQLObject sqlmeta class. Like this:
def to_json(obj):
return json.dumps(dict((c, getattr(obj, c)) for c in obj.sqlmeta.columns))
When I run this with your class Foo I get:
>>> print to_json(f)
{"bar": "test", "lulz": "only for the", "baz": true}
Edit: if you want to include magic attributes in your json string and you don't mind using something of a hack, you could abuse the fact that the attributes of your object are python properties. For example, if I add a magic attribute foo to your original sample class:
class Foo(SQLObject):
bar = UnicodeCol(length=128)
baz = BoolCol(default=True)
lulz = UnicodeCol(length=256)
def _get_foo(self):
return "foo"
Then I can define the to_json() function like this:
def to_json(obj):
cls = type(obj)
d = dict((c, getattr(obj, c)) for c in vars(cls) if isinstance(getattr(cls, c), property))
return json.dumps(d)
Now, if I do this:
f = Foo(bar = "test", lulz = "only for the")
print to_json(f)
I get the following result:
{"baz": true, "lulz": "only for the", "bar": "test", "foo": "foo"}
import json
json.dumps(obj_instance.sqlmeta.asDict())
In my case this object contained datetimes which json doesn't serialize, so I did something like this:
json.dumps(dict((k, str(v)) for (k,v) in obj_instance.sqlmeta.asDict().items()))
Something like this ...
class MyTable( sqlobject.SQLObject ):
# ... your columns ...
json.dumps({
'MyTable': [row.sqlmeta.asDict() for row in MyTable.select()]
}, indent=4, sort_keys=True )
Suppose you have a list of sqlobject.SQLObject derived classes called
'Tables'
Tables = [MyTable, ...]
def dump():
r={}
for t in Tables:
r[t.__name__] = [row.sqlmeta.asDict() for row in t.select()]
return json.dumps(r, indent=4, sort_keys=True)