Averaging Numbers with Embedded Python Code inside HTML - python

This won't be a long or complex question. I'm just wondering if there is any simple way to accomplish calculating an average of numbers pulled from the datastore.
At the moment, I have this for loop inside my HTML:
{% for rating_tmp in ratings %}
{{rating_tmp.rating}}
{% endfor %}
... and it works nicely. Every time I add a value, the for loop places it on the page in a row:
2.5 4.5 2.5 3.5 etc...
Averaging numbers is obviously the sum of the numbers over the number of values. Can I throw more python in there and accomplish this all within the HTML? Or is this something that should go into main.py?

Absolutely! Just calculate the average in python inside HTML file. There is nothing wrong with doing that.

You can probably do this in a Jinja template, but I wouldn't recommend it. What you're doing here is pretty clearly logic, not layout, so you should do it in code, and pass it in as a variable or a property. If you change how you average in future, for instance, you should be changing the code that generates it, not the template that displays it.

Related

Why it is possible to use a split filter in ansible?

It might look like a weird question by, I really would like to understand this. I am new to Ansible, and I am trying to understand how I could figure out that I can use a filter called split. As I understand, the Ansible filters are builtin inside Jinja2 engine. On the project website there is nothing about split filter. I am really confused how come, it is possible to use split filter.
On Ansible website there is one mention about split
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
To split a string into a list:
{{ csv_string | split(",") }}
My question here is, how would I know that I can do | split(",",1)
that page does not explain that for example I could call a split filter with delimeter and a integer that describes how many times I want to split it.
Is there a different documentation, or a way to figure those things out on my own?
I was told that I could do in Python:
help(str.split)
And this explains me how to use split method, this is great however, how can I be sure that this is the same way of implementation as in the Ansible filter? Is this split filter from Ansible documentation inside 'Ansible' or inside Jinja? And maybe its just missing from documentation in Jinja website?
This doesn't explain where | split(",") is coming from but per the Jinja docs:
Python Methods
You can also use any of the methods defined on a variable’s type. The value returned from the method invocation is used as the value of the expression. Here is an example that uses methods defined on strings (where page.title is a string):
{{ page.title.capitalize() }}
So str.split() should also be valid syntax and work the same way.

What is the need of memoization in python

I was reading this article
http://programmingzen.com/2009/05/18/memoization-in-ruby-and-python/
Actually can anyone please explain with example what will happen if i don't use it. I am not able to find which problem is solved by it. I just want to know two example where in one simple example without memoization and other with memoization so that i can see why we use it.
If example can be based on web realted stuff or Django that will be good so that i cam more understand it. I am not too techy in algorithms
Explained simply, I'll put the question like this. How many "E" characters are there in this block of text?
Now, how many "E" characters are there in the first block of text?
And now, how many "E" characters are there in the first block of text?
Finally, how many "E" characters are there in the first block of text?
If you were wondering, there were 9 "e"s and 2 "E"s in that first block. By the second run through, you probably already memorized how many "E"s there were in the first block. That's memoization for a count function/method over that block a text.
Memoization caches (stores) the most recently used results of the function so it can retrieve them fast later. Basically if you a function is slow but has has the same results most of the time it can be helpful.

Django Template Arithmetic

In my template, I am looping through a list, trying to make a two-column layout. Because of the desired two-column layout, the markup I need to write in the for loop is dependent on whether forloop.counter0 is even or odd. If I had the full power of Python in the template language, determining the parity of forloop.counter0 would be trivial, but unfortunately that is not the case. How can I test whether forloop.counter0 is even or odd using the Django template language, or just as good, is there another way I could get elements in the list to display alternatively in the left and right columns?
Thanks in advance!
You should probably use cycle here instead. As for your question, there is a filter called divisibleby.
The philosophy behind Django's template system is to avoid doing any serious logic in the template. Thus they only provide tools to do fairly basic calculations for cases like drawing grids etc.
You can use the divisibleby filter with forloop.counter:
{% if forloop.counter|divisibleby:"2" %}even{% else %}odd{% endif %}
Use cycle template tag:

Parsing a range of integers in a list

