Setting up our Django Project

This entry is part 2 of 2 in the series Django Web App

In order to start developing our Django app, I’m going to help you begin by using Python best practices which includes setting up a virtual environment for this version of Python and this project’s requirements.  With virtualenvwrapper installed, run mkvirtualenv drecipes.  This will create a separate, isolated Python environment so you can continue using a different Python version on other projects as well as different versions of libraries.  For example, when I develop with older versions of Django and Python on some projects, virtualenv allows me to keep the two projects separate while still being compatible with each production environment.

Each time you want to develop for the drecipes project, you’ll run workon drecipes in order to activate this environment.

Create a requirements.txt file in your project directory.  Add these two lines to it:

Django==1.7.6
mysqlclient==1.3.6

Next, run pip install -r requirements.txt.  This will take the 2 requirements from our file and install them so they are ready to use.

With Django installed, run django-admin.py startproject drecipes.  This will create the initial Django project structure that looks similar to this:

your_project_folder/
    manage.py
    drecipes/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    requirements.txt

In order to connect to our database, modify the settings.py file as follows:

DATABASES = {
     'default': {
-        'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': 'drecipes_codecrawl',
+        'USER': 'root',
+        'PASSWORD': 'Ma12sona',
+        'HOST': '127.0.0.1',
     }
 }

NAME should be your database name, USER is the database user you create.  It is never a good idea to run a database as root, but since I’m only doing this locally, I am not concerned with a security issue.  The same goes for the PASSWORD not being encrypted or at least not stored directly in version control.  Normally, I store all of these in environment variables that can differ based on host, like test, stage, and production may all have different settings.

Then run python manage.py migrate as follows:

$ python manage.py migrate
Operations to perform:
  Apply all migrations: auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying sessions.0001_initial... OK

We’re not going to use the built in Django admin, so you can remove the admin lines from drecipes/urls.py, but you don’t have to.  I always do when my app is in production, and I’m not using it.

You should now be able to run python manage.py runserver to see site on localhost:8000 (see screenshot).

Initial Django app running

Python Objects (or a Bike and a Wheel)

This entry is part 7 of 8 in the series Python

When I first tried to teach myself programming, I bought a Java book that started teaching object-oriented programming (OOP) by describing an object (a bicycle), which had properties (wheels, pedals, etc), and state (moving or stopped).  I said whaah?!  Why am I learning about a bike and whether it’s moving or not.

Needless to say, I was completely befuddled and had no idea what I was doing or how to relate this bike concept.  Funny enough, a handful of years later a co-worker of mine described programming in almost exactly the same way.  It made as much of no sense as it did the first time.

The point in this initial ramble of mine is to promise you I won’t try to explain programming and OOP by using your first grade tricycle.

I like to think of OOP as a useful way to combine similar sets of code/logic so you can use it over and over without rewriting it.  From How To Become A Hacker (not the breaking into things type, but hacker as in building killer software), Eric S. Raymond writes:

Hackers (and creative people in general) should never be bored or have to drudge at stupid repetitive work, because when this happens it means they aren’t doing what only they can do — solve new problems. This wastefulness hurts everybody. Therefore boredom and drudgery are not just unpleasant but actually evil.

 

 

To behave like a hacker, you have to believe this enough to want to automate away the boring bits as much as possible, not just for yourself but for everybody else (especially other hackers).

OOP is useful so you don’t have to write the same thing, over and over again.  The example I like to use is writing a banking application.  First I’ll briefly explain a core part of DRY (Don’t Repeat Yourself) as functions.  If you have a for loop where you perform the same logic over a list, you can separate that logic into a function so you only write it once, but you can call it as many times as you need.

"""We're going to print abreviated titles
from a list of titles
"""
def short_title(title):
    new_title = ''
    if len(title) > 20: 
        new_title = title[:21]+'...'
    else:
        new_title = title

    return new_title

titles = [ 
    'Here is Title 1',
    'Title 2', 
    "A longer title that won't fit.",
    'Something a bit longer than we want'
]

