Tuesday, April 30, 2013

Beautiful CSS


For most websites, the main goal is to turn the usual web-surfer into a client, or at least get them to read the site's content. This can be quite saddening for some as a website can be so functional and informative, yet still overlooked. So, how can you make a surfer stay on your website? Capture his attention of course! However, considering today's fast paced society, the first few seconds a surfer spends on your site could be your only chance to do so. This is where CSS comes in.

[TEASER: It moves!]
If you want to try making this with CSS, continue reading.

CSS (Cascading Style Sheets) are incredible. To state it simply, they make your site look beautiful by defining how things should look. You don't have to be an IT expert to know this. If you were into Friendster before, you'd be familiar with CSS. Well, if you ever bothered changing your layout that is. I'm saying this because, embarrassing as it may, that's where I first encountered CSS and I honestly thought it was beautiful. It was only in college though that I fully understood its concept. All IT experts probably know this but I'll put in a short explanation for those who don't. Basically, you use CSS with HTML (HyperText Markup Language). It's like HTML is the content while CSS is the presentation of a document. Simple as that. But, it doesn't stop with just changing fonts, colors, alignments, and etc. As CSS standards continue to evolve, it gives more opportunities for web designers to revolutionize how websites look, such as with the animations given by CSS3.

So that you'll know what I'm talking about, try out the codes from the link below.


Did you try it? 

If you have, I hope you were able to understand what I meant by "beautiful CSS".

Internship: Week Two


It's week two of the internship at Ingenuity! We're mostly left on our own now. We did have two lectures at the start of the week: one on Version Control and another on Agile Methodology. After that, it was all us, just working on our project. We had our first stand-up meeting.

Oh, and our mentor. The interns are divided into groups with a mentor assigned to them to help them along. My group's mentor is usually available online when we need him—as compared to the other groups who have them in person. I wouldn't mind except for one thing: we can't get online! The internet connection has been spotty the last few days. I despair over the internet connection. /o\

Still, we can usually ask the friendly people in the office for help so it isn't all bad. We've just been delayed because we can't get online resources. It does get frustrating though, knowing that there's probably an easy solution online somewhere and you can't access it.

The workplace does help. It's calming and there's air conditioning. Hurray for cool temperatures! It's a change getting used to the work environment, but not a bad one. I'm not used to the cold so I keep wearing a jacket. I'm also eyeing the Ping Pong tables here. I want to play a game sometime. When I get some decent progress on my project, I'm possibly going to take some time off to play ping-pong. I DESERVE IT.

Not to mention the fact that I keep getting zapped by static electricity! Probably because of my jacket. I'm cautious about opening doors now. Tip: press your knuckle to the door handle first instead of your fingertips. Your knuckles are much less sensitive so even if you do get jolted, you probably won't feel it. It was annoying until I found that out, probably got jolted two dozen times this week.

There's also a water dispenser right behind me. I don't think I've ever drunk so much water at a constant basis. Might be because of the cold that I'm drinking more often (cold dehydrates you because the air is usually dryer) but it doesn't actually make you thirsty (something about fluid levels and vasoconstriction) so it's probably just me. I dunno, but at least I'll always be hydrated.

Though if there's one thing I can complain about, it's the chairs. They look cool and they ARE nice, but they get uncomfortable when you sit in them too long. And since most of my time is spent sitting, it becomes a problem. By the end of the week, I've gotten used to standing up and randomly doing stretches. Luckily enough, there are some nicer chairs in the office. I've got my eye on one of those swivel chairs....



Tuesday, April 23, 2013

Hello, World


Cool ambiance, calm feeling, and friendly environment – the first impressions I had upon entering the office. When I took the exam for internship, I really wanted to be there. It didn't seem like an office to me because from what I saw, they were all relaxed, or so it seemed. The office didn't seem like an office. It looked more like a lounge or a house to me. That’s what makes it special. No dress codes, no harsh environment, no scary people. Think of how that affects a productivity of a person.

Serving our internship at Ingenuity is just like attending school. We have our desks, our laptops, and our teacher. We have lessons on mornings and exercises in the afternoon. We are few of the lucky ones who actually learn while serving an internship. We are blessed with people who teach us things which we do not directly learn from our school. The best part is that we get it for free and also, we are blessed with a very comfortable lecture room.

