Tuesday, November 17, 2009

Lazy programmers

I recently accessed the on-line customer service for the Des Moines Register. Part of that process has you register your account number. Here's the message I got on the field to enter your account number:
(You can find your account number on your invoice or call customer service at 1-877-424-0225. You must drop all beginning zeros and include the 'DM'. For example DM00012345 becomes DM12345.)
Exactly how difficult would it be to write an algorithm that would add the DM if I forgot? Or drop the leading zeros?

The DM Register is hardly alone. Many sites ask you to enter your credit card number, but without spaces. Stripping spaces takes only 1 to 2 lines of code, depending on the language you are using. If I want to enter spaces with my credit card number, don't let that stand in the way of my spending money at your web site.

Sunday, August 30, 2009

HP Counterfeit Ink

Just when I thought my HP Photosmart C7280 Printer could not be any more annoying, it has picked up a new "feature."

What were a few of the original annoying features?
  • Continuously running 6 different processes.
  • Throwing up a dialog box to every computer in the house when it is low on ink, out of paper, or even if it has been turned on.
  • Originally it had 'critical updates' 2-3 times a week it needed to download. I figured out how to turn that off thankfully.
  • 1/2 the computers in the house cause a blank sheet to print between each actual page we want printed.
The 'new' feature: accusing me of using counterfeit ink. It is already a waste when studies have shown printers to report cartridges empty long before they actually are. But now I can't use my nearly full cartridge after only a month, because printer is suddenly convinced it is not a 'real' HP cartridge. At first it kept giving me nasty messages about voiding my warranty. Now it just refuses to use it at all.

Bad Hewlett-Packard.

Thursday, July 9, 2009

Searching and Sorting algorithms

I'm teaching second semester programming this summer. This is the class where classic algorithms such as binary search and QuickSort are introduced. These algorithms have a certain beauty about them that I really enjoy.

The book I'm using is Java Software Structures. This book is a solid CS2 textbook that covers searching and sorting in the order one would expect. I did not find the book to be outstanding, just a solid contender. I think the book would be outstanding if these issues were addressed:
  • The book uses generics, iterators, and other advanced features of Java without adequate coverage in the text. There is some coverage, but not enough. Many students coming out of a CS1 course won't be prepped enough to use them.
  • Code for searching and sorting is only given using generics. This forces students to solve 2 problems, what is the algorithm doing, and what's going on with the generics. I'd prefer the code first be introduced using an integer array, or even pseudo-code. If the code using generics was shown right after an integer array example, it would help emphasize what generics add.
  • I'd like to see some recursive algorithms, like binary search, be shown in non-recursive form. Otherwise students might think that the recursive algorithm is the only way to do it.
  • I'd like to see better images of the searching and sorting in progress.

Past that, not a bad book.

Tuesday, June 23, 2009

8-bit microcontoller programming

I'm once again learning how to do simple embedded programming. I'm using the DEMO9S08AW60E board from Freescale. Unfortunately I'm solving the same problems I ran into last summer I worked on this.

So just in case someone (like me) runs into these problems, I'll blog about them so that the solution can be found via Google.

1. CodeWarrior for Microcontrollers doesn't work with 64-bit Microsoft Vista. It won't even install. Its been that way for several years, no fix coming. Even more annoying, the installer just fails with a cryptic message. Nothing that would indicate that the problem is 64-bit Vista incompatibility.

2. Any time my program tries to run an analog to digital conversion (ADC), the program hangs. I'm not sure why, but I traced the issue to this line in the ADC bean's initialization function:

setReg8(ADC1CFG, 0x7A); /* Set prescaler bits */


Once that runs, I can't do a conversion. The line is auto-generated by the 'processor expert' that comes with CodeWarrior. Every time the processor expert generates the code, I have to comment out this line. I'm not sure yet whatthe 'prescalar bits' are supposed to be set to. I figure when I take the time to understand that, I can code around the issue.

3. Since doing a ADC uses an interrupt, it doesn't work to place the code inside a different interrupt. Measurements have to be done in the main loop.

Now I can blink LEDs and read a 2-axis accelerometer. My not-very-exciting program can change the rate the lights blink depending on how the board is tilted. Next step is to see if the custom printed board a student built last year can be programmed. That board is set up for interfacing robotic servos.

Saturday, June 13, 2009

Python and scope

I think this rule with scope in Python is not intuitive. Take a look at the following program:

1 x = 1
2
3 def main():
4 print x
5
6 main()

x is in scope within main(), and the program runs correctly. Now look at this program:

1 x = 1
2
3 def main():
4 print x
5 x = 1
6
7 main()

This program fails, it can't print x because the value for x has not been set before printing it in line 4.

Why? x is set in line 1, correct? True. But that x is not in scope.

By setting x=1 in the main function, we get a brand new variable called x, which is only in the main function. There are 2 variables, both named x. One for the main file script, and one for the main function. And since x has not been set in the main function, print x does not work.

Saturday, March 7, 2009

Running into walls with Python and Pygame

This is an example of using Python and Pygame. You can move a square box with the keyboard and bump into wall objects.


 import pygame
from pygame.locals import *

black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)

