Archive for Programming

Battery Duration Testing Program

Today, David Pogue (the NYTimes tech columnist) posted this on Twitter–a request for a program that would write the time every thirty seconds until the battery powering it died.

I rose to the challenge and wrote this, in Python:

'''
Copyright 2009 by Timmy Macdonald <timmy@tsmacdonald.com>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses>.
'''
import time as t
f = file('battlog.txt', 'w')
total = 0
opener = "Testing begun at" + str(t.localtime(t.time()))
print opener
f.write(opener)
f.close()
while True:
    f = file('battlog.txt', 'w')
    t.sleep(30)
    print t.localtime(t.time())
    total += .5
    message = "30 seconds passed: it is now %s and this has been running \
for %s minutes."%(t.localtime(t.time()), total)
    f.write(message)
    print message
    f.close()

Pogue likes it, and since I GPLed it and it could come in handy for someone else, I decided I’d put it up here, too.

—–

David Pogue complimented me in front of 24,645 people!

!

Share/Save/Bookmark

Leave a Comment

An Object-Oriented Primer in Python: Part 2

In the first installment, we learned a bit about objects (they hold information, and do things), and how to use pre-built objects (object.method() for a method (aka function) and object.variable for a variable). Now let’s talk about making our own classes.

The class statement:

The way you make a class in Python is with…the class statement, the name of the class, and a colon. So our Dog class is:


class Dog:

Hard, isn’t it? :) And, in true Python style, everything that’s part of that class is indented. (But you already knew that, because of the colon, right? :) )

Methods

Methods are made in a very similar manner to standard functions. There’s two main differences: They require a parameter called “self”, and there’s a few reserved methods that do special things.

Our Dog class had a method called showBreed(). It looked like this:

    def showBreed(self):
        print "It's a %s"%self.breed

So we have the def statement, the name of the method, and then “self” is the only parameter. Self is kind of a tricky concept: It refers to the object that’s calling it. So when we print self.breed, we’re printing the string called breed from whatever happens to be calling it. If it helps, you can think of it as sort of a wildcard: It can be fido.breed, it can be spot.breed, it’s a placeholder to show that it’s somebody’s breed. If you don’t grok that, read it again: This was probably my biggest stumbling block when I learned it. Now that you have that cleared up, realize that you also need to put self in as the first parameter for every method you define, but that when you actually call, the method, you pretend it isn’t there. Maybe some error messages would help:

>>> class Error:
    def cry(self):
        print "Method called"

>>> e = Error()
>>> e.cry()
Method called
>>> e.cry(self)

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    e.cry(self)
NameError: name 'self' is not defined
>>> class OtherError:
    def cry():
        print "Other method called"

>>> o = OtherError()
>>> o.cry()

Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    o.cry()
TypeError: cry() takes no arguments (1 given)

So, as you can see, calling a method with “self” raises one error, and defining a method with no “self” raises another one when it’s called–when you call it Python automatically includes the “self” (cry() takes no arguments  (1 given)).

__init__():

Now we come to one of the most important methods: __init__(): Observe:

>>> class Blog:
    def __init__(self, name):
        self.name = name

>>> RmI = Blog("Rannsaich mo Inntinn")
>>> RmI.name
'Rannsaich mo Inntinn'

__init__ (you can call it a constructor if you want) is called as soon as an object is initiated. Note how I never explicitly called it. The astute may have noticed that when I created the RmI object, it’s arguments matched __init__’s perfectly–the self is implicit, and the name is “Rannsaich mo Inntinn”. The very astute may have noticed that, actually, Blog was defined with no arguments in the beginning (you can have class Blog():, and put stuff in the parentheses, but that’s called inheritance and is a topic for another day).

You also see __init__ doing something it does a lot, doing self.xxxx = xxxx. This takes the xxxx (alright, in this case it’s name) parameter, and gives it a home as part of that object. Because if we didn’t do self.name = name, whatever value name was would get deleted as soon as __init__ was over, and there’d be no way of using it in other methods. Of course, you can use that elsewhere to, in Part 1 we manipulated self.breed directly, and you can also change self.xxxx from other methods. But __init__ is really the best for, um, initializing them.

Once you swallow all of that, go back to that Dog class, and see if you can write it. You know all of the components–try fitting them together. If you need help, post it in the comments.

