Monthly Archives: June 2016

SQLAlchemy hybrid_property

I learned about hybrid_property in order to do some calculations directly on the database. In my brainstorming project, you can create a session where you add ideas. You can then add other users and rank ideas. I wanted to be able to automatically calculate the average scores. Below is an implementation of this.

from app import db
from sqlalchemy.ext.hybrid import hybrid_property

class Idea(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    idea_session_id = db.Column(db.Integer, db.ForeignKey('idea_session.id'), nullable=False)
    name = db.Column(db.String, nullable=False)
    creator_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    scores = db.relationship("Score", backref='idea', cascade='delete', lazy='dynamic')

    @hybrid_property
    def avg_score(self):
        scores_for_idea = [score.score for score in self.scores]
        if len(scores_for_idea) == 0:
            return 0
        return sum(scores_for_idea)/float(len(scores_for_idea))

    def json_view(self):
        score_format = '%.1f' % self.avg_score
        return {"id": self.id, "session": self.idea_session_id, "name": self.name, "score": score_format}

class Score(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    score = db.Column(db.Integer, nullable=False)
    idea_id = db.Column(db.Integer, db.ForeignKey('idea.id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

SQLAlchemy cascade

On my brain storming project, I learned more about working with databases and database design. Foreign keys with cascade delete refer to when a parent row has dependent children. Dependent children have foreign keys that refer back to the parent’s primary key. When a parent row with dependent children is deleted, the children row are deleted as well. You can set the foreign key to NULL on delete as well.

In SQLAlchemy, this is implemented by using relationships. Below is a portion of my models.py file. The User table is parent to IdeaSessions. Each IdeaSession has a creator_id which references a user id. On the User table, a relationship is defined and the cascade attribute is set to ‘delete’.

from app import db

class User(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    auth_server_id = db.Column(db.String, default=None)
    created = db.Column(
        db.DateTime, default=datetime.utcnow, nullable=False
    )
    name = db.Column(db.String, nullable=False)
    email = db.Column(db.String, nullable=False)
    profile_pic = db.Column(db.String, nullable=False)
    
    idea_session = db.relationship("IdeaSession", cascade='delete')
    ideas = db.relationship("Idea", cascade='delete')
    scores = db.relationship("Score", cascade='delete')
    permissions = db.relationship("Permission", cascade='delete')

class IdeaSession(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    name = db.Column(db.String, nullable=False)
    description = db.Column(db.String, default='No Description')
    created = db.Column(db.DateTime, default=datetime.utcnow)
    creator_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    idea = db.relationship("Idea", cascade='delete')
    permissions = db.relationship("Permission", cascade='delete')

    def json_view(self):
        return {"id": self.id, "name": self.name, "created": self.created, "creator": self.creator_id}

virtualenvwrapper

I learned about a pretty neat tool for managing virtual environments from my RC Start Mentor. RC Start is a program that is being piloted by the Recurse Center.

Virtualenvwrapper lets you store and run your virtual environments out of one location.You can also easily switch between them. Previously, I had stored my virtual environment directories in each project folder.

 

Testing and Test-Driven-Development

I’m on exercise 47 of Learn Python the Hard Way which covers testing. While reading up on different testing modules, I came across some articles on Test-Driven Development. I had heard of the term before, but didn’t know much about it.

Apparently some benefits of TDD are 1) Greater confidence code is working, 2) Checks that a change didn’t break something else, 3) Forces you to think about unusual circumstances, and 4) Results in more Modular code. I’m sure there are others as well. It seems to be a topic that many people find very important.

I came across some articles that walk through an application of the TDD methodology for an example problem.

Test Driven Development In Python
More Test Driven Development in Python

 

Learn Python The Hard Way

So I applied to the RC Start program through the Recurse Center and was paired up with a mentor. My main goal was having someone who could review my code and ask advice on general topics that are important to learn.

I didn’t have any plans to go back and specifically do more python related studying, but he recommended that I go through Zed Shaw’s Learn Python the Hard Way because it covers some of the topics I was interested in learning about such as testing and project organization.

I also feel like it’s not a bad idea to go back and solidify the foundations in what I am learning. I just finished wrapping up the first iteration of my latest project so this might not be a bad time to go through and do some reviewing.

Backbone async

I started learning how to use Backbone.js, a front-end library for managing the structure of your web application. While it seems Backbone is on the decline, I still decided to go with it and do at least one project with it because I heard it was an easier place to get started.

Backbone lets you separates your data from the DOM and helps connect your API over a RESTful JSON interface. My motivation for learning Backbone was to create a single-page web application. My previous project loaded every page every time there was an action. It seems a lot of modern web sites are single-page web apps. The JSON interface sends JSON to the server and receives JSON and only updates that section that is relevant. This allows for more fluidity and I feel like an overall better user experience.

In certain parts, I kept getting errors when using fetch or create. After creating or fetching, I would try to render it, but I would get an error saying I was trying to render undefined. It turns out, that I was trying to render these objects before the previous function was completed. This issue could be solved by passing the secondary action I was trying to complete as a callback in the success attribute.

#second attempt
app.scoreList.create(this.ratedIdea(idea, score), {success: function(){
  app.ratedIdeaList.fetch({wait:true, reset:true});
}})

Many-to-One Relationship Sqlalchemy

I’m working on a new project called brainStorm. It is essentially a fancy todo list. You can create different sessions, add users and vote on items. In the process, I learned about mapping relationships between items. In the below code, “Unranked” refers to each idea and “Score” refers to each score. There are potentially multiple scores for each item. The relationship indicator is included in the child table. We include the unranked_id and mark it as a foreign key and then specify the unranked as a relationship. This will allow you to pull the Score data through the Unranked table.

#model.py
class Unranked(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    session = db.Column(db.Integer, nullable=False)
    name = db.Column(db.String, nullable=False)
    avg_score = db.Column(db.Numeric(3,1), default=None)

    def json_view(self):
        return {"id": self.id, "session": self.session, "name": self.name, "score": str(self.avg_score)}

class Score(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    unranked_id = db.Column(db.Integer, db.ForeignKey('unranked.id'))
    unranked = db.relationship('Unranked',backref=db.backref('scores',lazy='dynamic'))
    user_id = db.Column(db.Integer, nullable=False)
    score = db.Column(db.Integer, nullable=False)

#views.py
def update_average(idea_id):
	idea = Unranked.query.filter_by(id=idea_id).first()
	scores_q = idea.scores.all()
	scores = [score.score for score in scores_q]
	idea.avg_score = sum(scores)/float(len(scores))
	db.session.commit()

binary heap

A binary heap is an array that implicitly represents a complete binary tree by virtue of its positions. A Max heap keeps the highest value at the lowest position, while a min heap keeps the lowest value at the lowest position.

class BinHeap:
    def __init__(self):
        self.heapList = [0]
        self.size = 0

    def percUp(self, i):
        # starting form last index, divide 2 to get to the beginning
        while i // 2 > 0:
            if self.heapList[i] < self.heapList[i // 2]: 
                tmp = self.heapList[i // 2]
                self.heapList[i // 2] = self.heapList[i]
                self.heapList[i] = tmp
            i = i // 2

    def insert(self, k):
        self.heapList.append(k)
        self.size = self.size + 1
        self.percUp(self.size)
        

    def minChild(self, i):
        # if i*2 + 1 (position of second child) is greater than size
        # return first child bc means there is no second child
        if (i*2 + 1) > self.size:
            return i * 2
        else:
            if self.heapList[i*2] < self.heapList[i*2 + 1]:
                return i*2
            else:
                return i*2 + 1

    def percDown(self, i):
        # i*2 is first child of i. i * 2 must be greater than size
        # for there to be no first child
        # only percDown if at least one child
        while i * 2 <= self.size:
            mc = self.minChild(i)
            if self.heapList[i] > self.heapList[mc]:
                tmp = self.heapList[i]
                self.heapList[i] = self.heapList[mc]
                self.heapList[mc] = tmp
            i = mc

    def delMin(self):
        retval = self.heapList[1]
        self.heapList[1] = self.heapList[self.size]
        self.heapList.pop()
        self.size = self.size - 1
        self.percDown(1)
        return retval

    def buildHeap(self, alist):
        self.size = len(alist)
        self.heapList = [0] + alist[:]
        i = len(alist) // 2

        while i > 0:
            self.percDown(i)
            i = i - 1

Linked List Implementation

I started spending some time learning about data structures and algorithms. It seems like an important subject for learning to solve problems. Below is my implementation of the linked list in python.

Linked lists are data structures with two parts: the head and nodes. In this implementation, nodes contain two things: data and a pointer to the next item in the list. The head only contains an item to the first node.

#python 2.7
#linked-list.py

class Node(object):
    def __init__(self, d, n = None):
        self.data = d
        self.next_node = n

    def get_next (self):
        return self.next_node

    def set_next(self, n):
        self.next_node = n

    def get_data(self):
        return self.data

    def set_data(self, d):
        self.data = d

class LinkedList(object):
    def __init__(self, h = None):
        self.head = h
        self.size = 0

    def add(self, d):
        new_node = Node(d, self.head)
        self.root = new_node
        self.size += 1
        
    def remove(self, d):
        this_node = self.head
        prev_node = None
        while this_node:
            if this_node.get_data() == d:
                if prev_node:
                    prev_node.set_next(this_node.get_next())
                else:
                    self.head = this_node
                self.size -= 1
                return True
            else:
                prev_node = this_node
                this_node = this_node.get_next()
        return False

    def find(self, d):
        this_node = self.head
        while this_node:
            if this_node.get_data() == d:
                return d
            else:
                this_node = this_node.get_next()
        return None