We get the best of our time during our lectures. It’s always good to pay attention to what is being taught and also, prepare all the necessary things (operating systems, software, knowledge, etc.) before each session. It is always good to have a first step especially when you know the schedule. However, we all have our share of problems. On the 1st week of internship, I had problems coping up because I didn't have the appropriate operating system. Because of this, I got left behind and I was asking everyone I know on what to do. Though sometimes the lectures are fast, thanks to my fellow interns, I am able to catch up with the lessons.

To conclude the 1st week, we got a taste of what it feels like to work in a stress-free office--an office where you can feel that everybody is just chilling. Big thanks to the first person who welcomed us to the company, Ma'am Ghea, for being jolly, for making us alive, for giving us a good first impression about the office.  

All Sorts of Pancakes

Python has a handy built-in method for sorting objects in a list intuitively called sort(). Although this functionality is great, there are times that we need to use a different type of sorting to solve certain problems. Last week, we interns were given exercises to familiarize ourselves with the Python programming language. One of the exercises given was to sort a list of numbers using a technique similar to flipping a stack of pancakes (hence known as the pancake sort). The goal is to arrange the list by reversing one group of pancakes at a time.
Mmmmm... pancakes...
Mmmmm... pancakes... ♥

By utilizing what we have learned from our discussions, I used one of the built-in data types in Python called the list to solve the pancake problem. A list is similar to an array in other programming languages, but is more advanced and versatile. It can hold different types of values such as strings, objects, and even lists in itself.

Some of the available methods for a list we can use for the pancake sort includes:
  • list[n:m]: returns a subset of the list starting from n to m
  • list.index(n, i): returns the index of the item n in a list starting from i
  • max(list): returns the largest item in a list
  • len(list): returns the total length or number of items in a list
  • reversed(list): returns a reversed copy of the list
Now suppose you have a tower of pancakes with different sizes. The process of the pancake sort goes like this:
  1. Find the largest pancake m in the unordered part of the list
  2. Flip the group of pancakes from the topmost pancake to pancake m so that m will be at the top
  3. Flip the unordered part again so that m will be at the bottom of the list
  4. Repeat until all pancakes are in the right place
By using the available methods, the final product will (or may) look similar to this:
    for i in range(len(pancakes)):
        largest = pancakes.index(max(pancakes[i:len(pancakes)]), i)
        if largest != i:
            if largest != len(pancakes):
                pancakes[largest:len(pancakes)] = reversed(pancakes[largest:len(pancakes)])
            pancakes[i:len(pancakes)] = reversed(pancakes[i:len(pancakes)])
And that is it, pancit. Place it in a function and pass it a list and it will be sorted pancake-style!

Last few words I want to say: though I may not look like it, I am still a guy who loves simplicity and beauty. And that my friends is why I love pancakesPython. :)

Friday, April 19, 2013

Introducing django-annoying



Let's face it. There are lots of problems that we encounter when developing using Django framework. The main problems are listed below. This is where django-annoying comes in. It alleviates some of the issues in Django and provides some useful solutions.
Main Problems:
- A wise man said, "Try and except is much slower in python".
- Static files serving
Solution:
- Use django-annoying
        django-annoying eliminates certain annoyance in Django framework.
Example usage:
from annoying.functions import get_object_or_None

def get_user(request, user_id):
    user = get_object_or_None(User, id=user_id)
    if not user:
        ...

Normal installation:
1. pip install django-annoying
2. go into site-packages and copy annoying directory
3. paste it into your project directory
Shortcut installation:
I took the liberty of attaching the annoying folder along with this post so you don't have to install django-annoying to get a copy of the annoying folder. So all you have to do is download the attachment, unzip it, and copy the annoying folder into your project directory.
For more information, please have a look at their wiki page:

Tuesday, April 16, 2013

Ebook: Hacking Secret Ciphers with Python


Al Sweigart of Invent with Python has released a new ebook, Hacking Secret Ciphers with Python. The book is an introduction to cryptography with extensive code examples in Python. From the description:

