I'm taking a couple of the free online classes offered by Standford. One on Artifical Intelligence and one on Machine Learning.
I haven't had so much fun since kindergarten. Actually that's not fair, I didn't enjoy kindergarten this much. I'm listening to the classes during my lunch, after work, during weekends. I'm working on my assignment with so much enthusiasm, I dread the day when this class ends.
Stanford just announced a slew of new online classes offered starting in Jan 2012. I was way too excited when I first read the description on them. Now I'm a little sad, becasue I want to take 8 out of the 11 courses that are being offered and I don't have enough time. :(
Woe is me.
ps: If you are not taking any of these classes you are missing out big time. Please do yourself a favor and sign up.
Background:
You can safely skip this section if you're not interested in the back story behind why I decided to code this up.
I was listening to KhanAcademy videos on probability. I was particularly intrigued by the combinatorics video. The formula to calculate the number of combinations of nCr was simple, but I wanted to print all the possible combinations of nCr.
Problem Statement:
Given 'ABCD' what are the possible outcomes if you pick 3 letters from it to form a combination without repetition (i.e. 'ABC' is the same as 'BAC').
At first I tried to solve this using an iterative method and gave up pretty quickly. It was clearly designed to be a recursive problem. After 4 hours of breaking my head I finally got a working algorithm using recursion. I was pretty adamant about not looking it up online but I seeked some help from IRC (Thanks jtolds).
Code:
def combo(w, l):
lst = []
for i in range(len(w)):
if l == 1:
lst.append(w[i])
for c in combo(w[i+1:], l-1):
lst.append(w[i] + c)
return lst
Output:
>>> combinations.combo('abcde',3)
['abc', 'abd', 'abe', 'acd', 'ace', 'ade', 'bcd', 'bce', 'bde', 'cde']
Thoughts:
- It helps to think about recursion with the assumption that an answer for step n-1 already exists.
- If you are getting partial answers check the condition surrounding the return statement.
- Recursion is still not clear (or easy).
Labels: programming, python, recursion
I did a presentation at our local Python User Group meeting tonight. It was well received, but shorter than I had expected. I should've added a lot more code examples.
We talked about usage of cProfile, pstats, runsnakerun and timeit.
Here are the slides from the presentations:
The slides were done using latex-beamer, but I wrote the slides in reStructuredText and used rst2beamer to create slides.
The source code for the slides are available on my github page.
Labels: programming, python
Sal Khan was teaching how to find the probability of 2 heads when you toss a coin 5 times.
A classic nCk problem:
Bonus: It also teaches you corner cases like 0! = 1 and
Labels: programming
"TOO LONG AGO".
The initial friction to setup a substantial project using C++ is unfucking bearable.
When we started code revamp at work recently, I decided to be a good citizen and decided to incorporate cpptest, a unit testing framework.
It made me realize how unreasonably complicated Makefiles can become. After 3 hours of peeling away at the complexity I managed to add cpptest to the build dependency of the project.
Now time to write a few tests and check it out. I'm thinking "We are almost there".
FALSE!
Compilation gives me a gazillion error messages that make absolutely no sense. After about 30mins of StackOverflowing and Googling, I find out that string and map that I declared in the headers files need to be namespaced. Of course there is no indication (not even a hint) of that in the error messages. So I add 'using namespace std' and get past it.
Awesome my first test is compiling successfully. Time to run this baby and declare victory.
Close! But no cigar.
The executable was unable to load the CppTest library during runtime. Argh!
It's already 6pm and I'm hungry. That'll have to wait for another day.
TL;DR - C++ and Makefile can burn in a fire of thousand suns.
Labels: c++, programming
I quickly realized it's not easy to translate programming ideas to English statements without a syntactic structure. When I was whining about it to Vijay, he told me to try prototyping it in Python instead of writing pseudocode. Intrigued by this, I decided to write a prototype in Python to test how various modules will come together.
Surprisingly it took me a mere 2 hours to code up the prototype. I can't emphasize enough, how effortless it was in Python.
What makes Python an ideal choice for prototyping:
Dynamically typed language:Python doesn't require you to declare the datatype of a variable. This lets you write a function that is generic enough to handle any kind of data. For eg:
def max_val(a,b): return a if a >b else b
A list in Python need not be homogenous. This is a perfectly good list:
[1, 'abc', [1,2,3]]
class newDataType { int i; String str; Vector vInts; };
Built-in support for lists, dictionaries, sets, etc reduces the time involved in hunting for a library that provides you those basic data-structures.
Expressive and Succinct:
The algorithms that operate on the data-structures are intuitive and simple to use. The final code is more readable than a pseudocode.
For example: Lets check if a list has an element
>>> lst = [1,2,3] # Create a list >>> res = 2 in lst # Check if 2 is in 'lst' True
If we have to do it in C++.
list lst; lst.push_back(3); lst.push_back(1); lst.push_back(7); list::iterator result = find(lst.begin(), lst.end(), 7); bool res = (result != lst.end())
Python Interpreter and Help System:
This is a huge plus. The presence of interpreter not only aids you in testing snippets of code, but it acts as an help system. Lets say we want to look up the functions that operate on a List.
>>> dir([]) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__' , '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__','__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> help([].sort) Help on built-in function sort: sort(...) L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*; cmp(x, y) -> -1, 0, 1
- The type definition of the datastructures emerge as we code.
- The edge cases start to emerge when you prototype.
- A set of required supporting routines.
- A better estimation of the time required to complete a task.
Labels: c++, programming, python
Tmux is an awesome replacement for Screen. I have a couple of standard terminal layouts for programming. One of them is show below.
- Vim editor on the left.
- Top right pane has the bpython interpreter.
- Bottom right pane has the bash prompt.
selectp -t 0 # Select pane 0
splitw -h -p 50 'bpython' # Split pane 0 vertically by 50%
selectp -t 1 # Select pane 1
splitw -v -p 25 # Split pane 1 horizontally by 25%
selectp -t 0 # Select pane 0
In my tmux.conf file I have bound <prefix>+P to sourcing this file. So now anytime I want to launch my python dev layout, I hit <prefix>+<shift>+p.
bind P source-file ~/.tmux/pdev
Labels: linux, programming, python, tmux
Looking for tech jobs can be daunting. Networking is touted as the magic bullet for job seekers. But where do you start?
Here are some robust ways to build your network.
Users Group:
User groups are typically monthly meetings for geeks who get together to talk about their favorite programming language or operating system. Usually they are accompanied with a mailing list which is used to announce the meetings, ask questions and post job openings. So sign up to the mailing list and start attending the meetups. They are full of really nice people who are willing to help.
- Utah Python - Utah Python Users Group
- URUG - Utah Ruby Users Group
- SLLUG - Salt Lake Linux Users Group
- SLLUG-JOBS - Mailing list to announce job postings
- PLUG - Provo Linux Users Group
Local Conferences:
Most cities have some tech conferences that are a great source for networking. I found out about a lot of the user group by going to one of the following conference.
UTOSC - Utah Open Source Conference.
HackUTOS - Utah Open Source Project Day - Geeks, snacks and open source.
LaunchUp - A local entreneurship clinic. A great way to learn about the local start-up scene. You can meet new CEOs and fresh companies looking to hire tech talent. A must for job-seekers.
I hope this helps someone.
Last week I successfully submitted my first patch to an open source project and it was accepted.
I like the bpython interpreter for all my python needs. It is quite handy for a python newbie like me. A few weeks ago I was in the middle of building an elaborate datastructure to learn list comprehension in python, when bpython crashed and took all the history with it. I whined about it on twitter and one of the developers of the project prompted me to submit a bug report. I was quite impressed by the fact that a core developer of bpython replied to my bitching on twitter.
After I filed the bug report, I decided to get the source code and poke around. I finally implemented a feature that will save the history after each command instead of waiting till the end of a session.
The following factors were the main impetus that led me to contribute to the project.
Project Hosting:
The project was hosted on bit bucket which is a Github equivalent for mercurial. This makes it so easy to fork a project and issue pull requests, compared to the traditional source forge model of submitting patches in a mailing list. The social coding sites like Github and BitBucket have reduced much of the initial friction in starting an open source project.
Project Size:
This one has a huge impact when I decide to dive into the code. Traditional C projects tend to have a ton of files that are too big and daunting for a beginner. The bpython project was written in python and had a total of 13 .py files. This makes it dead simple to make a quick change and run the project without compiling it. Again the choice of language has a lot to do with this.
IRC:
The welcoming nature of the community around a project does a lot to encourage a new comer. The IRC channels are a great way to interact with the developers compared to a passive form of communication such as emails. I jumped on #bpython irc channel and started asking questions when I ran into an issue with bpython source code. People on that channel are really helpful and prompt in answering questions.
Persistence:
My first pull request was scrutinized by the core developers and some suggestions for improvements were given. During that process I learned a lot about code review and how to check for corner cases. Finally after I made all those improvements the pull request was accepted and merged with the main repo. So having a beginners mind (no ego) is an absolute must when getting started on any project. Don't be discouraged if your first attempt is unsuccessful.
Now I'm proud to say my name is listed in the AUTHORS file of bpython project.
Labels: programming, python
Tmux is an alternative for screen. For anyone who doesn't know screen, it is a terminal multiplexer which means, it allow multiple windows in terminal. It can split your window into multiple panes (vertical/horizontal), detach a session which can be attached at a later time. Detach/Attach is very useful for running a job in a remote server without having to keep the ssh open the whole time.
Labels: linux, programming, tmux
- Open gconf-editor
- apps
- metacity
- general
- raise on click (uncheck)
- Open gconf-editor
- apps
- metacity
- general
- compositing_manager (check)
If you think your users are idiots, only idiots will use it.
Labels: gnome ubuntu linux
I've been exclusively using Meego on my netbook and I was moderately happy with what it provided. So I did what any self-respecting hacker would do - I tried to make it better. Well, we all know how that usually ends. I managed to uninstall every single kernel in the system and rendered the system unbootable. Taking this as an opportunity I decided to try a grown-up OS. Enter Ubuntu into the picture.
- Fedora looked nice but wouldn't connect to internet. Same problem as Ubuntu, but this time, it wouldn't offer to download proprietary drivers.
- Mandriva image hangs up in the middle of booting (I'm personally embarrassed by this). Btw, Mandriva has to be the ugliest of all the OSes. Seriously man, you gotta up the ante a little bit if you want to stay in this game.
- Mint OS same as Ubuntu, only it looked even more gorgeous. I might try this out in the future.
Today I presented in the Salt Lake Linux User Group meeting. The topic was "Hands on Intro - Git". It went well and I actually enjoyed it quite a bit. I choked twice once while trying to explain how to git apply patches that you receive via email, but then recovered from it with some help from the audience. But the second time I choked while trying to explain how to pull from multiple remote repositories, I couldn't recover from that. I do that so rarely it never occurred to me. Oh well, the first time is the hardest.
Labels: programming, ptimer
Default MySQL uses /var/lib/mysql folder to store the database files. If you'd like to change that default location to something else, you can modify the mysql config file called my.cnf located in /etc/my.cnf.
[mysqld]IS:
user = mysql
datadir = /var/lib/mysql
[mysqld]Create the folder /home/mysql and copy the folders that are inside /var/lib/mysql to /home/mysql.
user = mysql
datadir = /home/mysql
cp -r /var/lib/mysql /home/mysql
chown -R mysql:mysql /home/mysql
service mysqld restart
Labels: mysql, programming
Making Standalone Application for Mac OS X from PyQt app using py2app
0 comments Posted by Amjith at 9:46 PM$ sudo easy_install -U py2appNext step is to create a setup.py that defines our package.
from setuptools import setup
APP = ['ptimer.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True,
'iconfile': 'bell.icns',
'includes': ['sip', 'PyQt4']}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
You'll notice that we included both sip and PyQt4 as dependencies, they will be bundled with the application.
$ python setup.py py2app
$ cd dist/ptimer.app/Contents/ResourcesTowards the end of the file there is a function def _run(*scripts):
$ open __boot__.py
Add this line after the import statement:
sys.path = [os.path.join(os.environ['RESOURCEPATH'], 'lib', 'python2.6', 'lib-dynload')] + sys.pathYou might have to change python2.6 to the appropriate folder name inside the dist/ptimer.app/Contents/Resources/lib folder. Double-click to make sure it is working.
$ hdiutil create ptimer.dmg -srcfolder dist/ptimer.app
Labels: programming, ptimer, PyQt4, python
python configure.py -d /Library/Python/2.6/site-packages -b /usr/local/bin --use-arch=i386
>>> import PyQt4
$arch -i386 python2.6 pyqt_test.py
#!/usr/bin/env python
import sys
from PyQt4 import QtCore, QtGui
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.pushButton = QtGui.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(80, 80, 271, 151))
self.pushButton.setObjectName("pushButton")
self.retranslateUi(Dialog)
QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), Dialog.close)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "Close", None, QtGui.QApplication.UnicodeUTF8))
class DialogTest(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = DialogTest()
myapp.show()
sys.exit(app.exec_())
Now try running the script:
$arch -i386 python2.6 pyqt_test.py
Traceback (most recent call last):Happy Hacking!
File "pyqt_test.py", line 4, in
from PyQt4 import QtCore, QtGui
ImportError: dlopen(/Library/Python/2.6/site-packages/PyQt4/QtCore.so, 2): no suitable image found. Did find:
/Library/Python/2.6/site-packages/PyQt4/QtCore.so: mach-o, but wrong architecture
Labels: Mac OS X, programming, PyQt4, python
- Choose a task to be accomplished
- Set the Pomodoro to 25 minutes (the Pomodoro is a timer)
- Work on the task until the Pomodoro rings, then put a check on your sheet of paper
- Take a short break (5 minutes is OK)
- Every 4 Pomodoros take a longer break
- Download and unzip the ptimer
- Launch ptimer.py
- Windows: Double click on ptimer.py
- Linux/Mac OS X: Type './ptimer.py' from Terminal
- Set the appropriate alarm times in the settings box and press Ok.

- The ptimer will reside in the system tray.

- When the timer expires it will flash a small display.

- Left click to start the second alarm timer.
- Repeat as necessary.
- Right click on the timer display or the systray icon to control the behavior of the timer display.
Labels: pomodoro, programming, ptimer, PyQt4, python
Caving (or Spelunking) is the sport of exploring caves. Yosh and I recently had the opportunity to go on our first spelunking adventure. It was offered at the Timponogos caves in Utah for a group of five. It wasn't quite as dangerous and difficult as it sounds, but it was definitely more than just walking inside a cave. We donned our hard-hats with head lamps before entering the dark hole in the mountain. We were accompanied by a Ranger who knew what he was doing.
Labels: caving, hiking, spelunking