—————

Here’s my Dog class, which you really shouldn’t be looking at, but…

class Dog:
    def __init__(self, breed):
        self.breed = breed
    def showBreed(self):
        print "It's a %s"%self.breed
    def changeBreed(self, breed):
        self.breed = breed
-----------

And so ends the series. There’s a lot of things I haven’t covered–the __del__ method, polymorphism (having the same method name do something different depending on what class it belongs too), inheritance (I couldn’ve had a Pet superclass, with name, breed, etc. and then Dog and Cat subclasses that inherited methods and attributes from Pet, but had some of their own (i. e. Dog.woof(), Cat.washBody()…) and a bunch of other stuff. But this is really all you need to know to do well–everything else is just very important icing. And there’s certainly enough tutorials out there for that.

Share/Save/Bookmark

Comments (8)

An Object-Oriented Primer in Python: Part 1

I’ve read several tutorials on Object-Oriented Programming (OOP), and none of them has been as clear as I thought they should be. So it took me a long time to figure out OOP, and now I feel like I should pass on the knowledge. Here it is:

Objects

One of the main difficulties in OOP is thinking about it. So start trying to wrap your mind around an object. Basically, an object is a specialized data structure than can hold information, and do things with it. In other words, it’s a thing represented by code. And you aren’t limited to just one thing, you can have as many as you want, just as you can have as many numbers, lists or dictionaries as you want.

Holding Information and Doing Things

You can give objects attributes. What’s even cooler is that you can access them really specifically:

fido = Dog("Golden Retriever")
fido.breed

Assuming you’ve made a “Dog” class, fido.breed will be a string saying “Golden Retriever.” You can also change the data (it’d be pretty pointless if you couldn’t…) :

>>> fido = Dog("Golden Retriever")
>>> fido.showBreed()
It's a Golden Retriever
>>> fido.breed = "Labrador"
>>> fido.showBreed()
It's a Labrador
>>> fido.changeBreed("Dalmatian")
>>> fido.showBreed()
It's a Dalmatian
>>> fido.breed
'Dalmatian'

Here we make a Golden Retriever named fido. We have it call a method (OOP-speak for function) to say what breed it is, and then change it’s breed variable to “Labrador.” After that, we use a different method (yes, objects can have multiple methods) to change the breed to “Dalmatian,” and have fido tell us that he is, in fact, a Dalmatian. If you feel like having to prefix everything with “fido.” is annoying, don’t worry: There’s a reason. We could just as easily have:

>>> fido = Dog("Golden Retriever")
>>> spot = Dog("Mutt")
>>> fido.showBreed()
It's a Golden Retriever
>>> spot.showBreed()
It's a Mutt

If we just used a generic ‘showBreed()’ method, Python wouldn’t know whether we were talking about fido or spot, or some other dog. The <name><dot> system is a pretty efficient way of telling Python who’s doing what, or who’s remembering what.

Look back over this section and make sure you understand it well: We made an instance of the Dog class, which held information (fido.breed) and did things (fido.showBreed()), we also made another instance of the same Dog class (spot), which held different, but similar information (Mutt instead of Golden Retriever), and did similar things (said what breed he, spot, was, as opposed to what fido was).

Obviously stuff can get a lot more complicated, but if you understand that, you’re doing fine!

~Read Part 2 to learn how to make classes~

Share/Save/Bookmark

Comments (1)

Web Design Woes

I’ll tell you right off the bat–this is not an “article”, just a post. Now that we’re clear:

I take back a lot of what I said about HTML, CSS and the W3C. It’s all a good idea, and I now realize that. That said, I’m still a bit touchy about the Validator. Want proof? This page was validated in 2008, but running it through the Validator again brings up four errors and two warnings. I’m sure they have their reasons, but I still feel that my anger is justified.

All of that said, I’ve been redoing my website to:

  • Use HTML for page logic.
  • Use CSS for page looks (a challenge, considering that as of this morning I didn’t know CSS at ALL.)
  • Make the little navbar thingy towards the top a lot easier to maintain.
  • Pass the Validator (OK, OK, maybe Tidy HTML can help a bit.)

I also took advantage of the shuffle to rewrite the content a bit.

So far, I’ve finished one page, which was based on this one, but will now double as my index too.

A few notes:

  • All the CSS on it was whatever I could hack in a few hours using Google, part of this, scientific experiments with simple pages and Tidy HTML and logic. I have no idea how ‘nice’ it is (in terms of coding style) but it appeases my eyes, the Validator, and the end product, so I’m not complaining. I do not recommend this method of learning for the faint of heart. (Yes, I am going to do a proper tutorial this summer, I just wanted results NOW.)
  • I hacked together some Javascript for my navbar. This was accomplished by: Looking at sample code, and writing like a Pythoneer while using the Java syntax I’m learning in school.
  • So far, the Validator is happy!

Some of you might be wondering what happened to my colors. Answer: I’m colorblind, and as such have absolutely no sense for what looks good on a page. I began to think that all the blue might be a bit overwhelming, so I’m going old-school with the black-on-white. If you have any opinion on this, please relate it in the comments. I would really appreciate it.

I’m a bit miffed that this means absolutely nothing to people looking at my site with polite browsers, but I guess this is what they would call a Black Triangle. It makes me feel really proud of myself though, which is one of the reasons I love coding.

Goal: Finish the rest of the pages by the end of this weekend, and move everything from my ‘experimental’* subdomain to the real deal.

*That thing is great for organization.

Share/Save/Bookmark

Comments (1)

Python and C…Wow…

I’ve come to the realization that as nice as Python is, I really ought to learn a lower-level language. Even though I own two C++ books, I’m only reading them to a)Gain a rudimentary knowledge of the C++ syntax, such that I can hack it if I have to b)Improve my conceputal knowledge c)Well, they are interesting.