# This class represents the bar at the bottom that the player controls
class Wall(pygame.sprite.Sprite):
# Constructor function
def __init__(self,height,width,x,y):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)

# Make a blue wall, of the size specified in the parameters
self.image = pygame.Surface([width, height])
self.image.fill((blue))

# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)

# This class represents the bar at the bottom that the player controls
class Player(pygame.sprite.Sprite):
# Constructor function
def __init__(self,x,y):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)

# Set speed vector
self.change_x=0
self.change_y=0

# Set height, width
self.image = pygame.Surface([15, 15])
self.image.fill((white))

# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.rect.topleft = [x,y]

# Change the speed of the player
def changespeed(self,x,y):
self.change_x+=x
self.change_y+=y

# Find a new position for the player
def update(self,walls):
# Get the old position, in case we need to go back to it
old_x=self.rect.topleft[0]
old_y=self.rect.topleft[1]

# Update position according to our speed (vector)
new_x=old_x+self.change_x
new_y=old_y+self.change_y

# Put the player in the new spot
self.rect.topleft = (new_x,new_y)

# Did this update cause us to hit a wall?
collide = pygame.sprite.spritecollide(self, walls, False)
if collide:
# Whoops, hit a wall. Go back to the old position
self.rect.topleft=(old_x,old_y)

# This is the main function where our program begins
def main():
score = 0
# Call this function so the Pygame library can initialize itself
pygame.init()

# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])
# Set the title of the window
pygame.display.set_caption('Test')
# Enable this to make the mouse dissappear when over our window
#pygame.mouse.set_visible(0)
# This is a font we use to draw text on the screen (size 36)
font = pygame.font.Font(None, 36)

# Create a surface we can draw on
background = pygame.Surface(screen.get_size())
# Used for converting color maps and such
background = background.convert()
# Fill the screen with a black background
background.fill(black)

# Create the player paddle object
player = Player( 50,50 )
movingsprites = pygame.sprite.RenderPlain((player))

# Make the walls. (height, width, x_pos, y_pos)
wall_list=[]
wall_list.append(Wall(600,10,0,0))
wall_list.append(Wall(10,790,10,0))
wall_list.append(Wall(10,100,10,200))

walls=pygame.sprite.RenderPlain(wall_list)

clock = pygame.time.Clock()

while 1:
clock.tick(40)

for event in pygame.event.get():
if event.type == pygame.QUIT:
return

if event.type == KEYDOWN:
if event.key == K_LEFT:
player.changespeed(-3,0)
if event.key == K_RIGHT:
player.changespeed(3,0)
if event.key == K_UP:
player.changespeed(0,-3)
if event.key == K_DOWN:
player.changespeed(0,3)

if event.type == KEYUP:
if event.key == K_LEFT:
player.changespeed(3,0)
if event.key == K_RIGHT:
player.changespeed(-3,0)
if event.key == K_UP:
player.changespeed(0,3)
if event.key == K_DOWN:
player.changespeed(0,-3)

player.update(walls)

pygame.draw.rect(screen,black,(0,0,800,600))
movingsprites.draw(screen)
walls.draw(screen)
pygame.display.flip()

#this calls the 'main' function when this script is executed
main()

Tuesday, February 17, 2009

Wells Fargo Rewards

I'm a fan of Wells Fargo. But even good companies can make a mess of things.

Today I decided to use some of the reward points for my credit card. So I dug out my password and signed on to the rewards site. After logging in I got this screen:

wf_1

I didn't read it to carefully the first time. I still don't quite get what it is saying, but for some reason it thinks I need to choose a new user name and password. My old user name and password meet all their requirements, why do I need a new one?

This is the next screen:
wf_2

After seeing this, alarm bells go off. I already logged in, why does it need this information? I checked the URL and the signed certificate and both were legit. So I go on to the next screen:

wf_3

The option where you can choose to change user name, password, or both? You can't choose any option other than both. Why even show the option if it isn't one?

It then asks for my card number. Didn't I already enter that in the last screen? The default password is the last 4 of my SSN, which I entered the last screen.

On the plus side, I was able to enter the same user name and password I had before and the system took it. On the bad side, the next time I logged in it sent me though the process again.

Another example of security improvements that annoy the user and don't improve security: The Wells Fargo employee site. Here they improve security by requiring not one, but two passwords.

I think this is supposed to be a poor man's version of two-factor authentication. Except the person specifying the requirement flunked their security class. There is no difference between two passwords and one password. They are both "something you know"; just one factor. You could just increase the minimum password length to get the same effect.

Thursday, February 12, 2009

DSL Splitter

Ever since we switched from cable Internet service to DSL service, we've had three problems:
  • Our phone line was noisy.
  • The Internet might disconnect while someone was on the phone.
  • We didn't weren't getting the full speed of the Internet connection we were paying for.
I just finished installing a solution to those problems:
This thing works great. $30, plus $10 for shipping. About an hour to install.

Wednesday, January 7, 2009

TinyMCE Javascript WYSIWYG editor

TinyMCE looks like a good WYSIWYG editor that can be put on web pages. I like what Google uses for Blogger as well. About anything would be better than what Moodle uses. What editor do other people like to use?Link