Sunday, 17 July 2016

"Hello World!"....in Morse Code!



My forey into electronics! It's a simple setup, just some blinking lights. Really simple C code. This video was a bunch of colored lights blinking, but I was also playing around with getting the blinking lights to blink in Morse Code. It's not that hard, but getting the lights to blink once in C is like 5 lines of code or so. Then you have Morse, which is like 3 or 4 blink patterns per letter. Rewriting all that every time I want to test different phrases is tedious with so I wrote out an array in C of the Morse Code, and a Python file that will convert text I type in into something for Arduino.

----------------------------
import string, os
from os import path, listdir

class MorseCode():

    def __init__(self):
        self.MorseCodex = {'a':'alphaA ();', 'b':'alphaB ();', 'c':'alphaC ();', 'd':'alphaD ();', 'e':'alphaE ();', 
                 'f':'alphaF ();', 'g':'alphaG ();', 'h':'alphaH ();', 'i':'alphaI ();', 'j':'alphaJ ();',
                 'k':'alphaK ();', 'l':'alphaL ();', 'm':'alphaM ();', 'n':'alphaN ();', 'o':'alphaO ();',
                 'p':'alphaP ();', 'q':'alphaQ ();', 'r':'alphaR ();', 's':'alphaS ();', 't':'alphaT ();',
                 'u':'alphaU ();', 'v':'alphaV ();', 'w':'alphaW ();', 'x':'alphaX ();', 'y':'alphaY ();',
                 'z':'alphaZ ();', '0':'Null ();', '1':'Eins ();', '2':'Zwei ();', '3':'Drei ();', '4':'Vier ();',
                 '5':'Funf ();', '6':'Sechs ();', '7':'Sieben ();', '8':'Acht ();', '9':'Neun ();', ' ':'wordSpace ();', 
                 '.':'sentenceSpace ();'}

    def returnMorseCodex(self):
        return self.MorseCodex
 

class DirectoryInput():
    def __init__(self):
        self.dirInput='C:\\Users\\HP-OK\\Desktop\\MorseCodeConverterText'

    def formatDirPath(self):
        workDir=self.dirInput
        fLst=os.listdir(workDir)
        return fLst

class UserEntry():

    def __init__(self):
        self.engText = raw_input("Enter Your Text: ")

    def formatToList(self):
        lowerAllText = self.engText.lower()
        charList = list(lowerAllText)
        return charList

    #def tst(self):
        #self.testing = MorseCode()
        #return self.testing.returnMorseCodex()

class Converter():

    def __init__(self):
        userInput = UserEntry()
        dirPathInput = DirectoryInput()
        morseCodeLib = MorseCode()
        self.letterList = userInput.formatToList()
        self.dirPath = dirPathInput.formatDirPath()
        self.morseLib = morseCodeLib.returnMorseCodex()
        
    def convertEngToMorse(self):
        morseList = list()
        lineBreak = '\nletterSpace ();\n'

        for item in self.letterList:
            for key, val in self.morseLib.iteritems():
                if item == key:
                    morseList.append(val)

        convertedText = lineBreak.join(morseList)

        bseTemplate = 'void loop() {\n\nplaceholder\nletterSpace ();\n\n}'

        if 'placeholder' in bseTemplate:
            self.newTemplate = bseTemplate.replace('placeholder', convertedText)

        for fname in self.dirPath:
            f_open=open(fname, 'w+')
            f_open.write(self.newTemplate)
            f_open.close()


myString = Converter()

myString.convertEngToMorse()

    
----------------------------


Windows Batch Rename

There are numerous window tools out there that allows you to manage batch window files in the way that Linux does, and I didn't have to write this but I did anyway, for practice.

The main thing I learnt with this project is just how seemingly simple tasks can be difficult for the computer to implement, and by which I mean counting in this specific case.

It's not something you'd see often nowadays, but when you have long sequences of files numbered 1 - 100 for example, the computer is not going to number them 1 - 100 for you. It will be 1, 10, 11....19, 2, 20, 21.....and so on.

Given that in animation, numbering of the files are super important, if the batch renamer can't sort the files into a list naturally, then it's worse than useless. It would rename the number 10 frame as 2, and the number 2 frame as 10....So natural sorting turns out to be pretty tricky to implement. My original code just for natural sorting was about 40 lines or so and wonky, but I found an implementation using regular expression that was much simpler. Unfortunately, I could no longer remember where I found the code from so could not attribute it. In any case, the code comes below, runs off IDLE, and has no UI hahaha. The key portion for natural sorting is in the first 3 functions.

----------------------------
import os, string
from os import path, listdir, rename
from string import Template, zfill
usrInput=raw_input("Enter directory pathway: ")
workDir=usrInput.replace("\\", "\\\\")
fLst=os.listdir(workDir)

def tryint(s):
    try:
        return int(s)
    except:
        return s
       
def numeric_key(s):
    import re
    return [tryint(c) for c in re.split("([0-9]+)", s)]

def natsort(Lst):
    fLst.sort(key=numeric_key)
   
natsort(fLst)
print fLst

def srep():
    nWord = raw_input("enter new name: ")
    old = raw_input("enter old name: ")
    if len(old)<1:
        print "no entry detected, try again"
        exit()
    for item in fLst:
        original_file=os.path.join(workDir, item)
        if old in original_file:
            base, ext = os.path.splitext(original_file)
            newFile=item.replace(old, nWord)
            os.rename(original_file, (os.path.join(workDir, newFile)))
            print '{0} --> {1}'.format(item, newFile)

       