for title in titles:
    print short_title(title)

To declare a function, we use the keyword def to declare (or define) a function.  title in def short_title(title): is a parameter that is passed into this function, which we use later to create a short title.  The gist of short_title is to return an abbreviated title if it’s longer than 20 characters.  Don’t worry too much about the details, just try to understand that the short_title function allows us to repeat creating an abbreviated title and use it anywhere else we need it.

The output, in case you were curious:

$ python function.py 
Here is Title 1
Title 2
A longer title that w...
Something a bit longe...

Next lesson we’ll go over the following code about the rich, poor, and greedy:

# bank.py
class Person(object):
    """This is the base class that represents
    a Person
    """
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def get_full_name(self):
        return self.first_name +' '+ self.last_name

class Employee(Person):
    """Since an employee is a Person, we indicate
    that we are a Person by declaring
    class Employee(Person):
    The item inside of () shows we inherit from
    Person
    """
    def __init__(self, fname, lname, age, salary, manager):
        Person.__init__(self, first_name=fname, last_name=lname, age=age)
        self.salary = salary
        self.manager = manager

    def get_manager_salary(self):
        return self.manager.salary

    def is_owner(self):
        return True if self.manager is not None else False

class Customer(Person):
    """A Customer is also a Person
    which means we also have a first and last name
    as well as an age
    """
    def __init__(self, first_name, last_name, age, bank_account):
        Person.__init__(self, first_name, last_name, age=age)
        self.bank_account = bank_account

    def get_account_balance(self):
        return self.bank_account.balance

    def deposit(self, amount):
        # We return the new account balance
        return self.bank_account.increase_cash(amount)

    def spend(self, amount):
        return self.bank_account.decrease_cash(amount)

class BankAccount(object):
    """A class that represents a bank
    account
    """
    def __init__(self, balance, manager):
        self.balance = balance
        self.manager = manager

    def decrease_cash(self, spent_money):
        self.balance -= spent_money
        return self.balance

    def increase_cash(self, money):
        self.balance += money
        return self.balance

bank_manager = Employee('Scrooge', 'McMuffins', salary=1000000, age=99, manager=None)
rich_bank_account = BankAccount(1000, bank_manager)
rich_customer = Customer('Rich', 'Person', age=205, bank_account=rich_bank_account)

print 'The bank manager for your bank is %s'%(bank_manager.get_full_name())
print 'Your account has $%d in it'%(rich_bank_account.balance)

interest_payment = 2500
print '%s\'s account earns $%d of interest'%(rich_customer.get_full_name(), interest_payment)
new_balance = rich_bank_account.increase_cash(interest_payment)
print '%s\'s new balance is $%d'%(rich_customer.get_full_name(), new_balance)
print '%s\'s age is %d years old'%(rich_customer.get_full_name(), rich_customer.age)

print '%s spends a little money'%(rich_customer.get_full_name())
rich_customer.spend(100)
print '%s now has $%d'%(rich_customer.get_full_name(), rich_customer.get_account_balance())

# He has the same mean bank manager as the rich person!
poor_account = BankAccount(10, manager=bank_manager)
poor_customer = Customer('Poor', 'Person', 105, poor_account)

print '%s starts with $%d'%(poor_customer.get_full_name(), poor_account.balance)
print '%s steals money from %s'%(bank_manager.get_full_name(), poor_customer.get_full_name())
poor_account.decrease_cash(5)
print '%s now only has $%d'%(poor_customer.get_full_name(), poor_customer.get_account_balance())

The output for this code is below:

$ python bank.py 
The bank manager for your bank is Scrooge McMuffins
Your account has $1000 in it
Rich Person's account earns $2500 of interest
Rich Person's new balance is $3500
Rich Person's age is 205 years old
Rich Person spends a little money
Rich Person now has $3400
Poor Person starts with $10
Scrooge McMuffins steals money from Poor Person
Poor Person now only has $5

Can you piece it together before we talk about it?  Comment below with any thoughts….