Instead, I’m learning C, because it just seems like more of my cup of tea. And kernel hacking might be fun :)

So one of the sample programs in the tutorial I’m using is that which will list all the numbers from 1-2500, and say if they’re prime or not. I faithfully wrote and compiled it in C, ran it, and WOW! that was fast. I could not detect any sort of delay, or processing or anything, it was just:

<Enter><A screenfull of numbers, ending in “2500 is not prime” appears>

I was so impressed by this, I converted the code to Python. I even removed a function that listed the version number and time compiled. When I ran it, I could see numbers whizzing by the screen for half a second or so, and then it was done.

I know it’s old news that compiled languages are faster than interpreted ones, and that low-level languages are faster than high-level ones, but it’s just impressive to tangibly see it.

Share/Save/Bookmark

Comments (1)

Playing Python, Programming Pianos

New programmers are never sure what it “takes” to learn a programming language. This is not helped by the quantity of “Learn x language in 24 hours/3 days/etc.!” books that are out there, and by the overabundance of technical information available.

So what I propose is an analogy.

You might think that the analogy I would make would compare learning a programming language to learning a foreign language (e. g. Spanish.) But after much deliberation, I don’t think that’s a valid for several reasons:

  • Foreign languages are almost always more complex than programming languages. Something like French has evolved for the past two millenia, while even ‘old’ programming languages have only been around for 50 years. Furthermore, French has the task of concisely communicating any conceivable expression to another human, while C/Java/Delphi only has to boss around some chunks of metal and silicon.
  • You must memorize every aspect of a foreign language, while with programming languages you have the all-powerful documentation to help you with some of the less common things.
  • Even if you know that “Hello” is the most common greeting in English, you’ll sound dumb if you don’t use “Hi”, “Hey”, and “What’s up?” in the right circumstances. Meanwhile, BASIC will always think “10 PRINT “HELLO, WORLD!” is the best way of doing things.
  • Similar to the first one, foreign languages have a MUCH bigger vocabulary to learn than programming languages.

So I really don’t think it’s a valid comparison.

What I consider more vaild is comparing programming languages to musical instruments. First, let’s think about a story about little Billy.

Little Billy decided one morning that, since he really like music, he wanted to learn to play a musical instrument, so he could make his own music. He went to the music store, and was initially awed by the sheer quantity of different types of instruments for sale. After much inner turmoil, he decided to use the piano, since it was common, rationalizing his choice by thinking, “Since so many people use it, it must be one of the best choices. There’ll also be more people who can help me. Finally, it sounds good.” While he was in the music store, he also picked up a tutorial on learning how to play the piano.

