Wednesday, August 10, 2011

A Hippocampus Anatomy Game


Problem: Write a game, any kind of game. Just start doing it, do a small version, make it bigger, keep a list of things to do, and do them.

I made this Choose Your Own Adventure-like game as practice after learning about branches and functions, if-else statements and while loops. I wanted to make an educational game that incorporated a deep interest of mine, neuroscience. So the subject of this game is a way to learn and explore one of the most studied regions in the brain, the hippocampus. The hippocampus is primarily known to be involved in memory and is located in the medial temporal lobe. Keep in mind: this region is very complex and this is only a crude (but hopefully fun) way to explore it.

This turned out to be fairly straightforward endeavor, thanks to Zed Shaw's Learn Python the Hard Way. I really enjoyed reviewing the anatomy of the hippocampus and finding better ways to navigate through the game. As of yet, I haven't used classes, lists nor dictionaries in this version of the game, but plan on doing so in the next. If you have any suggestions within these parameters, please feel free to share them.

In this game, you are in control and can decide where you want to travel and how much you want to learn about the hippocampus anatomy.

Here's what the code looks like:
from sys import exit

def entorhinal_cortex():
    print "You are currently in between layer 2 and 3 of the entorhinal cortex. You have the option of traveling in either layer. Which layer do you want to walk along?"

    next = raw_input ("> ")
    if "2" in next or "3" in next:
        how_much = int(next)
    else:
        dead("Sorry, no can do. Guess you're stuck in the entorhinal cortex!")
        
    if how_much == 2:
        print "Welcome! Now you have the option of exploring the dentate gyrus or the hippocampal region CA3. Enter your choice."

        while True:
            next = raw_input("> ")
            if next.lower() == "dentate gyrus":
                dentate_gyrus()
            elif next.lower() == "hippocampal region ca3":
                hippocampal_region_CA3()
            else:
                print "That doesn't make much sense. Try typing that in again."
            
    elif how_much == 3:
        print "Sweet pick. Since the entorhinal cortex has 2 major projections, you have the option of exploring the hippocampal region CA1 or the subiculum. Enter your choice."

        while True:
            next = raw_input("> ")
            if next.lower() == "hippocampal region CA1":
                hippocampal_region_CA1()
            elif next.lower() == "subiculum":
                subiculum()
            else:
                dead("You just missed out on such a good adventure. Bummer.")

def dentate_gyrus():
    print "Ah, the dentate gyrus. Good pick. The dentate gyrus is one of the few regions in the adult brain where neurogenesis is thought to take place. It also plays a role in depression."
    print "There are three major types of neurons found here."
    print "Would you like to learn about them?"

    while True:
        next = raw_input ("> ")
        if next.lower() == "yes":
            print "The dentate gyrus primarily consists of granule cells, interneurons and pyramidal cells." 
            print "The dentate gyrus' main projection is to the CA3. So off to there you go!"
            hippocampal_region_CA3()
        else: 
            dead("Aww, too bad. Guess you don't really want to explore the hippocampus.")

def hippocampal_region_CA3():
    print "Now you're in the hippocampal region CA3 or simply, CA3."
    print "There are a few proposed behavioral functions of the CA3."
    print "Would you like to learn about one?"

    next = raw_input ("> ")
    if next.lower() == "yes":
        print "The CA3 plays a role in the encoding of new spatial information within short-term memory with a duration of seconds and minutes."
        print "The CA3's main projection is to the CA1. So that's where you're headed to next."
        hippocampal_region_CA1()
    else: 
        dead("Ok, you missed out. But no problem.")
        
def subiculum():
    print "Hey, now you're in the most inferior region of the hippcampus called the subiculum. It lies between the entorhinal cortex and the CA1."
    print "Do you want to stay or leave?"

    next = raw_input("> ")
    if next.lower() == "stay":
        dead("Alright guess I'll leave you here.") 
    elif next.lower() == "leave":
        entorhinal_cortex_2()
    else:
        print "Huh? Try again."

def hippocampal_region_CA1():
    print
    print "--------------------"
    print "Welcome to the hippocampal region CA1 or simply, CA1."
    print "This region sends a large amount of output to the subiculum and some inputs back to the entorhinal cortex."
    print "Which way would you like to travel?"

    while True:
        next = raw_input("> ")
        if next.lower() == "subiculum":
            subiculum()
        elif next.lower() == "entorhinal cortex":
            entorhinal_cortex_2()
        else:
            print "Try typing that again."
    