The book features the source code to several ciphers and hacking programs for these ciphers. The programs include the Caesar cipher, transposition cipher, simple substitution cipher, multiplicative & affine ciphers, Vigenere cipher, and hacking programs for each of these ciphers. The final chapters cover the modern RSA cipher and public key cryptography.

Hacking Secret Ciphers is the third installment in Sweigart's series of Invent with Python books, the first two being Invent Your Own Computer Games with Python and Making Games with Python. The books are aimed at beginning programmers but scale well to more advanced topics.

Thursday, April 11, 2013

Git Workflow



When working on a project with multiple developers, it is very important to follow specific guidelines for revision control so that code collaboration or integration will be easier and the project's revision history will be clean. This article describes a simple version control workflow that we follow based from Github flow.
  • Keep the master branch deployable.  This means that the master branch should be kept stable and safe to deploy all the time. No one should be pushing anything on this branch instead, one should branch off of it and work on that branch.
  • Work on feature branches. When starting to work on a feature, create a branch off of master and name it descriptively (some examples of branch names:  cyclomatic-complexity-calculation,template-redesign, ticket-101-user-workdesk, etc.). Changes should be committed on the branch regularly and push to the same named branch on the remote or main repository so that everyone in the team will know what is being worked on. It is also important to keep the branch updated by rebasing to the master branch.
  • Keep your changeset clean. Do not mix unrelated features or changes in a single commit and use a commit message that clearly specify the essence of the commit. When using an issue tracker  such as that of Github, Redmine, Bitbucket and others, it is also good to add a reference to the issue being addressed in the commit message. repository
  • Commit often. With frequent commits, one can see the evolution of the code that is being worked on and it also gives one a place to go back to when something goes wrong in the current revision.
  • Review the code and merge to master. After the feature branch has been tested and when it is ready to be integrated with the development main line, merge the branch with master. When using Github, one must open a pull request and the repository maintainer will be the one to perform the merge.
  • Deploying a stable release. When the code is ready for release, it is good to tag the current revision with the release name or version or create a new branch for the release. For information on tagging, follow this link.

For further reading:

Wednesday, April 10, 2013

Get All Fields in a Model


Say for example you have the following model:
from django import models

class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(Author)
    date_published = models.DateTimeField(default=datetime.datetime.now())
Then you wanted to get all fields or field names of the Book model.

Solution:

You can actually do two things.
First:
If you wanted to get all fields as an object, you can add the following as a method in your Book model:
def get_model_fields(self):
    return self._meta.fields
Second:
If you wanted to get all field names of the Book model, then you can add the following method:
def get_model_field_names(self):
    return self._meta.get_all_field_names()

Note:

There is a big difference between the two methods above. The first one returns a list of objects based on Book model while the second one returns a list of strings so use them according to your needs.

Monday, April 8, 2013

Summer OJT 2013

Summer is here again and college students are scrambling on top of each other trying to secure a good company to intern with. With very few IT companies here in Davao City, some spend their entire internship doing tasks in offices that barely have anything to do with their course or have little bearing on their related learning experience, if at all.

We at Ingenuity have always been emphatic to the plight of the academe. With so few dedicated IT companies here, a relevant internship is few and far between. So every summer, we make it a point to contribute what we can.

This year, we invited everyone who's interested to apply to come join us for the OJT. It used to be that the interns would only be a select few, mostly top students running for Latin honors or those whose potential was so awesome, their talents are on the Tech Industry gossip vine. Now, everybody was invited to join. Needless to say, the applications came pouring in.



We leveled the playing field with generic and basic questions on our screening exams and gave the applicants free rein to be creative with answering their essay questions.

Although most of them have passable knowledge about basic programming concepts, mostly everyone impressed us by getting really high grades in other parts of the exams and for being pleasantly surprising in how they answered their essays.

My name is Eduardo but you can call me Nonoy.
I am not very handsome, but don't call me shokoy.
My goal is to have fun, get experience, and to learn.
So one day I can have a job for me to earn.
I had made a short poem, I hope you don't mind.
I am not such a bad person, the truth is I am kind. :)