@codecrawl
@zachhilbert

Becoming a Python Grown-Up

This entry is part 6 of 8 in the series Python

These Python lessons have been moving fairly quickly, and that’s primarily because of all the other great lessons on the rest of site.  Once you learn to develop code in a language, it’s relatively simple to move on to learn a new language.  I’m assuming that new language for you, is Python.

Since we have touched on variables, basic data structures, and for loops, I want to finish up some of the core basics by going over while loops and conditional statements.

The code we’re going to work with is below:

wallet_money = 150 
# We're going to invest in penny stocks
# that cost a lot more than a penny
while wallet_money > 0:
    invest_amount = 0 
    # Checking if we should give up the rest
    if wallet_money <= 15: 
        # Invest all our money in pennies
        invest_amount = wallet_money
        wallet_money = 0
    else:
        # Invest 25% in pennies
        invest_amount = .25 * wallet_money
        wallet_money -= invest_amount
    print "Investing $%d" % (invest_amount)
    print "$%d left after losing on pennies" % (wallet_money)

print 'We squandered our savings on penny stocks!'

In order to follow this code, we have to acknowledge the elephant in the code block….we don’t have brackets!  Instead of using brackets to distinguish logic blocks, Python uses indentation, so formatting becomes the lifeblood of a successfully running python program.

Indentation needs to be consistent, ie. keep using tabs if you start with tabs, or keep using 2 spaces if you start with 2 spaces.

wallet_money = 150 
# We're going to invest in penny stocks
# that cost a lot more than a penny
while wallet_money > 0:
    invest_amount = 0
    ...stuff...

Here we start with $150 and a while statement.  While statements say “while <test is true>: do stuff.”  In our case, we say “while our wallet money hasn’t run out, invest, over, and over, and over….”  The ‘:’ colon after the test indicates that logic within this statement is to follow.

invest_amount = 0 
# Checking if we should give up the rest
if wallet_money <= 15: 
    # Invest all our money in pennies
    invest_amount = wallet_money
    wallet_money = 0
else:
    # Invest 25% in pennies
    invest_amount = .25 * wallet_money
    wallet_money -= invest_amount
print "Investing $%d" % (invest_amount)
print "$%d left after losing on pennies" % (wallet_money)

While we have money in our wallet, we first check to see how much we have left.

# Checking if we should give up the rest
if wallet_money <= 15: 
    # Invest all our money in pennies
    invest_amount = wallet_money
    wallet_money = 0

Because our money amount changes each time we invest, this if is called a conditional statement, meaning the logic is subject to change depending on the condition of our check.  If we have $15 or less, then we invest the rest of our money.

else:
    # Invest 25% in pennies
    invest_amount = .25 * wallet_money
    wallet_money -= invest_amount

Here, else is exactly what it sounds like, if we have $15 or less, then invest everything, else invest 25% of the remaining money.  This is called an if/else construct.  We can also have if/elif/elif/else, etc. where elif has another check each time for something different.

One thing to note here is the wallet_money -= invest_amount line.  This is the same as saying wallet_money = wallet_money – invest_amount, but in a more concise way.

Finally we print the investment amount and remaining amounts each time the loop runs, and we end up broke again by trusting in the stock market of pennies.  These print statements should look familiar.

I saved my file as penny_stocks.py which can be run using the command python penny_stocks.py.  You can see the output of this script below:

$ python penny_stocks.py 
Investing $37
$112 left after losing on pennies
Investing $28
$84 left after losing on pennies
Investing $21
$63 left after losing on pennies
Investing $15
$47 left after losing on pennies
Investing $11
$35 left after losing on pennies
Investing $8
$26 left after losing on pennies
Investing $6
$20 left after losing on pennies
Investing $5
$15 left after losing on pennies
Investing $3
$11 left after losing on pennies
Investing $11
$0 left after losing on pennies
We squandered our savings on penny stocks!

After this, you should be pretty close to becoming a Python professional, ready to write all sorts of applications!

Python Variables, Loops, and More…Oh My