def rname():
    count = 0
    class BatchRename(Template):
        delimiter = '%'
    usrInpFmt=raw_input('Enter rename style (%d-date %n-seqnum %f-format):  ')
    pad=int(raw_input('Enter padding: '))
    start=int(raw_input('Start From?: '))
    fmt=usrInpFmt+"%n%f"
 
    t = BatchRename(fmt)

    for i, filename in enumerate(fLst):
        original_file=os.path.join(workDir, filename)
        count=start+i
        base, ext = os.path.splitext(filename)
        newName = t.substitute(n=string.zfill(count, pad), f=ext)
        os.rename(original_file, (os.path.join(workDir, newName)))
        print '{0} --> {1}'.format(filename, newName)

style=raw_input("function type? 1) search and replace 2) rename _ ")
if style is "1":
    srep()
elif style is "2":
    rname()
else:
    print "function not within call"
----------------------------

Saturday, 16 July 2016

Stop Watch!

Code

This was an assignment for the Python Course I took on Coursera, Interactive Python Programming. It's written in a web-based Python shell called CodeSkulptor developed by the course instructors, and comes with some of Python's libraries as well as some gui commands built into it. It's a simple game where you hit the stop button just as the clock hits the second mark. You can run it by hitting the play button at the top left hand off the page.

Anyone who knows about computers will likely know that that computers don't keep track of time in minutes and hours. Instead it's just one giant chunk of miliseconds. So one minute is 60 seconds*10 miliseconds.

One way I could have solved this is to write some long tedious if/elif loop, where I say something like:

----------------------------
msec = total_time%10

if msec == 10:
    msec_counter = 0
    sec_counter = 1
    if sec_counter == 60:
        sec_counter = 0
        minute_counter = 1
----------------------------

and so on for hours and days. Personally, I don't like code with too many nested loops, because it's hard to read, and logic errors can crop up easily. It also makes it challenging to edit later. Instead, I like to use functions to break up the computations.

I looked for other ways to implement this, and this is where I think I fell in love with using mathematics to implement solutions. I could do this in a much clearer way (to me at least) then writing long-winded loops with the added bonus that I can use that function later on.

This is the implementation I ended up using:

----------------------------
def format(t):
    # using euclid division a = bq + r
    # where a = t, b = 600(60 secs)
    # q = minutes(t/b), r = remainder
 
    def euclid_division(t):
        r = t-600*(t/600)       # collapsed equation using a = bq+r
        return r                      # we want to find remainder (r), therefore
                                          # the new equation is r = a - bq
                                          # where a is t, b is 600, and q is quotient
     
    def euclid_division_min(t):
        r = euclid_division(t)     # collapsed equation from a = bq+r
        loc_min = (t -r)/600       # we try to find out how many minutes given t deciseconds
        return loc_min               # so new equation is q = (a - r)/b
                                               # where a = t, r is derived from function euclid_division(t)
                                               # and b is 600. q is given "loc_min" as variable name here
                             
    # declare global variables
    global decisec                # declared global var for later use to keep score.
    decisec = t%10              # decisecond portion easily found with modulo.
    # local variables
    sec = euclid_division(t)/10
    min = euclid_division_min(t)
 
    if sec < 10:                      # if string.zfill() function exist, would be a lot simpler
        sec = "0" + str(sec)     # but since it's not loaded, longer, clumsier way neccesary

    if min < 10:
        min = "0" + str(min)
     
     
    return str(min) + ":" + str(sec) + "." + str(decisec)
----------------------------

The solution I happened upon uses euclidean division, a = bq + r. Within this equation are all the ingredients I need to find the second, minute, hour for implementing the clock. We can find the msec portion with modulo, and the second/minute portion can be found with the two functions euclid_division() and euclid_division_min().

Wednesday, 1 January 2014

Zhouzhuang - Environment modeling and texture

Hey all, been a VERY long while since I updated and the reason is, I was working fully on this, and stopped sculpting for a bit. Modelled in Maya, textured with Photoshop and Mari. Rendered with mental ray. HDRI setup done with the excellent, excellent loader script sIBL from HDRLabs! Some touchups in photoshop, because my gamma is wonky. 

Still a LOT of room for improvements, especially with lighting, but I'm pretty happy with this because it's a big step for me, having never modelled, textured, lit AND render a full set before. Hopefully there will be another leap next time!




Here are the model and wire renders!




Cheers, and happy 2014!

Saturday, 20 July 2013

Creature Entry VIII

Due to moving to a new country and starting a new job, I haven't been able to update anything for quite a while. Here's my latest entry.



This was VERY challenging to do..........


Orthographic:




*base mesh made in Maya, sculpted in zbrush, rendered passes from zbrush, painted in photoshop.

Saturday, 4 May 2013

Creature Entry VII

Experimenting with a much more painted style.....




Orthographic views:




End painted result feels really far from the sculpt though....have to rethink this. And yes, I missed the ears on the sculpt heh.



*base mesh made in Maya, sculpted in zbrush, rendered passes from zbrush, painted in photoshop.



Sunday, 17 March 2013

Creature Entry VI

Homonculus. A familiar, constructed by a demented wizard, kind of thing. Been hectic lately, trying to get back to the groove of concept sculpting!




Orthos:




*base mesh made in Maya, sculpted in zbrush, rendered passes from zbrush, painted in photoshop.