It's not everyday that you see an Indian kid call himself "Bombay" good naturedly


We are so excited to mentor these kids for the summer! They will learn Python-Django and more awesome stuff that will add to their knowledge and hopefully make them better programmers in the future.

haystack + SOLR search and wkhtmltopdf in Django

Two of the most useful tools in web app development are searching and the pdf export. I will be introducing Django apps that do just those. There are official tutorials but here I'll be discussing the basics of customization.

Haystack Search + SOLR

First up, the search app. The most popular Django app for searching, as far as I know, is django-haystack. It supports several searching backends - the more advanced SOLR, ElasticSearch, Xapian, and the simpler Whoosh.

I have tried Whoosh but so far, I like SOLR better. Haystack supports functions for SOLR that are not in Whoosh; one in particular is faceted search.

You'd need to have an Apache server running Tomcat to setup SOLR (see setup guide on their website). If you lack the resources or just don't want to be bothered with setting up Apache, Tomcat, and SOLR - the works, there is a free SOLR service on the web - http://opensolr.com/. You can create a free account and setup a SOLR core on which to store your indexes. All you need to do is to upload your schema.xml - the structure of your indexes which I will discuss later.

The first thing you need, assuming you already have a SOLR backend setup, is to install haystack into your virtual environment which can be done by a simple pip install django-haystack. Create a search_sites.py file inside your app:
#!/project/your_app/search_sites.py

import haystack
haystack.autodiscover()

Then add these to your django settings file:
INSTALLED_APPS = (
    ...
    'haystack',
    ....
)

HAYSTACK_SITECONF = 'your_app.search_sites' #path to your search_sites.py file
HAYSTACK_SEARCH_ENGINE = 'solr'
HAYSTACK_SOLR_URL = 'http://localhost:8080/solr/' #url of your SOLR backend
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 20
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
        'URL': HAYSTACK_SOLR_URL
    },
}

Haystack + SOLR works by creating an index of your data. The index is what the SOLR backend will use for searching. To create that index, you need to create a search_indexes.py file in your app directory. Haystack automatically searches for any such file. Inside, you'll create the structure of your index like so:
#!/project/your_app/search_indexes.py

from datetime import datetime
from django.template.defaultfilters import slugify
from haystack import indexes, site

from your_app.models import YourModel

class YourModelIndex(indexes.RealTimeSearchIndex):
    """
       This class will be the structure of your index.
       It must inherit from one of haystack's index types.
       I recommend RealTimeSearchIndex as it updates automatically 
       your index when a model instance is modified or added.

       Notes:
       * there must always be a text field for each index class.
       * model_attr argument is used to associate your index field 
       with your model field. It takes a string - the name of your model field.
    """
    text = indexes.CharField(document=True, use_template=True)
    field1 = indexes.CharField(model_attr='model_field1', null=True)
    field2 = indexes.MultiValueField(null=True)
    modified = indexes.DateTimeField(model_attr='model_date_modified', null=True)
    sort_field = indexes.CharField(indexed=True)

    def get_model(self):
        return YourModel

    def prepare_field2(self, model_instance):
        """
           prepare_[one of your model index's field names] methods are added 
           if further processing of data is needed before being indexed, 
           for example, a list.
        """
        return [item.name for item in model_instance.your_multivalue_field.all()]

    def prepare_sort_field(self, model_instance):
        """
            I use this to manipulate data that I can manually sort later.
            Useful if you do a lot of sorting. 
            You can add as many sort fields as you need.
        """
        return slugify(model_instance.lastname+' '+model_instance.firstname)
    
    def index_queryset(self):
        """Used when the entire index for model is updated."""
        return self.get_model().objects.filter(date_modified__lte=datetime.now())


site.register(YourModel, YourModelIndex)

Next, you'll need to create the template for your index. The template must be in templates/search/indexes/your_app/yourmodel_text.txt. You'll have to make one for each model you need to index.
{% autoescape off %}
{{ object.lastname }}
{{ object.firstname }}
{% endautoescape %}