This entry is part 5 of 8 in the series Python

We’ll start with the example at the end of Python Variables: Part 2.

>>> 
>>> book_titles = ['Book Title', 'Smashed Soup', 'Learning Programming']
>>> 
>>> # Let's create a list of books we have
... for title in book_titles:
...     print title
... 
Book Title
Smashed Soup
Learning Programming
>>> 
>>> book_pricing = {'Book Title': 29.99,
...                 'Smashed Soup': 4.99,
...                 'Learning Programming': 999.99}
>>> 
>>> for title in book_pricing.keys():
...     price = book_pricing[title]
...     print title + ' - $' + str(price)
... 
Smashed Soup - $4.99
Learning Programming - $999.99
Book Title - $29.99
>>>

In this example, there are quite a few new functions and manipulations that we haven’t seen yet.  That is to be expected since variables would be quite boring and useless if there were no provided way to change them as necessary.

We start with an array, book_titles, and then loop through each title by using a for loop.  In the loop, we print the title of each book.

>>> 
>>> book_titles = ['Book Title', 'Smashed Soup', 'Learning Programming']
>>> 
>>> # Let's create a list of books we have
... for title in book_titles:
...     print title
... 
Book Title
Smashed Soup
Learning Programming
>>>

The way a for loop works in Python is again similar to other languages.  We write:

for <single_item_in_list> in <our_list>:
    <logic for each item here>

You can read this as “for each <item> in <list>, do stuff,” where <item> is your variable name for the single item in the <list>.  This is used when you have a list of items you want to perform the same logic on.

After this, we loop through the dictionary of books and their prices.  Sometimes, you have an array of items like book titles and use those titles to access their prices in a dictionary, like book_pricing.  Other times, you just want to loop through all the items in a dictionary.  Those are called key – value pairs.

>>> 
>>> book_pricing = {'Book Title': 29.99,
...                 'Smashed Soup': 4.99,
...                 'Learning Programming': 999.99}
>>> 
>>> for title in book_pricing.keys():
...     price = book_pricing[title]
...     print title + ' - $' + str(price)
... 
Smashed Soup - $4.99
Learning Programming - $999.99
Book Title - $29.99
>>>

Here we use keys() which is a method of all dictionary objects.  Method is just another name for function but used on objects which we’ll go over more when we discuss object-oriented development.  What keys() does is return all the, you guessed it, keys of the dictionary as a list.

In our case, we loop through this list of titles and use title as a key for book_pricing to get the book title’s price.  We assign this value to the price variable, then we print title and price.  You may notice, though, that we add ‘ – $’ to format the output.  In order to get this all together, we concatenate the strings by using the ‘+’ plus sign, which is like ‘adding’ our text together.  We also use the str() function to convert our price to a string, since Python will throw a fit if we try to concatenate a string and a different type:

>>> 
>>> price = 9.99
>>> title = 'Book Title'
>>> 
>>> print title + ' - $' + price
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'float' objects
>>>

As you’ll find out as you use more Python, there are many other ways to build and manipulate variables and data in general.  This is just the tip of the iceberg, and we’ll see more of that as we move forward.

Python Variables: Part 2

This entry is part 4 of 8 in the series Python

So we’re going to go a bit deeper into Python variables and variable types so we can move on toward some more complex and useful logic than preventing clumsiness.

Variables themselves are pretty dynamic, but there are a few caveats we have to keep in mind when programming.  The first item to remember is how variable names must be composed.

Variable names must not start with a number, as that would confuse Python when reading your dynamic value:

>>> 
>>> 1dollar = 1
  File "<stdin>", line 1
    1dollar = 1
          ^
SyntaxError: invalid syntax
>>>

After starting with a letter, variable names must be alphanumeric:

>>> 
>>> te$t_var = 'test'
  File "<stdin>", line 1
    te$t_var = 'test'
      ^
SyntaxError: invalid syntax
>>> 
>>> 
>>> file_backups~ = 4
  File "<stdin>", line 1
    file_backups~ = 4
                ^