def entorhinal_cortex_2():
    print "You have now, more or less, made a full loop within the connections of the hippocampus. Congratulations!"
    print "If you want to explore a bit more, please replay the game! Is this what you want to do?"
    next = raw_input("> ")
    if next.lower() == "yes":
        entorhinal_cortex()
    else: 
        dead("Thanks for playing.")
    
def dead(why):
    print why, "Have a good one."
    exit(0)

def start():
    print "Hello. You're about to explore the hippocampus."
    print "There will be many paths and therfore, many decisions you can make."
    print "Enter 'Ready!' when prompted and you can begin your journey."

    next = raw_input("> ")  

    if next.lower() == "ready!":
        entorhinal_cortex()
    else:
        dead("Maybe another time!")

start()
Here's what the output of one possible route looks like:
In my desire to add more flexibility to the program, I only experimented with how to allow the user to be able to respond to prompts in any case. This actually took me a little experimenting (and time) to figure how to do in a concise way.

Goals for improving the code and behavior of this game:
1) Make it more concise and clearer to read. Remove any repetition.
2) Incorporate classes, lists and dictionaries.
3.) Figure out how to travel backwards through the game. Give the user a chance to change their mind and reverse direction.
4.) This game made me realize that I don't know the full extent of possible operations that I have at my disposal. I want to experiment with more of them in the next version of the game.

Questions:
1.) Is there anything in my code that is considered bad practice?
2.) What are some ways that I can condense the code?
3.) Can I improve the naming of functions?
If you'd like a copy of the program to play with (and expand!), you can go here

Friday, June 10, 2011

Lessons From A Beginner Programmer


I've recently started an exciting journey into programming and thought it might be useful to share a few things that I've learned so far.

1.) Don't Be Intimidated. When I first gave serious consideration to learning how to program, a friend gave me some useful advice that stuck with me: "Whatever you do, however you decide to approach this, don't be intimated." My first thought was full of that naive yet self-confident, "Well, yeah of course." The more time I spent on it, both independently and with others, I understood why she said that. It's easy to be intimidated by the hacker culture, the concepts, the skill level of other programmers and so on. Although I admit to sometimes being discouraged by this, her advice has become a mantra in my mind. Don't be discouraged by programmers (if you're exposed to any), don't be discouraged by the concepts, and more importantly, don't be discouraged by the journey. You'll know if you truly want to learn if you can push through these obstacles.

2.) Pick A Project. I had been wanting to pick up programming since college, but not enough to put any significant energy toward it. I brushed over introductory chapters of CS books and perused through lectures on various college websites but that's about as far as I made it. This desire changed when I began thinking of a web project that I wanted to use for myself. At some point I decided, "Hey, I want to see this out there. Instead of waiting for it to occur, why not start learning and work toward it on my own?" Around the time I started learning programming, I also started learning how to read and write Devanagari (Hindi). So I got some Hindi textbooks from the library and just went at it. But the work quickly began to feel meaningless because I wasn't motivated by a project, like for example, a book in Hindi to read or a letter to write to a relative in India. So pick a project that matters to you. Think of what you want to accomplish and how enabled you will feel by doing it. The passion for your project will help you through the "hard stuff." It’s immensely critical that you really care about the idea and have a project to work toward. If this doesn't exist, learning may feel a little pointless at times. Figure out your intentions and dedicate yourself to it.

3.) Be Patient. Take your time working through the exercises and problem sets. The hard work you do on them really pays off in the long run. Learning the basics may feel like low-level skills, but it's worth it to master these from the get go before moving on. Along with this, keep in mind that you will always have more to learn. There's no end to your proficiency and creations, so regardless of what, take as long as it takes. Especially in the beginning, be patient with the material and yourself as you learn.

4.) Examine Yourself. Since it had been some time since I picked up anything new with such ferocity, I realized that being a beginner, at anything, really gives you key insights into yourself. How you learn, what your motivations are, what discourages you, etc. It can be hard to pick up challenging activities, because, well, they are challenging. It’s a learning process and that can be difficult if you’ve generally been doing the things you know well often. So while you're learning, think seriously about your learning techniques and strengths/weaknesses.

5.) Experiment With It. This one takes a little practice but it's been the most important one for me. When you're learning the basics, really play with each part of the code. Whenever I would ask a friend a coding question, often times the response would include the answer and encouragement to experiment with it. For instance, if an exercise asks you to solve one problem, see how many other ways you can solve it. See how other people tried to solve a similar problem. How is their coding style different than yours? Reading and playing with a lot of code will really help with your fluency in the language. All this experimentation will improve the quality of your learning and will ultimately make you a better coder.

Don't forget to seek out programming events/workshops in your area, set up coding dates with friends, and of course refer to online communities.