Once that's done, you'll need to create the schema for your SOLR. In your terminal run python manage.py build_solr_index. Copy the output to your SOLR's schema.xml configuration file and restart your server to load the changes. To start the indexing process, run python manage.py rebuild_index.

You can now start searching by using the default search page, all you need to do is point a url to a haystack view. If you'd rather customize your search, you can begin by subclassing one of haystack's many views i.e. SearchView. By subclassing, you can override the template and the form, essential for customizing the look and the behavior of your search.
#!/project/your_app/views.py
from haystack.query import SearchQuerySet
from haystack.views import SearchView


class MySearchView(SearchView):
    __name__ = 'MySearchView'
    template = 'my-search-template.html'
    
    def __init__(self, *args, **kwargs):
        # Needed to switch out the default form class.
        if kwargs.get('form_class') is None:
            kwargs['form_class'] = MySearchForm
        
        super(SearchView, self).__init__(*args, **kwargs)


def search(request):
    sqs = SearchQuerySet()
    form = MySearchForm(request.GET)
    if form.is_valid():
        cd = form.cleaned_data

    return MySearchView(form_class=MySearchForm, searchqueryset=sqs)(request)

Your form must subclass the SearchForm class from haystack. You can change the behavior of the search by adding form fields (i.e select fields, and radio button choices) and overriding the form's search method.
from your_app.models import YourModel

import haystack
from haystack.query import SearchQuerySet
from haystack.forms import SearchForm


class MySearchForm(SearchForm):
    #q is the default field in all SearchForm classes
    q = forms.CharField(required=False, label='Search') 
    field1 = forms.ChoiceField(choices=CHOICES, label='Search In')

    def __init__(self, *args, **kwargs):
        super(MySearchForm, self).__init__(*args, **kwargs)
        #I usually put here the dynamic choices for my ChoiceFields

    def search(self):
        """Customize your search behavior here."""
        #call the search method by the superclass to narrow the search
        #but can be modified to set all rows for searching
        sqs = super(MySearchForm, self).search()

        #if you have multiple indexed models, 
        #you can specify which model to search on
        sqs = sqs.models([YourModel])

        #the most basic way to search is to use filter
        sqs = sqs.filter(lastname='Sample') #you can filter multiple fields
        sqs = sqs.filter(firstname='Sample') #filter uses AND 
        #so these two filters match the record with Sample as first and lastname
        
        #you can have multiple SearchQuerySets
        sqs2 = sqs._clone()
        
        #if you need to filter thru several fields using OR
        sqs2 = sqs2.filter_or(lastname='Sample2')
        sqs2 = sqs2.filter_or(firstname='Sample2')
        
        #combining multiple SQS
        sqs = sqs.__and__(sqs2)
        
        #OR
        sqs = sqs.__or__(sqs2)
        
        #if your search is too complex you can always use raw SOLR queries
        sqs = sqs.narrow(u"age:[18 TO 30] AND height:[170 TO 200]")
        
        #sort
        sqs = sqs.order_by('sort_field')
        return sqs

WKHTMLTOPDF
The second tool is django-wkhtmltopdf. This app is a wrapper for the wkhtmltopdf tool which renders a HTML file to a PDF file using webkit. Basically, what the wrapper does is that it renders a template, like django's render_to_response function, write it to a temporary HTML file, call the wkhtmltopdf tool to convert the file to PDF and then return the PDF as the response.

Their site includes a straightforward setup guide so I won't dig into that. However, the wrapper's docs don't discuss much about customizing the view so I'll be discussing that.






Here's a sample Django view:

from wkhtmltopdf.views import PDFTemplateResponse


def toPDF(request, template='to/template.html'):
    template = 'custom/template.html'
    data = getData()
    context = {
        'data' : data
    }
    cmd_options = settings.WKHTMLTOPDF_CMD_OPTIONS

    #return render_to_response(template, context)
    return PDFTemplateResponse(request=request, context=context, template=template, filename='filename', header_template='pdf/header.html', footer_template='pdf/footer.html', cmd_options=cmd_options)


You create the templates as you would a template for a webpage; but here, you have an option to specify the separate template files for the header and footer. For more on how to customize the output see here.

That's it! Hope these tools and my examples help you in your own coding.