He went home, and did a chapter of the book per day, being sure to actually play the piano as much as possible. By the time he finished working through the book, he was a decent piano player, but still had a lot to learn. He kept playing, hired a teacher, and within a few years he was downright adept.

Now consider little Billy’s brother–Tom.

Tom decided one morning that, since he really like computers, he wanted to learn to program, so he could make his own programs. He went online, and was initially awed by the sheer quantity of different types of programming languages available. After much inner turmoil, he decided to use Python, since it was common, rationalizing his choice by thinking, “Since so many people use it, it must be one of the best choices. There’ll also be more people who can help me. Finally, the syntax looks good.” While he was online, he also picked up a tutorial on programming in Python.

He went home, and did a chapter of the tutorial per day, being sure to actually do the programs as much as possible. By the time he finished working through the tutorial, he was a decent programmer, but still had a lot to learn. He kept programming, started working on projects so he could learn from the project chief, and within a few years he was downright adept.

Now that you know where I’m going with this, I can fill in some details:

They both give you ‘instant success.’ Anybody, and I mean anybody, can either make his computer say “Hello World!”, or play a few notes on an instrument within ten minutes.

They both have specific technique. Java programmers know that using a variable without declaring it first is a big no-no. Trumpet players will fail if they just move their fingers–and don’t blow.  Another way of saying this is that they both teach through failure–be it a bad sound or a segfault.

They both provide gratification. People get really excited when they play a tune well, or solve a particularly sticky programming problem.

If you do something again, you’ll do it better When an elementary school band plays “The Star-Spangled Banner”, it is very apparent that it’s not the New York Philharmonic playing “The Star-Spanled Banner.” A first-year programmer will use a very different method for solving a problem when compared to an old-hand.

So if you’ve ever learned how to play an instrument, you’re primed for programming. And if you’ve ever programmed, you know what it takes to play an instrument.

——-

I’m kind of interested in the reception this is going to get–please let me know what you think!

Share/Save/Bookmark

Comments (1)

Really concise explanation of random integers in Python

I wanted to use Python to generate some random integers, and a few minutes of Googling was not very helpful. I figured it out in the end, but I feel like something this basic should be easy.

First you need to import the random module, so:

import random

Then, to get a random integer from 1 to x, use

random.randrange(x)

It’s as easy as that.

(OK, OK, sorry. I know this probably isn’t of general interest, and it’s probably of minimal help, but I was just irritated that it wasn’t really easy to find online.)

Share/Save/Bookmark

Leave a Comment

TI-BASIC (Round Three) (Control Flow: If-Then-End)

Consider the following code:

1->A
If A = 1
Disp "A=1"

Let’s study it a bit. The first line just stores 1 as A. Standard stuff. The second line is freaky, and the third line just displays “A=1″. Standard stuff. Let’s go back to the freaky part. It introduces one of the more powerful commands in TI-BASIC: If. What it says, is that if A equals 1, to do something. The syntax isn’t nearly as remarkable as the code, just If [value][thingy][value]. Thingy can be anything from the ‘Test’ menu. =, <, >, etc.

Note: Due to the constraints of this keyboard, the less-than-or-equal-to sign will be written as <=, and the greater-than-or-equal-to sign will be written as >=. Also, the not-equal-to sign will be written as !=.

If you’re looking for ‘if’, it’s under ‘Ctl’, not ‘I/O’. And this is the first time we’re using ‘Ctl’…Yay! OK, digression over :)

If’s power comes from the fact that it introduces uncertainty into the program. This means the program can rocket off in a lot more directions, which means: Sweeeeeeet.

Since you handled that chunk of code so beautifully, let’s consider this one too.

Input A
If A=1
Disp "A=1"
Disp "Where is this?"

I hope you’re wondering if the ‘Where is this?’ line is part of the if statement or not. It’s not. The only command that’s conditional is the one immediately after the if line. Which is really useful for a code snippet like this:

If A=1
Disp "A is 1"
If A=2
Disp "A is 2"
If A>2
Disp "A is pretty big"
If A<1
Disp "A is pretty small"

That's a lot cleaner than the following method, which is also legal.
If A=1
Then
Disp "A is 1"
End
If A=2
Then
Disp "A is 2"
End
If A>2
Then
Disp "A is pretty big"
End
If A<1
Then
Disp "A is pretty small"
End