I've just began learning Python and I've ran into a small problem.
I need to parse a text file, more specifically an HTML file (but it's syntax is so weird - divs after divs after divs, the result of a Google's 'View as HTML' for a certain PDF i can't seem to extract the text because it has a messy table done in m$ word).
Anyway, I chose a rather low-level approach because i just need the data asap and since I'm beginning to learn Python, I figured learning the basics would do me some good too.
I've got everything done except for a small part in which i need to retrieve a set of integers from a set of divs. Here's an example:
<div style="position:absolute;top:522;left:1020"><nobr>*88</nobr></div>
Now the numbers i want to retrieve all the ones inside <nobr></nobr> (in that case, '588') and, since it's quite a messy file, i have to make sure that what I am getting is correct. To do so, that number inside <nobr></nobr> must be preceded by "left:1020", "left:1024" or "left:1028". This is because of the automatic conversion and the best choice would be to get all the number preceded by left:102[0-] in my opinion.
To do so, I was trying to use:
for o in re.finditer('left:102[0-9]"><nobr>(.*?)</nobr></div>', words[index])
out = o.group(1)
But so far, no such luck... How can I get those numbers?
Thanks in advance,
J.
Don't use regular expressions to parse HTML. BeautifulSoup will make light work of this.
As for your specific problem, it might be that you are missing a colon at the end of the first line:
for o in re.finditer('left:102[0-9]"><nobr>(.*?)</nobr></div>', words[index]):
out = o.group(1)
If this isn't the problem, please post the error you are getting, at what you expect the output to be.

Syntax error whenever I put Python code inside a Django template

I'm trying to do the following in my Django template:
{% for embed in embeds %}
{% embed2 = embed.replace("<", "<") %}
{{embed2}}<br />
{% endfor %}
However, I always get an invalid block or some syntax error when I do anything like that (by that I mean {% %} code inside a loop). Python doesn't have {} to signify "scope" so I think this might be my problem? Am I formatting my code wrong?
Edit: the exact error is: Invalid block tag: 'embed2'
Edit2: Since someone said what I'm doing is not supported by Django templates, I rewrote the code, putting the logic in the view. I now have:
embed_list = []
for embed in embeds:
embed_list[len(embed_list):] = [embed.replace("<", "<")] #this is line 35
return render_to_response("scanvideos.html", {
"embed_list" :embed_list
})
However, I now get an error: 'NoneType' object is not callable" on line 35.
I am quite sure that Django templates does not support that.
For your replace operation I would look into different filters.
You really should try to keep as much logic as you can in your views and not in the templates.
Django's template language is deliberately hobbled. When used by non-programming designers, this is definitely a Good Thing, but there are times when you need to do a little programming. (No, I don't want to argue about that. This has come up several times on django-users and django-dev.)
Two ways to accomplish what you were trying:
Use a different template engine. See Jinja2 for a good example that is fully explained for integrating with Django.
Use a template tag that permits you to do Python expressions. See limodou's Expr tag.
I have used the expr tag in several places and it has made life much easier. My next major Django site will use jinja2.
I don't see why you'd get "NoneType object is not callable". That should mean that somewhere on the line is an expression like "foo(...)", and it means foo is None.
BTW: You are trying to extend the embed_list, and it's easier to do it like this:
embed_list = []
for embed in embeds:
embed_list.append(embed.replace("<", "<")) #this is line 35
return render_to_response("scanvideos.html", {"embed_list":embed_list})
and even easier to use a list comprehension:
embed_list = [embed.replace("<", "<") for embed in embeds]
Instead of using a slice assignment to grow a list
embed_list[len(embed_list):] = [foo]
you should probably just do
embed_list.append(foo)
But really you should try unescaping html with a library function rather than doing it yourself.
That NoneType error sounds like embed.replace is None at some point, which only makes sense if your list is not a list of strings - you might want to double-check that with some asserts or something similar.
Django templates use their own syntax, not like Kid or Genshi.
You have to roll your own Custom Template Tag.
I guess the main reason is enforcing good practice. In my case, I've already a hard time explaining those special templates tags to the designer on our team. If it was plain Python I'm pretty sure we wouldn't have chosen Django at all. I think there's also a performance issue, Django templates benchmarks are fast, while last time I checked genshi was much slower. I don't know if it's due to freely embedded Python, though.
You either need to review your approach and write your own custom templates (more or less synonyms to "helpers" in Ruby on Rails), or try another template engine.
For your edit, there's a better syntax in Python:
embed_list.append(embed.replace("<", "<"))
I don't know if it'll fix your error, but at least it's less JavaScriptesque ;-)
Edit 2: Django automatically escapes all variables. You can enforce raw HTML with |safe filter : {{embed|safe}}.
You'd better take some time reading the documentation, which is really great and useful.

Categories