Showing posts with label 10. Show all posts
Showing posts with label 10. Show all posts

Thursday, November 14, 2013

Book Review #10


Programming Python
Mark Lulz

Programming Python is the more practical of the Learning Python-Programming Python pair. In all, I like this book better. I'm more of a practical programmer than theoretical one. As a Perl fan, I hate to see the oft-repeated attitude that Python is a "better Perl". Other than that, I have no problem. I am somewhat disappointed to discover that the thick 1500 pages tome does not cover PyGame. It does get a mention, but come on. Don't you think that if you don't have a space to cover that, at least reference some good books on it? I'm rather disappointed. Granted, the main purpose of the book is to write a clean, portable python programs, and in that mission, it succeeds admirably. But the lack of other resources cited remains a rather curious omission that would have made the book even more complete.

I also think that as good as it is, the book fails to convey Python's strength. Take this example from the clock (Ch 11, p748):


  1. def point (tick, range, radius):
  2.     angle = tick * (360.0 / range)
  3.     radiansPerDegree = math.pi / 180
  4.     pointX = int( round( radius * math.sin(angle * radiansPerDegree) ))
  5.     pointY = int( round( radius * math.cos(angle * radiansPerDegree) ))
  6.     return (pointX, pointY)


Reading the code makes it obvious that this is just a way to return a point, given angle and distance. In other words, polar coordinates. There are several marks, that I want to address.

  1. Why the parenthesis in (360.0 / range)? Precision should be no problem. The only reason that I can think of is variable types. I mark this as a drawback of strongly typed languages. The parenthesis should be optional.
  2. radiansPerDegree? Some languages provides that as a function. Why do you have to built your own?
  3. int( round( ? Come on. In any other language, it's either int() or round(). Definitely not both!
  4. math.sin(), math.cos(). Do you seriously prefer this to sin(), cos()?


And that's just the language. I suppose, if I'm feeling mischievious, I can point out that radiansPerDegree is completely internalized, and thus unnecessary complication. Just because the function takes radians, does not mean you have to convert degrees to radians. Like so:


  1. angle = math.pi * 2 * tick / range


You may put any necessary parenthesis where you want. If simple is better than complex, then the text code doesn't show. What's the matter? Can't think in radians? Don't you think that as a professional programmer, you should learn it? No computer language is so good that you can be sloppy!

And if I really nitpick, I guess I can complain about associating X with sin, and Y with cos, instead of the "proper" way X with cos, Y with sin. But I won't. ;)

And here's another thing, later in the book (p. 761):


  1. class PPClockBig(PhotoClockConfig):
  2.     picture, bg, fg = gifdir + 'ora-pp.gif', 'navy', 'green'

  3. class LP4EClock(GilliganClock):
  4.     size = 700
  5.     picture = gifdir + 'ora-lp4e.gif'
  6.     bg = 'navy'


and so on...

I counted 9 such classes. People have pointed out to me that Python is so powerful that it can take such flexible class arrangements. I agree that the language is powerful in order to take that. However, I'd rather see it in tabular form. A straight array will be simpler, cleaner, and clearer. Plus the advantage of loading it from file, so that you don't have to change the code just because you want a new background color. BTW, Perl can trivially do it via HereString, while retaining simplicity and clarity.

The book ends with a bad joke:

"But how will I know why Python is better than Perl?"

"You will know. When your code you try to read six months from now."

I think that joke is in poor taste. You're trying too hard to position "Python as the better Perl". My response?

"I get it. Your brain is spaghetti. However, instead of straightening your brain and learn how to code properly, you simply blame your tool. What kind of a workman, are you?"

I can still recommend the book, but it's not as good as Learning Python. Little distractionary things pepper the book, and I do not enjoy it as much.

Monday, October 28, 2013

Cooking Journal #10


Hashbrown


I bought a sack of Russell potato from Idaho. The package says that it's good for frying. Actually, it doesn't matter what kind of potato. As long as it says Idaho on the box, it's good.


I sliced the potato thinly, like as if I'm making some potato chips. Ummm. Yes, that's a Buck knife. Not a kitchen knife.



Next I sliced it again. This time perpendicularly. Notice now that the potato are little strings standing upright.



Next step is to fry them. I didn't use anything, except a spoonful of oil. It works fine as-is, but cooking time is too long for me. I guess I just don't have the patience to do it. The potato sticks together, so I have no problem flipping it for even cooking.



Serve with fried egg and sausages. That's a good hearty breakfast! It does take too long to prepare, but doing it once a week isn't bad.

Saturday, October 26, 2013

Nintendo Journal 10


Leatherman Blast



Although my daily carry is a Buck folder, I do have other knives. I have several Swiss Army Knife folders. Some models are Camp, Hunter, and several others. I really like these Swiss Army knives. They are sharp, hold their edge, and very convenient to have.

You see a Leatherman Blast next to it. I guess I got in by the hype. There's no question the metal in Leatherman Blast is good. It may even be better than the one in Swiss Army Knife. However, I think they ignore usability issue. Pulling out the blades and other tools are rather painful, and not at all easy. The plier is nice, and the tool selection is fine. However, pulling those tools out is ridiculously hard when compared to Swiss Army Knife.

Am I being spoiled? I don't think so. Gerber makes a good one and it's easy to use. So, for multi-tool needs, I first go to SAK, then Gerber. If it's not convenient, I'd rather not use it.

Saturday, August 24, 2013

Raspberry Pi Journal #10

Book Making with Thermal Binder

Last Journal, I showed you how I made some books with laser printer, stapler, and a roll of duck tape. This time, I showed you how I do the same thing, but with a thermal binder.


The model I use is Fellowes Helios 60, which as I understand it, a step up from the cheapest model. This model is more solidly built, and I'm glad I have it. First you turn on the device from the power switch in the back. Then, when you're ready to bind, you push the power button on the front. When the status light turns green, you're ready to bind.



The device has a springy clamp to it. It automatically adjust to the thickness of the binder. It's all very easy and convenient to use.



The device has a chart printed to tell you how long the thermal process should take. It also has a stair-case ruler that lets you slide the binder to see which of the setting should be used. I hardly ever do that since it has automatic sensor on the device.



The binder has 3 strips of glue. Strange that they are along the spine. I thought it would be crisscrossing the spine. But it works fine. I don't have the really thick spine, but I think the thicker the spine, the wider the glue strip in the middle.



The paper must be perfectly aligned! Once I square them, I like to run my finger along the paper to make sure that the paper is one solid block. Then I slip the cover, and run my finger again to make sure. I can't emphasize this enough. Everything must be square. There isn't much glue to bind the paper if a few sheets are misaligned, even by a millimeter.




Once the binder is in place, just hit the OK button. The timer is set automatically. Sometimes, I manually adjust the timer to one level more. It adds 10 seconds to the time.



There's cooling rack in the back of the device. It's really very convenient to use. Sometimes, though, the paper would bend, so it's a good idea to put some solid backing on it. The binding is really tight, and unless the papers are misaligned, it's pretty solid.

I printed a few bound book this way. Mostly some instructional pages. The cover is transparent, so I can print out a cover sheet no problem. Did I say it's convenient? It's very convenient!



Saturday, August 17, 2013

Petit Computer Journal #10


Graphics and Paint


We are going to go ahead and do all the graphic routines. I think the best way to do it is to just make a paint program. It won't be the prettiest paint program ever, but it'll do to make us understand how the graphic works. For the interface, I'll use Directional Pad for choosing colors and Tools. Touchscreen is for drawing. Turn the panel off by PNLTYPE "OFF"

'SHAPE MAKER
ACLS:GPAGE1:PNLTYPE "OFF"
S=0:MAXS=12:

S is current shape number. MAXS is Max shape number. Starts with one, and as time goes on, keep increasing it.

@LOOP
GOSUB @DT
VSYNC 1:B=BUTTON(3)
IF B AND 1 THEN C=(C+1)%16
IF B AND 2 THEN C=(C+16-1)%16
IF B AND 4 THEN S=(S+MAXS-1)%MAXS
IF B AND 8 THEN S=(S+1)%MAXS

X=TCHX:Y=TCHY
FOR I=1 TO 1:I=!TCHST:IF I==0 THEN GOSUB @SETR:GOSUB @DRAW
NEXT
GOTO @LOOP

The interface routine is simplicity itself. Basically, either use the directional pad to change color and shape, or detect Touch screen for drawing. This is done simply because it was done spontaneously while waiting for something. I added the number of shapes gradually over time.

@DT
CLS:COLOR 0
?"COLOR=";
GPAGE 0:GFILL 50,0,100,50,C:GPAGE 1
LOCATE 0,10:?"SHAPE=";
IF S==0 THEN ?"CIRCLE"
IF S==1 THEN ?"LINE"
IF S==2 THEN ?"BOX"
IF S==3 THEN ?"FILL"
IF S==4 THEN ?"LINETO"
IF S==5 THEN ?"PAINT"
IF S==6 THEN ?"PSET"
IF S==7 THEN ?"PAINT BORDER"
IF S==8 THEN ?"AIRBRUSH"
IF S==9 THEN ?"AIRBRUSH STENCIL"
IF S==10 THEN ?"PSET STENCIL"
IF S==11 THEN ?"HEAVY AIRBRUSH STENCIL"
RETURN

This is to draw the top screen, showing the color and the shape tools. If the selection is somewhat random, it is because I add to it random. The first four was done immediately. Then I add LINETO. PAINT,PSET follows. PAINT BORDER because I want to learn how to use it. The rest is my desire to add stipling to the graphic.

It is actually an improvisation. A good way to do it is using ELSE-IF ladder. A better way to do it would be using Array. The best way to do it is by using Graphics, icons, and highlights. I'm not going to do that for now.

@SETR
DX=TCHX-X:DY=TCHY-Y
R=SQR(DX*DX+DY*DY)
RETURN

Set Radius. This is used for CIRCLE.

@DRAW
GCOLOR C
S=S%MAXS:ON S GOSUB @CIR,@LIN,@BOX,@FIL,@LI2,@PAI,@SET,@BOR,@AIR,@STE,@PST,@HAIR

It doesn't get any simpler than that. Who knew computer programming can be so easy? I know I'm bucking the convention here, but I really don't think much about computer programming. Computer programming is merely the translation from English (human) language to BASIC (computer) language. It can be done mechanically. Design, which requires you to specify something that doesn't exists, is a much more challenging endeavour, simply because there is no way to be sure what you do is the best way to do it. You must experiments with different things.

I like to have 3 different solutions to the problem: A good one, a better one, and a best one. It has served me well throughout the years and something I suggest you adopt in order to expand your skills as computer programmer.

@CIR
FOR J=0 TO R:GCIRCLE X,Y,J:NEXT
RETURN

@LIN
GLINE X,Y,TCHX,TCHY
RETURN

@BOX
GBOX X,Y,TCHX,TCHY
RETURN

@FIL
GFILL X,Y,TCHX,TCHY
RETURN

Do I really need to explain these? They are self-explanatory. I will mention that loop for circle. The circle command isn't filled. I don't find much use for rings. I want circles. This is a design decision. So, I wrote it like that. Filled CIRCLE! It's not perfect, though, and you are encourage to fix it.

The color was set by GCOLOR C statement above. I could, and indeed, should, use the expanded command of specifying color at the end: GLINE X,Y,TCHX,TCHY,C on all commands. It's part of unifying aspect of the program.

@LI2
X2=TCHX:Y2=TCHY
GLINE X,Y,X2,Y2
X=X2:Y=Y2
RETURN

This is simply connecting line. If you look at the Touch screen code above, you will see that the last point of the line becomes the first point of the next line. Easy as pie!

@PAI
GPAINT X,Y
RETURN

@SET
IF TCHST==1 THEN GPSET TCHX,TCHY:GOTO @SET

@BOR
GPAINT X,Y,C,C+1
RETURN

GPAINT is easy enough. How about @BOR? That's GPAINT with border. I want to see how the paint functions with border color specified. Here, I specified C+1 as the border. Obviously, you can specify any color you want as the border, not just the next one.

Regarding GPSET, I put it in a loop because I want to do stippling technique. No mystery there.

@AIR
FOR W=1 TO 200:NEXT
IF TCHST==1 THEN GPSET TCHX+(RND(17)-8,TCHY+(RND(17)-8):GOTO @AIR
RETURN

@STE
VC=GSPOIT(X,Y)
@STE2
VSYNC 1:VX=TCHX+(RND(11)-5):VY=TCHY+(RND(11)-5)
IF GSPOIT(VX,VY)==VC THEN GPSET VX,VY
IF TCHST==1 GOTO @STE2
RETURN

@PST
VC=GSPOIT(X,Y)
@PST2
VX=TCHX:VY=TCHY
IF GSPOIT(VX,VY)==VC THEN GPSET VX,VY
IF TCHST==1 GOTO @PST2
RETURN

@HAIR
VC=GSPOIT(X,Y)
@HAIR2
VX=TCHX+(RND(11)-5):VY=TCHY+(RND(11)-5)
IF GSPOIT(VX,VY)==VC THEN GPSET VX,VY
FOR W=1 TO 200:NEXT:'WAIT AWHILE
IF TCHST==1 GOTO @HAIR2
RETURN

The @AIR airbrush is simple enough. There is a WAIT 200 cycles because if not, the pixels are sprayed remarkably quickly. Otherwise, it's just a random GPSET within a square.

@STE Stencil is the same way with the added factor GSPOIT() where VC is set to the current color. The pixel won't be plotted unless the pixel color is the same as the original VC.

@PST GPSET with Stencil. Enough said.

@HAIR Heavy airbrush. This is where I experimented the most. The discoveries found here was shared with other functions, notably the WAIT 200 cycles.

And you know what? The implementation of the program itself was really quick. So much so, in fact, that it was done while there was still waiting time. I spent the rest of the time doodling. Dogs, Flowers, People, and other sketches. It really works! It makes me wonder whether or not I should spend points getting The New Art Academy!

Haha, joking aside, I did do several renderings that I like very much. I experimented with saving the pictures. Not too successful, so I will need to revisit the issue in later journal. Until then, please have fun with drawing sketches, and share!

UPDATE:

I managed to implement LOAD/SAVE GRP files. Pretty simple. SAVE GRP0:filename (top screen). GRP1:filename (bottom screen). Also GRP2, and GRP3, for back buffer screens. I will give you the subroutine codes only. I assume you know how to integrate it to the program.

@BIG :'BIG LINE TO
X2=TCHX:Y2=TCHY
GLINE X,Y,X2,Y2
GLINE X+1,Y,X2+1,Y2
GLINE X-1,Y,X2-1,Y2
GLINE X,Y+1,X2,Y2+1
GLINE X,Y-1,X2,Y2-1
X=X2:Y=Y2
RETURN

@SAV
SAVE "GRP1:G0"
RETURN

@LOA
LOAD "GRP1:G0"
RETURN

Also, there's no reason why we can't have at least reasonable User Interface. Try this:

@LOOP
GOSUB @DT
VSYNC 1:B=BUTTON(3)
IF B AND 8 THEN C=(C+1)%16
IF B AND 4 THEN C=(C+16-1)%16
IF B AND 1 THEN S=(S+MAXS-1)%MAXS
IF B AND 2 THEN S=(S+1)%MAXS

That's right. We just exchanged the up/down with left/right. What does this change give us? How about this?

@DT
CLS:GPAGE 0

GFILL 0,160,255,175
GFILL C*16,160,(C+1)*16,175,C
FOR I=0 TO 15
GFILL I*16,175,(I+1)*16-2,191,I
NEXT

COLOR 0
LOCATE 0,0:?"ACTION"
?"   CIRCLE"
?"   LINE"
?"   BOX"
?"   FILL"
?"   LINETO"
?"   PAINT"
?"   PSET"
?"   PAINT BORDER"
?"   AIRBRUSH"
?"   AIRBRUSH STENCIL"
?"   PSET STENCIL"
?"   HEAVY AIRBRUSH STENCIL"
?"   BIG LINETO"
?"   SAVE GRP1:G0"
?"   LOAD GRP1:G0"

LOCATE 0,S+1:?">"

GPAGE 1
RETURN

Now the interface have gone from only a Dilbert nerd would tolerate, to the average programmer would tolerate. Quite a big difference with only small changes involved. Small, but significant changes. I made the mistake of coding a lot of PRINT, only to take them out once I realized this small change is all it takes. The lessons here are:

  1. Good is the enemy of Great
  2. Do not be afraid in discarding bad code!
  3. Think then Do. Do then Think results in a lot of time wasted writing and discarding bad code.


I would love to have zoom, but the whole interface must be redesigned. Maybe a speech balloon and layer option, hmmm?