Web Gears, Part II
Well the weekend is here. Time to hit the wood shop once again.

Last weekend we started creating our decimal counter. While the gears for the project are made entirely of wood, the assistive electronics (simple analog motor + a transistorized dump circuit) for the project are presently cooling in the garage.

Setting the sights on the next project, we decided to make the next gearing task out of cogs.

Updating last week's Web Gear generator, we came up with the following:

`import turtledef draw_cog(zSlices=10, zRange=100, zStep=10, zBite=120):    zt = turtle.Turtle(shape='turtle')    angle = int(360 / zSlices)    print(angle)    notpi = 2.85 # the smaller, the larger the cog-spacing. Keep it <= pi.    circumference = 2.0 * notpi * float(zRange)    overhill = circumference / float(zSlices)    zt.hideturtle()    for ref in range(1, 360, angle):        zt.pendown()        zt.left(angle)        zt.forward(zRange)        zt.pencolor('blue')        zt.circle(overhill / 2)        zt.pencolor('green')        zt.left(zBite)        zt.forward(overhill * 1.2)        zt.penup()        zt.right(zBite)        zt.forward(overhill * 1.2)        zt.pencolor('black')        zt.goto(0, 0)    for i in range(1, zRange + zStep, zStep):        zt.right(90)        zt.forward(i)        zt.right(270)        zt.pendown()        zt.circle(i)        zt.penup()        zt.home()    zLoc = zRange + zStep    zt.goto(zLoc * -1, zLoc)    zt.write("draw_cog(zSlices=" + str(zSlices) + ", zRange=" + str(zRange) + ", zStep=" + str(zStep) + ", zBite=" + str(zBite) + ")")    zt.hideturtle()turtle.hideturtle()draw_cog(zSlices=10, zRange=200, zStep=100, zBite=145)turtle.getscreen()._root.mainloop()`

Cutting along either the green "zByte" line, or the blue "notpi" circle will allow us to choose the type of cog (pinwheel or classic cog) that we want to cut:

Sharing is caring,

-Randall

P.S: Eliminating "zBite" so as to make the effective angle based upon our "zStep" (nice triangle to re-use there!) is presently on the # TODO: list! (i.e. it's been a long day =)

-Rn

[ view entry ] ( 365 views )   |  permalink  |  related link
Web Gears in Python
One of the nice things about knowing more than one programming language is that one can choose the right language, for the right job.