SyntaxError: invalid syntax
>>>

Notice how the ‘$’ dollar sign and ‘~’ tilde cause Python some heartburn.

Variable names must also not conflict with Python keywords, which can be found here.  Python reserves these for its special cases and logic, so variable names cannot be the same.

and       del       from      not       while    
as        elif      global    or        with     
assert    else      if        pass      yield    
break     except    import    print              
class     exec      in        raise              
continue  finally   is        return             
def       for       lambda    try

But, if I choose a good variable name and find out it is a keyword, what I do, and what is often done is to prepend or append an ‘_’ underscore and an optional prefix/suffix.

>>> 
>>> school = 'Harvard'
>>> class = 'CS203'
  File "<stdin>", line 1
    class = 'CS203'
          ^
SyntaxError: invalid syntax
>>> class_ = 'CS203'
>>> class_
'CS203'
>>> 
>>> pass = 'P@$$w0rd'
  File "<stdin>", line 1
    pass = 'P@$$w0rd'
         ^
SyntaxError: invalid syntax
>>> user_pass = 'P@$$w0rd'
>>>

Although, you should never store a password in clear text (unencrypted), this is a sufficient example.

A few types of useful variable types are as follows:

>>> 
>>> # We mentioned strings
... string_var = 'FirstName LastName'
>>> 
>>> # I also mentioned integers (simple numbers)
... integer_amount = 1309
>>> 
>>> # We can also use floats
... # Which is just a fancy name for a decimal
... float_amount = 9.99
>>> 
>>> # Tuple here
... book_tuple = ('Book Title', 29.99, 2010)
>>> 
>>> # List is like arrays in other langs
... lotto_nums = [23, 45, 67, 99]
>>> 
>>> # A dictionary is like book index
... # with titles and prices
... book_prices = {'Book Title': 29.99, '2010 Funnies': 9.99}
>>> 
>>> # Which can be retrieved like so...
... book_prices['2010 Funnies']
9.99
>>>

There are also types called classes which are a bit more complicated, and we will cover those a little later.  For the most part, these variables mimic items we deal with day-to-day.  A list is just that, a list of items, like a shopping cart.  Tuples are similar to lists, except that tuples represent more of a single object and its properties.

>>> 
>>> # Tuple here
... book_tuple = ('Book Title', 29.99, 2010)
>>>

For our tuple, example, the book_tuple represents a book title, price, and publication date.  So another book would follow the same pattern, whereas we don’t necessarily expect a list to contain properties in the same location within the list.  The differences are subtle, but over time, you learn to understand and use the differences appropriately.

Lastly, we display a dictionary which acts as an index of key-value pairs.

>>> # A dictionary is like book index
... # with titles and prices
... book_prices = {'Book Title': 29.99, '2010 Funnies': 9.99}
>>>

Here we declare a dictionary, book_prices, with 2 books and their respective prices.  Then we access a book to get its price:

>>> 
>>> # Which can be retrieved like so...
... book_prices['2010 Funnies']
9.99
>>>

All of these variable types will help us perform logic based on input and requirements of our application.

I’ll give you a hint of things to come.  Now we have a book store and we want a list of book titles as well as a list of those titles and their respective price.

>>> 
>>> book_titles = ['Book Title', 'Smashed Soup', 'Learning Programming']
>>> 
>>> # Let's create a list of books we have
... for title in book_titles:
...     print title
... 
Book Title
Smashed Soup
Learning Programming
>>> 
>>> book_pricing = {'Book Title': 29.99,
...                 'Smashed Soup': 4.99,
...                 'Learning Programming': 999.99}
>>> 
>>> for title in book_pricing.keys():
...     price = book_pricing[title]
...     print title + ' - $' + str(price)
... 
Smashed Soup - $4.99
Learning Programming - $999.99
Book Title - $29.99
>>>

I’ll try to remember to use this example in our next lesson to go over exactly what is going on here, but for now that’s all.  Any questions, comment below.