Polling demand for Pycha charts

I’ve been looking over my statistics for the past few months on this blog and it quickly becomes apparent that the most sought after item is in fact the Pycha charts post. ( http://www.robvennikfotografie.nl/jvennik/?p=69 )

Seeing as I wrote it roughly a month after I was introduced to the whole Django situation, I pondered the idea of rewriting the post with the knowledge I posses now to form a better resource for those of you looking to implement a chart system. So if you’re interested in the above, please react to this post. Preferably by commenting, I fear that I cannot communicate so well with smoke signals.

Tags: , , ,

No Comments


Uploading to Amazon S3 using the GAE + Django

The project I’m involved with needed to serve media files to an external data storage, in this case the Amazon S3 storage. I used the following to make this work.

  • Google AppEngine
  • Django (Appengine helper is recommended)
def add_media(request, research_id):
research = Research.get_by_id(int(research_id))
return render_to_response(”research/add_media.html”, RequestContext(request, {’research_id’: research_id, ‘research’: research}))

I created this simple function in the views.py of my app. It basically just sends out the research_id (which is required for some links on the page) and it grabs the research object that I’ll need to read out in the template.

def add_media(request, research_id):
research = Research.get_by_id(int(research_id))
return render_to_response(”research/add_media.html”, RequestContext(request, {’research_id’: research_id, ‘research’: research}))

The following is an excerpt from the template on how to construct the form. If you need help constructing your policy and signature, you can use the following website.

http://www.jfileupload.com/products/js3upload/documentation/policygenerator.html

Add media for: <strong>{{ research.title }}</strong><br />
<form action=”http://YOURBUCKET.s3.amazonaws.com/” method=”post” enctype=”multipart/form-data” id=”mediaForm” onsubmit=’return add_key()’>
<input type=”hidden” id=”key” name=”key” value=”" /><br />
<input type=”hidden” name=”acl” value=”public-read” />
<input type=”hidden” name=”success_action_redirect” value=”YOURREDIRECT” >
<input type=”hidden” name=”AWSAccessKeyId ” value=”YOURACCESSKEY” />
<input type=”hidden” name=”Policy” value=”YOURPOLICY” />
<input type=”hidden” name=”Signature” value=”YOURSIGNATURE” />
File: <input type=”file” name=”file” id=”file” /> <br />
<input type=”submit” name=”submit” value=”Upload” />
</form>

Adjust the form according to your policy wishes. I have no restrictions on the key value, as I serve them dynamically through the javascript function add_key().

<script type=”text/javascript”>
function add_key()
{
var key = document.getElementById(’key’);
var filename = document.getElementById(’file’);
key.value = “{{ research.slug }}/” + filename.value;
}
</script>

So if your research slug would be “testresearch” and your filename is “image.jpg” the output of key would be “testresearch/image.jpg”.

Hope this helps for anyone having any difficulties with GAE and Amazon S3

Tags: , , , , ,

No Comments


Export to excel using the Google App Engine and XLWT

I’ve recently starting working on a new webplatform that required the option to export data to an excel document, whilst not taking up any space on the filesystem. Considering that we’re using the google appengine. Now you could use the Amazon S3 storage for this, but as we don’t have any access to an account for that just yet. I chose to take it on as follows:

What you need:

I personally used django set up with the Google App Engine Django Helper.

class ExcelResponse(HttpResponse):

def __init__(self, data, headers=None, force_csv=False, encoding=’utf8′):
research = Research.get_by_id(int(data))
output_name=research.slug
output = StringIO.StringIO()
wbk = xlwt.Workbook(encoding=encoding)
sheet = wbk.add_sheet(research.slug)
sheet.write(0,0, research.title)
wbk.save(output)
mimetype = ‘application/vnd.ms-excel’
file_ext = ‘xls’
output.seek(0)
super(ExcelResponse, self).__init__(content=output.getvalue(),
mimetype=mimetype)
self['Content-Disposition'] = ‘attachment;filename=”%s.%s”‘ % \
(output_name.replace(’”‘, ‘\”‘), file_ext)

We start off by creating a class that will end up returning as a HttpResponse object. Among the *args, data is the one that receives an id from a different function ( see below). We have to typecast data into an int for it to work in the query to research.

output_name will be the filename preceding the extension. Output starts a StringIO object. wbk then creates a new workbook, a sheet is created afterwards with the research slug as its label. We then write the research title to the first row and first cel and save that to the StringIO object. Specify further information for the filetype and then return it to the client.

To put this to use, I’m using a simple request handler that looks like this:

@check_project_owner
def excel_report(request, r_id):

return ExcelResponse(data=r_id)

check_project_owner is a simple decorator that checks if the current logged in user corresponds with the research we’re trying to retrieve. It then returns the HttpResponse object class Excelresponse with the research id as the data.

Tags: , , , , , ,

No Comments


The Next Web chapter two

This upcoming Monday I’ll be starting the next semester of my study after a (what seems to be a short) summer vacation. As I have it planned at this moment, I’ll be enrolling in a new Django project. To my knowledge there will be several available, so we’ll see what happens there. Should be good no doubt.

I’ve formatted my laptop and am currently trying out a Windows 7 build, however I’ll be dual-booting it with Ubuntu Linux to get Django set up for the new project. Any interesting developments regarding Django that I come across will be posted here as I have before (kind of!) as demonstrated in the previous post. Now I haven’t really gotten around to get back into the whole ordeal that is Django, but I’m sure it’ll all come back from foggy memories dating back a year.

Next to that I’m currently looking around for a internship that involves webdevelopment / design, Django related would be greatly appreciated. Still unsure whether I want to go abroad for this one or not, it does however seem very appealing for my CV as well as general work experience of course!

Tags: , , ,

No Comments


Django – Pycha charts

As promised, I’m going to display a simple way to generate a piechart through a form in Django, using Pycha and Cairo. You’ll need to get the libraries for both naturally (Google is your friend). Do note that I’m showing it to you in the simplest of ways.

Starting off right away with the forms.py:

We’re creating a small form with 8 input values. 4 Labels for the corrosponding 4 values, as shown below.

class PieChartForm(forms.Form):
val_1_label = forms.CharField(max_length=45)
val_1 = forms.IntegerField()

val_2_label = forms.CharField(max_length=45)
val_2 = forms.IntegerField()

val_3_label = forms.CharField(max_length=45)
val_3 = forms.IntegerField()

val_4_label = forms.CharField(max_length=45)
val_4 = forms.IntegerField()

That is basically all we need as far as the forms go. Moving on to the views.py, we’ll start off with some essential imports.

import cairo
import pycha.pie
import pycha.bar
from pycha.chart import Option

Moving on to the function itself.

def piechart(request):
if request.method == ‘POST’:
form = PieChartForm(request.POST)
if form.is_valid():

This bit checks whether there is POST data availablem if so it requests the data for the form. Then it checks whether the form data is actually valid. Following is a lengthy-ish bit of code to sort out all the data.

graph_lable1 = request.POST.get(’val_1_label’).encode(’latin-1′)
graph_lable2 = request.POST.get(’val_2_label’).encode(’latin-1′)
graph_lable3 = request.POST.get(’val_3_label’).encode(’latin-1′)
graph_lable4 = request.POST.get(’val_4_label’).encode(’latin-1′)

graph_val1 = int(request.POST.get(’val_1′))
graph_val2 = int(request.POST.get(’val_2′))
graph_val3 = int(request.POST.get(’val_3′))
graph_val4 = int(request.POST.get(’val_4′))

The above section places the post data into variables and casts them into strings and integers. As the generator cannot process unicode results. We move on by defining the actual canvas to draw on, including the insertion of data.

width, height = (500, 400)
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
dataSet = (
(graph_lable1, ((0, graph_val1), (0, 0))),
(graph_lable2, ((0, graph_val2), (0, 0))),
(graph_lable3, ((0, graph_val3), (0, 0))),
(graph_lable4, ((0, graph_val4), (0, 0))),
)

In this case it’ll be a 500 x 400 canvas. Also, the additional zeroes are indeed required if you wish for the generator to actually generate anything other than an error. Next up we can set some options for the generator.

options = {
‘legend’: {’hide’: False},
‘background’: {’color’: ‘#fff’},
‘colorScheme’: ‘blue’,
}

The options within do exactly what they say, so I won’t be going into that. We continue by actually saving the PNG file.

filename = ‘/home/user/png-gen/png-file.png’
chart = pycha.pie.PieChart(surface, options)
chart.addDataset(dataSet)
chart.render()
surface.write_to_png(filename)

Naturally, you can do a lot of things with the filename. I created the function for a website that allows the creation of this within projectgroups. So we needed a way to allow for several files to be generated for a group instead of having them overwrite eachother continuously. This is the variable I used:

current_time = str(datetime.datetime.now().strftime(’%Y-%m-%d-%H:%M:%S’))
filename = settings.MEDIA_ROOT + ‘/project_files/’ + str(project_id) + ‘/graphs/piechart-’ + current_time + ‘.png’

If you’ve completed all the above steps, you’ll need to return the function to something. You could use a render_to_response to write the generated image back to a template. Like so:

return render_to_response(”app/media_render.html”, locals(), context_instance = RequestContext(request))

You can add the following for the form validation and for when there is no POST data available:

else:
# If the form does not return valid data, provide an alert message and redirect link to the previous page
return HttpResponse(”Error message here”)
else:
# If there is no POST data, generate the form
form = PieChartForm()
return render_to_response(”businessplan/piechart.html”, {’form’: form}, context_instance = RequestContext(request))

Good luck!

P.S. Do mind the indenting, that’s something WordPress does not do so well without the code plugin that I haven’t gotten around to installing just yet.

Tags: , , , ,

1 Comment


Web usability presentation – The Next Web

I did a presentation about the very basics of web usability a couple of weeks ago for the minor “The Next Web” at the NHL University of Applied Sciences. In this post I will share the content of it in text form.

Web usability is all about the presentation of information.  In general, you should always try to put ‘vital’ content above any other main content, as this is likely to be what users come to your website to see!

Presenting the right choices. If your navigation isn’t crystal clear as to what it leads to, you will lose visitors without question.

Positioning of elements. Many studies have been done on how people view a website, one of the small standards is that users generally view a page from left to right. Prioritizing your content in that style will lead to a website with a better overview and ease of use for potential visitors.

When designing / creating websites, usability is extremely important if you wish to keep your visitors. As opposed to them leaving due to faulty mechanics or just poor structure present on the page. A few examples that I mentioned in my presentations include:

Don’t use <HR> (horizontale ruler) tags to divide your content.
Using headings and subheadings provide a much clearer structure.

Stretching your website horizontally which will eventually show the horizontal scrollbar is a big no go as well.
Horizontal scrolls are almost non-existant in today’s websites, people are not used to these situations and will not even notice it 99% of the time. Next to the fact that it’s simply tedious to work with a website in such a way.

Using <b> (bold) as opposed to <strong> tags.
This is dubbed under semantic tags, one of the things I mentioned in my presentation was that screenreaders are unable to read <font size=”11″> and <b> tags properly. Of course there are many other advantages to using such techniques. For those that are interested in this particular subject, check out the following URL: http://blogs.sun.com/coolstuff/entry/value_of_semantic_tags

Simplicity rules.
After you’ve created a mock layout of a website, it’s a good idea to take a good look at it and remove any graphical addition that does not contribute to the structure of the website. Images are, after all only there to enhance the readability / present a certain style for your sector. (Corporate, gaming, education)

A couple of do and don’t pointers that I haven’t mentioned yet.

Do:

  • Use ALT tags for graphical elements, it’s a must. This isn’t only a W3C compliance issue, but surprisingly enough there are still many people using a text-based browser.
  • Black text on a white background optimizes pages for printing. If you use a script to actually output such values for printing anyway, using a very light grey tint may comfort the eyes a bit better still.
  • Consistent positioning of elements is very important unless you’re keen on losing visitors. When a content frame suddenly changes it’s position while navigating to a secondary page it will be only generate confusion and quite possibly annoyance.
  • Use the “fold” to create curiousity. The fold is the part of your screen where the page disappears into the status bar and you’ll have to scroll down to read / view further information. Placing an image of something interesting (and relevant of course) can trigger the curiousity for people to scroll down.

Don’t:

  • Use blue or underlined text either seperate or conjoined will make the users believe it’s a link. If this turns out to be false, it’ll only generate confusion.
  • Use completely bold and or upper case text is hardly pleasant to read.
  • Need the scroll bar to view important information.

Finally, two small subjects that I won’t cover in this post. However I will link to them, are the following.

Heatmaps: See how your users behave on your website (click-based).

Eyetracking: Research on how the users’ eyes browse your website.

Tags: , , , , ,

2 Comments


Things to come..

A couple of things that I want to re-add in the near future are as follows:

Overview of my presentation on Web Usability
I did a presentation some time ago about Web Usability, I’ll share it in text form in the near future.

Pycha Charts
Another feature I’ve developed for an ongoing project that involves using a form to generate a .PNG of several charts.
(PieChart, Vertical/Horizontal bar charts for example)

Over the past few weeks I’ve familiarized myself with the Django framework for Python. As far as anyone can within just a couple of weeks. The main issue I’m having with Django momentarily is, that a lot of things that we are trying to accomplish get’s us confronted with errors that are quite simply undocumentated. I’ve even had to get an answer through a Chinese website once, go figure.

I’m guessing however that if Django does turn out to be as popular as some people seem to rave about it, one would hope that they brush up on that particular area (documentation). Not that there isn’t any available, there is a lot available momentarily. However if you’re working for a specific outcome that deviates slightly from generic projects… You may find yourself learning a few vulgar words you thought never existed.

Guess you’ll learn something one way or the other then!

Tags: , , , , , , ,

1 Comment


A new beginning

After some difficulties with my hosting, I found out that not all my data was backed up. So I pretty much lost all the data I had present on the blog. I’ll be writing up a couple of posts in the near future as my project with Django continues.

Happy new year as well of course.

Tags: , ,

No Comments



SetPageWidth