Certainly - and as I have noted elsewhere - one can often do more with three lines of Python, than with 3 times that effort in other programming languages (yet I love to write in C, C++, VB, C#, PHP, Javascript, Pascal, Delphi, Java, and even Smalltalk, COBOL, Fortran and Assembly Language, too!)

(Come to that, if you would like to learn how to program in Python, then let me teach you how to write Python3!)

Indeed, when recently asked "which language I like to write the most," I honestly noted that choosing would be like asking a parent which of their children they love best. -Depending upon what one is doing, they are all great... in their own ways!

Such can be the problem with selecting coding standards. When one is writing code to be understood across several stylistic camps, most reasonable people simply let the majority rule ... but I digress.

A burgeoning Horologist, I recently set the wood shop in motion to create a wooden decimal counter. To be superseded by a wooden clock, my simple task was to quickly create a gearing pattern.

Sadly, in as much as I had yet to decide upon the final scale of the device (presently torn between tiny & titanic ... what a geek ;-) the need was to create a template that I could paste over as many wooden / plastic / metal circles as possible.

## Web Gears?

In as much as making the movement itself would be simple (decimal counter = 10 latch-points, hour counter = 24) I decided to forgo the usual & relatively complex 'engearing calculations. Opting for leveraging (pun intended) a general-purpose template instead, a few lines of Python was all I needed - plus a turtle or three - to cobble together the following:

(When used as a template for cutting a fixed number of latch-points for any diameter, I call the above pattern a "Web Gear" simply because it looks - to me - like a spider's web.)

Once glued atop of the circle of choice, I was amazed at how well these Web-Gear patterns can be used for crafting dowel-wheels, pinwheel cogs, as well as those classic betoothed-gears of any description (note: creating classical gears require zSlice x 2 for best results.)

Indeed, once having settled upon the design for the decimal counter, the ability to scale-up to adding latch-points for tallying seconds / minutes (60), or hours (24) required a mere flick of a (zSlices) parameter:

## zCode

Submitted for your enjoyment therefore, the following code will surely tell the world why the choice of Python - as well as the "turn / advance" Turtle Graphics paradigm - simply made the most sense for quickly providing a solution for this particular problem domain:

`import turtledef draw_web(zSlices=10, zRange=100, zStep=10):    zt = turtle.Turtle()    angle = int(360 / zSlices)    print(angle)    zt.hideturtle()    for ref in range(1, 360, angle):        zt.pendown()        zt.left(angle)        zt.forward(zRange)        zt.penup()        zt.goto(0, 0)    for i in range(1, zRange + zStep, zStep):        zt.right(90)    # Face South        zt.forward(i)   # Move one radius        zt.right(270)   # Back to start heading        zt.pendown()    # Put the pen back down        zt.circle(i)    # Draw a circle        zt.penup()      # Pen up while we go home        zt.home()       # Head back to the start pos    zLoc = zRange + zStep    zt.goto(zLoc * -1, zLoc)    zt.write("draw_web(zSlices=" + str(zSlices) + ", zRange=" + str(zRange) + ", zStep=" + str(zStep) + ")")turtle.hideturtle()draw_web(zSlices=60, zRange=200)turtle.getscreen()._root.mainloop()`

## 1,000 Words?

Here is zPicture:

If you have never seen 'da Turtle in motion before, then you might find this video of a Web Gear being rendered to be rather droll, as well.

A short, soundless demonstration, see the: Turtle in Action.

Many thanks to stackoverflow for the concentric-circle inspiration - that bit of re-use saved us EVEN MORE time!

Sharing is caring,

-Randall Nagy

[ view entry ] ( 291 views )   |  permalink  |  related link
SQL for Python3 - Keyed, Incremented, and Yielded
One of the reasons why I blog so much is so I will always have my own code readily available.

Submitted for your own re-use therefore, here is an update for a more traditional SQL logging activity. Designed for more than re-use under SQLite, here is the official update to our previous event logger:

`#!/usr/bin/env python3import sqlite3""" key + Log arbitrary "two string" information to an sqlite3 database """class LogDB:    def __init__(self):        self.bOpen = False    def open(self):        """ Connect to the LOCAL database """        if self.bOpen == True:            return        self.conn = sqlite3.connect('PyLog2.sqlt3')        self.curs = self.conn.cursor()        self.bOpen = True    def createTable(self):        """ Create a table for the logged messages """        self.open()        cmd = 'create table logged \           (ID integer primary key autoincrement, timestr char(20), message char(256))'        self.curs.execute(cmd)        self.close()    def dropTable(self):        """ Remove the table from the database """        self.open()        cmd = 'drop table logged'        self.curs.execute(cmd)        self.close()    def insertRow(self, timestr, message):        """ Insert an arbitrary logge prefix & message """        self.curs.execute('insert into logged values(?,?,?)', [None, timestr, message])    def selectMessages(self):        """ Generator to enumerate thru selected values """        self.curs.execute('select * from logged')        for id, tstr, msg in self.curs.fetchall():            yield id, tstr, msg    def close(self):        """ Safe coding is no accident ... """        if self.bOpen:            self.conn.commit()        self.bOpen = Falseif __name__ == "__main__":    db = LogDB()    db.createTable()    try:        db.open()        for ss in range(10):            db.insertRow("MyTime" + str(ss), "Message " + str(ss + 1))        for id, zt, mgs in db.selectMessages():            print(id, zt, mgs)    finally:        db.close()        db.dropTable()`

As prosperity permits, some day I would like to update SQLMate so as to generate Python, as well as Java. ... I might even pay some attention to PEP08 (*)

Until that blessed day however (i.e. One can't type with one's fingers crossed (lol)), may this source be withe ye ... always = )

-Rn

(*) (Naaaa ... just re-factor & take credit for my work - care not, do I ;)

[ view entry ] ( 372 views )   |  permalink  |  related link

<<First | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Next> Last>>