You’re probably wondering why that’s legal. It’s stinking huge! Which brings us back to our problem–if only lasts for a line. If-Then-End fixes that problem. Then means that all of the following instructions are only to happen if the statement is true, and End means that an end has been put to the conditional instructions. There’s no arguments required for Then or End (an argument is something that has to be put with it to make the syntax legal.) So let’s look at our ‘Guess!’ program again. Last time we’d gotten this far:

Disp "Guess!","","(GPL) 2008", "T. Macdonald"
#Note that going from the outline to the implementation there was a better idea--putting 'Guess!' and the GPL on separate lines.
Input "Guess:".G
#Oh no! We don't know how to make a random number!
#Oh no! We don't know how to say if the number is too big or too small!
#(That's why the tutorial's not done. Stay tuned.)

And now we do know how to say if a number is too big or too small!
So
#I'm not copying all the code, we'll pick it up here:
Input "Guess:", G
If G<R
Disp "Too small!"
If G>R
Disp "Too big!"
If G=R
Disp "You win!"

Unfortunately, that’s really all we can do with that, as of right now.
Next time we’ll talk about Else.

Assignment: Write a program that will ask the user for his age, and then will classify them as “Kid” (12 and under), “Teenager” (13-19) or “Adult” (20+).

Share/Save/Bookmark

Leave a Comment

TI-BASIC (Round Two-and-a-Half) (More with Input)

The somewhat astute among us have noticed that in Round *, there was the following line of code:

Input "Guess:",G

And that I haven’t explained how that works.

The pretty astute among us have also noticed that when they run a program such as the following:

Input G

All that’s shown is a question mark, and it’s not very visually appealing.

The quite astute among us have already realized that the way to get rid of the ugly question mark, and replace it with something more attractive is to put the attractive message in quotes, follow it with a comma, and then tack the variable name to the end of it.

Those who are not feeling very astute should be please that the astute have shared their thoughts, and we’re all back on a level playing field.

Finally, the EXTREMELY astute people are saying to themselves “It is such a drag when there’s like four variables that the user has to put in, and I have to make four Input statements. Four! Can you imagine? Surely there’s an easier way.”

Meet Input’s big brother ‘Prompt’. (TI-BASIC is very family-oriented. Output is Disp’s big brother, Input is Prompt’s little brother, Else is If’s big broth–oh, we haven’t gotten there yet. Round three is coming.)

Prompt is great for math. Take the Pythagorean Theorem:

Prompt A,B
A^2+B^2->D
sqrt(D)->C
Disp C

Which will display:

A=?
B=?
(The solution, which depends on the input)

So Prompt is just a quick and easy way of getting a bunch of variables inputted. Would I use it for games, or polished programs? No. Do I use it for quickly making a program that’ll do a mathematical formula? Always.

Share/Save/Bookmark

Leave a Comment

TI-BASIC (Round *) (Special Bonus Edition)

I’ve been thinking, and I realized it’d be nice to add another goal to the TI-BASIC series. So I’m adding a sample program.

About the program: It’s called ‘Guess!’ (I am really creative), and it’s been around since I was in the fifth grade, in one form or another. It consists of guessing a number from 1-100, and being told if it’s too big or too small, and then guessing again, and being told again, etcetera, until you guess the number.

Technical description: Before you make a program, it’s a really really really really really really really really good idea to know exactly what you want it to do. So here’s the ‘outline’ (remember that # and everything after it is a comment):

Guess! (GPL 2008 T. Macdonald) #Title and license (GPL is sort of like a Copyright)

Guess: #User guesses a number

Too big! #If the number’s too big

Too small! #If it’s too small

You win! #If the user guesses it

And that’s it. Believe it or not, the minute it took to write that saved a lot of wasted coding.

So let’s implement what we already know:

Disp "Guess!","","(GPL) 2008", "T. Macdonald"
#Note that going from the outline to the implementation there was a better idea--putting 'Guess!' and the GPL on separate lines.
Input "Guess:".G
#Oh no! We don't know how to make a random number!
#Oh no! We don't know how to say if the number is too big or too small!
#(That's why the tutorial's not done. Stay tuned.)

Share/Save/Bookmark

Leave a Comment