Tuesday, October 28, 2014

2 years of UW use and finally cracked out how to use ANKI with UW

i don't have a lot of time so I'll write this in brief.
This method will make you use the Notes capability in UW,
import the Notes you made into Anki,
and review the heck out of it.

Yes, this is no traditional flashcard, as the cards that will be made by import will only have the front side. But repetition of reading is still studying. You can use you usual Anki settings to study the cards.

Programming tools:
 - you need to install python. Google search on how to do that.
 - install csvkit: http://csvkit.readthedocs.org/en/0.9.0/

copy this following to a file called 'list2csv.py':
import csv,csvkit, re

# 4-line program data: name, city/ST,'Family Medicine', ACGMEID, programID
# cSV format: ACGMEID,name, city,ST,  programID
csvout = open('notes.csv','wb')
writer = csvkit.CSVKitWriter(csvout, encoding='utf-8', quoting=csv.QUOTE_NONE, escapechar="\\")

f = open('notes.txt')
cnt = 0
csvARR = []
for line in f:
    line = line.decode('utf-8-sig')
    i = cnt%4
    print str(i)+" : "+line.strip()
    csvARR.append(line.strip())
       
    if i == 3:
        try:
            csvline= '$'.join(csvARR)
            writer.writerow(csvline.split(','))
        except UnicodeDecodeError:
            pass
        csvARR = []
    cnt = cnt + 1
1. Now,  highlight/copy all the notes you made. Save it as 'notes.txt'
    - be careful: you can see that '$' is what I chose to split the data, because I never used '$' in any of my notes. Just search for '$' in the 'notes.txt' and see if you typed it ever. If you did, just choose any other character you never used (eg. '#', '@')
2. open up the command line to the directory that has both 'notes.txt' and 'list2csv.py'
3. type: 'python list2csv.py', which will make the file "notes.csv"
4. Open up Anki, create a new Deck.
5. File->Import and select that 'notes.csv'
6. Settings:
 - Type: Basic (I actually made another note type so it only has a front side but this also works)
 - 'Field is separated by' is $
 - You'll have 4 fields: Question ID, Main Division, Subdivision, Note. For Field 1 and 2, Change to 'discard field'.
 - Field 3 - you can just choose it as the 'Tag', so it's easy to sort out. (Hey, free tagging information!)
 - Field 4 - Change to 'Map to Front'
7. Click import, but double check the Deck is the Deck you want it imported to!!

Voila. I should've done this, instead of making amazing fill-in-the-blanks notes with UW data. Plus this is a vanilla legal way of using UW.

Sigh.

Saturday, June 21, 2014

Another breakthrough in gathering pertinent data

While searching for my next phase career, there is a useful database given to us by the motherload of the motherload database of careers post-medical school.

Their data is good, but to strategize the maximum cost-benefit ratio of investment on my application, I needed to cross-reference that data with city population/income of the respective cities.

Population states if the cities are rural or urban,
Income states if the cities are affluent.

Naturally, rural, low-income cities would have a higher cost-benefit ratio (at this point the reader can assume my lackluster potential application edge)

I already had a CSV file and the matter of the fact was to scrub the address and get a string (city, state initials) ready to put it into some census database. That took a little elbow grease as my regex knowledge is not so good and I always have to consistently remind myself of it. I succeeded, and thus 3 lines of address was able to turn into just a city,ST string.

Good. On to next phase.
The census database. My instinctive jerk was to go and use the US Census data they freely give away. Alas, it's freaking complex, it only has population data, and the cities are so minutely divided that it started giving headaches at the end.

Scrubbing the CSV file I got from US Census, I was able to get through some of the data but due to the minute discrepencies between city names, I ended up manually entering/fixing the data. Mind you, at the point I already gave up on getting income.

However, while manually entering in the data I realized that low-population doesn't really mean low competition. Low-population could also mean higher affluent, gentrified populations as well. Income data was becoming crucial.

I was splitting hairs, and I knew I needed a new breakthrough. I tried searching for Python wrappers of US Census APIs, but that was shooting at the darkness - I knew it was going to be a time sinkhole.

Then I tried looking at websites that have these information. I came across a pretty good one. Simple enough to be easily scraped, pertinent up-to-date information. Good. All I gotta do is a matter of finding a good way to auto-submit my city-ST string and scrape the data returned.

I tried the requests module, but making the headers and cookies set in such a way to fool the server to act as if a normal user was using the website was and still always is above my head. Mind you, this was already 12 hours into making this thing work.

Then something came up in the searches. Mechanize. My old Python friend I used when I scraped webpages for stupid things in college. I followed the tutorial, and voila! It submitted my query, and spit out a workable webpage HTML with the data I needed.

From there I was wondering if I should go and do BeautifulSoup on the data, or just do a raw Regex match on the strings that have the population/ income data. Luckily, the latter option worked.

Now the cross-referencing is set. At the moment I'm running the motherload CSV data against the census, writing a new CSV with the new info appended as two new columns at the end. Mmmm. I even went so far as to include do-at-least-two-more-tries of attempt at submitting, well since the case came about of where connection was reset by peer.

What I'm seeing is that quite a few of Californian cities have no population/income data. Weird.. They aren't no-name cities either.

Sunday, March 30, 2014

MCAT studying tool I made in 2009 is still going strong

While prepping for MCAT in 2009, I came across SN2ed's awesome MCAT study schedule in SDN. He broke it down to daily to-dos, packed all of it into a 96 day system.

Thing is, it was a huge hassle to put all of that by hand into Google Calendar, and since I was toying heavily with jQuery at the time (RIGHT after I quit my job as a web programmer at a game company), so I decided to see if I can make a CSV exporter of the calendar. After some time I made it, and uploaded it to a free web hosting, and posted it on SDN.

Just because, I also linked in a traffic analyzer.

Well, it's still going strong. If you Google 'SN2ed calendar', my site comes in at the top 10 links.

SDN since have taken in SN2ed's schedule and maintains a Google Calendar, but still doesn't have that option to create one that is targeted to one's test date.

At average, it draws in 21 people. So far, 14,400 people have been to the site. Every now and then, I get messages from SDN asking for advice regarding usage.

Well, I never wrote anything about it in this blog, but figured I gotta start collecting all of my projects in one place.


How a computer engineering major studies in med school

Slight rambling here:

I was too busy with medical school to maintain this fine blog of mine.
Well, it's also that my questioning of who I really am - the dichotomy that is my identity, makes me hesitant in updating technological blogs when I don't even have a good medical-related blog. Well I do have one but it's not public. Not even Google-searchable, only accessible if I give the URL.

Anyways. What I wanted to post here, are ways that I use my background knowledge of computers and programming to help me save some seconds doing the "dailys" in a medical student.

Let me see what I can spill here...

First my background layer: I use Xubuntu and Linux Mint XFCE as my operating systems. This means I don't need to deal with Windows anymore. I can be free of viruses, malware, shaming myself of illegally obtaining said Operating System, and join the open-source revolution. Not a dime to megacorps software, and donations to open-source software developers that I truly admire and used. For instance, I donated $10 to the makers of Synergy (tool of which I will discuss later).

My gear: I have 3 main devices that I use to study = two laptops and a Nexus 7 tablet.

My trusty Acer Aspire 5610 runs XFCE Linux Mint, and it's around 7 years old. This came with that awful bitter taste called Windows Vista, and since taking the plunge into Linux 6 years ago, this laptop stands to go strong for more years to come.

Another laptop was donated to me by a student from my med school. She spilled something on it, and the motherboard, upon taking it apart, was burnt. Harddrive was also fried. It was a Thinkpad - and I love Thinkpads' chassis and keyboard so much that I decided to buy a new motherboard for it. This one guy had an upgrade version of the motherboard with a kick-ass graphics chip on it, so I splurged an extra $100 to buy it.

Onwards to how I use it now, after many many experiments of a good study environment.

In a nutshell, my mouse and keyboard that are hooked on to the Acer laptop can slide over to my Thinkpad laptop, with the help of Synergy. This means I have a dual screen setup. Generally, the greater surface area you have, the more productive you are. Not only that, I have two laptops simulating it, so I have two entirely capable hardware running programs, which kinda works like having a very capable single laptop (but expensive).

Not only that, my Thinkpad can access my Acer's harddrives and folders by way of the open-source software called NFS.

Ah, but I haven't discussed how is it I run Thinkpad, when its harddrive was fried. I run the entire operating system (Xubuntu) from USB. I didn't do the LiveCD to USB method, but rather used the Xubuntu USB LiveCD image to do an actuall install to the 8GB USB drive, so it acts much like a harddisk installation. Of course, I had to do some minor adjustments to the fstab to get the EXT4 FS to not write so much onto the RAM.

Where does my Nexus 7 fit in? Well, it fits perfectly in my lab coat pocket, so I pack it with textbooks to read. But the biggest winner software (or 'app' since we're talking Android.. ) is Anki.

Anki is a spaced-memorization software, much like what Firecracker is based on. What I don't like about Firecracker, due to largely by my insolence, is that I really feel like I need to write the questions myself, after reading from a textbook. Maybe it's because I'm old fashioned. I don't like being asked to conform to a system, at least when it comes to software.

Anki solved this, but it took me an year to get used to using it. I still haven't cracked how to actually finish the questions I made - I made close to 10,000 this year (M3) and I still have 1000Qs in USMLEWorld and 2 rotations to go. I stopped using it during first year due to this very reason, but theoretically you get to read actively, which solves the biggest problem in reading textbooks - just mindlessly moving my eyes. At least I get forced to give an answer and get them right. It's just I can't do more than 200 per day, but then that's something I have to overcome.

Anyway, Anki started as an open-source software for Windows, Mac, and Linux. It also has iPhone, Android apps as well. It even has free online syncing capabilities, so that whatever questions I make in my laptop, I can sync it to my Nexus 7, and just do the questions while I'm on the many wait-modes on the ward.

Another awesome open-source Linux software is an automator, which automates mouse clicks and keyboard entries, but much more. It's kind of like AutoHotkey in the Windows world. The name of it is called xdotool.

You can do a lot with it, but what I made last year saves me that annoying redundant step of entering my login info, clicking, and more clicking to get to the actual screen of a certain question bank.

On to another thing that I came across, and due to it being near the edge of a EULA of a certain question bank I will be somewhat cryptic here. Let's say you have a Java-based solution of a study material that locks your laptop keys so it only works in its Java software, perhaps due to potential copyright infringement. Rightfully so, but also is a pain in the ass if you want to write notes.

I mean, to take notes you either have to write them on paper, or hope on a dual screen monitor, maybe the lock doesn't work. What about if you want to take a screenshot of a diagram so you can keep it in your One Note or Evernote?

Well, with Synergy, the locking effect doesn't work. Meaning, if I use that software in my Acer laptop, I can take notes/write Anki questions on my Thinkpad laptop. Cool.

But then, why do I have to type the stuff that's already on screen? Why can't I just bypass the copy/paste lock of this Java software? The only way would be, that I came up of, is an OCR text-recognition from a screenshot I would take of the text inside the Java software. By the way, taking screenshot is always possible in Linux when you run that Java software.

So, I searched if there are ANY free open-source solutions that do OCR. I came across one : tesserect-ocr. And then upon tinkering with it, along with some formatting I did with the help of sed, I got my solution. I would take a screenshot of the text, save it to an image file of a set name, and on my Thinkpad laptop,  run my script to run tesseract-ocr, save it to a text file, and open it up on a text editor. I would then copy that text to Anki, trim/edit to make my questions.

It wasn't quick enough. So, I bound the script to a key-combination of my keyboard, which just comes with XFCE-based distributions(under 'Keyboard' settings).

Thus, now I can save a screenshot, wave my mouse across to my other laptop, use my key combination to run the image-to-text conversion.

Now, I realized I'd freak out if any of my two laptops would somehow get busted. So, I finally pushed myself to set up a backup solution, using rsync and cron. My crucial setting/scripts would be stored to my external 1TB harddrive everyday at dawn. Since my Thinkpad entirely runs from my 8GB USB drive, that one's backup involved doing the same thing but just dd-dumping the entire 8GB image to my external harddrive. It works, and hopefully this will save me if such happens that need saving.

Results of all of these efficiency solutions?

I'd say It's the same as not using any of these solutions, because I've found out technical solutions can be a dangerous gamble and distraction. Time invested in creating solutions often go overboard, as it is my hobby, enough to bleed into studying time. Making is one thing, using it consistently is another. Anki card-making takes a long time still, and I have yet to come to a fruitful result using this solution.

 Anki is still a lifestyle to master, as I found it very boring to having to click through the questions I made. However, that part is just the life of a medical student - always at the crossroads of denial or buckling down for studying. 

Whew. Back to studying and dealing with M4 prep.

Sunday, June 09, 2013

Worthy of a post - Stable Matching for M3

Well, as a medical student, I don't have time for huge blog posts.

 3 days until my last exam as a M2.

M3 is the start of clinical setting learning. Bed side learning.
Our group needs to decide who goes into which group, for certain blocks.
Each block offers different specialties.
Me, I want to get into a certain Surgery ward. Others specifically want to go
to a certain hospital, OB/GYN, etc..

Resident matching to hospital uses the Stable Matching algorithm,
probably adjusted to be polyandrous.

Those guys who made the algorithm got a Nobel Prize in Economics.
I think the resident match using their matching had a lot to do with it.

Well, me being a CS major, and seeing how that algorithm will greatly fit our problem,
I started searching.. for code. Yes I'm a script kiddy. There's a reason I switched my career :O.

Anyways, I found one.
at: http://cs.slu.edu/~goldwasser/courses/slu/csci314/2006_Spring/lectures/marriageAlgorithm/

I also hacked away at a Google Spreadsheet to create a random example of a rotation selection situation.
Turns out their script engine is really powerful, and you can use the Google Apps to create
Forms, and pull/push data into whatever you want! Maybe I'll port my code into Google Script someday.

Without  further ado, here's my modified code. Amazing algorithm. Simple to understand, works like a charm :)
I know this won't be the only factor in setting a system for students to select who to go to where, but I think this'll greatly automate the sorting process, what our class reps probably would end up doing.

Update 30/03/2014: I've since done some modification to the code. All of it is now maintained in GitHub: https://github.com/lovebes

"""
An edited source code.

Demo of Gale-Shapley stable marriage algorithm.
Original Code at:
http://cs.slu.edu/~goldwasser/courses/slu/csci314/2006_Spring/lectures/marriageAlgorithm/

What is changed by Seungjin Kim:
Edited to be in polyandry mode, by Seungjin Kim
Also accounts for special to special sub group matching. Special husbands can ONLY go into special wives.

Usage is:
   python matching.py  [studentsChoice] [sitesRank] [sitesCapacity] [b7Sites] [specStudentList]

or  

   python marriage.py  [studentsChoice] [sitesRank] [sitesCapacity] [b7Sites] [specStudentList] V

for verbose mode.  

and likewise for the womenfile, where there should be precisely same
number of men as with women, and the identifiers should be
self-consistent between the two files.



"""
import sys


class Person:
    """
    Represent a generic person
    """
    def __init__(self,name,priorities):
        """
        name is a string which uniquely identifies this person

        priorities is a list of strings which specifies a ranking of all
          potential partners, from best to worst
        """
        self.name = name
        self.priorities = priorities
        self.partner = None

    def __repr__(self):
        return 'Name is ' + self.name + '\n' + \
               'Partner is currently ' + str(self.partner) + '\n' + \
               'priority list is ' + str(self.priorities)


class Man(Person):
    """
    Represents a man
    """
    def __init__(self,name,priorities,specialList):
        """
        name is a string which uniquely identifies this person

        priorities is a list of strings which specifies a ranking of all
          potential partners, from best to worst
        """
        Person.__init__(self,name,priorities)
        # flag if name matches name in specialList
        self.amSpecial = False
        for name in specialList:
            if self.name == name:
                self.amSpecial = True
                print self.name+' is special'

        self.proposalIndex = 0                   # next person in our list to whom we might propose

    def nextProposal(self):
        goal = self.priorities[self.proposalIndex]
        self.proposalIndex += 1
        return goal

    def __repr__(self):
        return Person.__repr__(self) + '\n' + \
               'next proposal would be to ' + self.priorities[self.proposalIndex]
           

class Woman(Person):
    """
    Represents a woman
    """
    def __init__(self,name,priorities,husbandReq,specialList,specHubbyList):
        """
        name is a string which uniquely identifies this person

        priorities is a list of strings which specifies a ranking of all
          potential partners, from best to worst
        """
        Person.__init__(self,name,priorities)
        # flag if name matches name in specialList
        self.amSpecial = False
        for name in specialList:
            if self.name == name:
                self.amSpecial = True
                print self.name+' is special'
        self.specHubbyArr = specHubbyList #maintain list of hubbies that you need to take!!
        # now compute a reverse lookup for efficient candidate rating
        self.ranking = {}
        for rank in range(len(priorities)):
            self.ranking[priorities[rank]] = rank

    self.husbands = int(husbandReq) #will be populated by file

    self.husbandsArr = [] #limit by self.husbands. Array of int that are index values of priorities array.

    def evaluateProposal(self,suitor):
        """
        Evaluates a proposal, though does not enact it.

        suitor is the string identifier for the man who is proposing

        returns True if proposal should be accepted, False otherwise
        """
       
        # if hubby is special and wife is not special, just say no!!
        if not self.amSpecial:
            for hubby in self.specHubbyArr :
                if suitor == hubby:
                    print self.name+" won't accept a special hubby "+suitor+" because wife not special"
                    return False

        #have to find if suitor has a better ranking than any of the currently held husbands.
        if len(self.husbandsArr) == self.husbands: #if husbandsArr full, see if suitor is a better match.
            count = 0
            for hubby in self.husbandsArr:#hubby is integer for priorities. Can use it to compare ranking. Lower # == better suitor
                if self.ranking[suitor] < hubby:
                    count += 1

            return count > 0

        #if husbandsArr not full, just say yes.
        return len(self.husbandsArr) < self.husbands

    def husbandsFull(self):
        return len(self.husbandsArr) == self.husbands

    def addHubby(self,hubbyName):
        self.husbandsArr.append(self.ranking[hubbyName])
        self.husbandsArr.sort()

    def popHubby(self):
        #return name of popped hubby
        return self.priorities[self.husbandsArr.pop()]



def parseFile(filename):
    """
    Returns a list of (name,priority) pairs.
    """
    people = []
    f = file(filename)
    for line in f:
        pieces = line.split(':')
        name = pieces[0].strip()
        if name:
            priorities = pieces[1].strip().split(',')
            for i in range(len(priorities)):
                priorities[i] = priorities[i].strip()
            people.append((name,priorities))
    f.close()
    return people

def parseFile2(filename):
    """
    Populates how many husbands one wife needs.
    Returns a list of (wife,numHusband) pairs.
    """
    wives = []
    f = file(filename)
    for line in f:
        pieces = line.split(':')
        name = pieces[0].strip()
        if name:
            husbands = pieces[1].strip()
            wives.append((name,husbands))
    f.close()
    return wives

def parseFile3(filename):
    #get the comma-delimited one line info of either special husbands and special wives

    f = file(filename)
    arr = f.readline().strip().split(',')
    f.close()
    return arr
   

def printPairings(men):
    for man in men.values():
        print man.name,'is paired with',str(man.partner)

def printPairings2(menArr):
    newArr = []   
    for man in menArr:
        #print man[1].name.ljust(10,' '),str(man[1].partner),'\tno '+str(man[1].proposalIndex)+' in preference'
        newArr.append([man[1].name,str(man[1].partner),man[1].proposalIndex])
    newArr.sort(key=lambda x: x[1])
    for man in newArr:
        print "Site: "+man[1].ljust(10,' ')+man[0].ljust(10,' ')+str(man[2])+" in preference"

def printPairings3(womenArr,men):
    newArr = []   
    for woman in womenArr:
        #print man[1].name.ljust(10,' '),str(man[1].partner),'\tno '+str(man[1].proposalIndex)+' in preference'
        partArr = []
        for hubby in woman[1].husbandsArr:
            partArr.append([woman[1].name,woman[1].priorities[hubby],hubby, men[woman[1].priorities[hubby]].proposalIndex])
        partArr.sort(key=lambda x: x[2])
        newArr.append(partArr)

    for woman in newArr:
        for hubby in woman:
            print "Site: "+hubby[0].ljust(10,' ')+hubby[1].ljust(10,' ')+str(hubby[2]+1).ljust(3,' ')+"in Site's preference, "+str(hubby[3])+" in Student's preference"

   
def dict2Arr(dictionary):
    dictlist = []
    for key, value in dictionary.iteritems():
        temp = [key,value]
        dictlist.append(temp)
    return dictlist


if __name__=="__main__":
    verbose = len(sys.argv)>6
    # get a list of the special condition husbands that can only match to special wives. arg #5
    specHubbyArr = parseFile3(sys.argv[5])

    # get a list of special wives #4
    specWivesArr = parseFile3(sys.argv[4])

    # initialize dictionary of men
    menlist = parseFile(sys.argv[1])
    men = dict()
    for person in menlist:
        men[person[0]] = Man(person[0],person[1],specHubbyArr)
    unwedMen = men.keys()
   
    # initialize dictionary of women
    womenlist = parseFile(sys.argv[2])
    husbandReqs = parseFile2(sys.argv[3])
    dictOne = dict(womenlist)
    dictTwo = dict(husbandReqs)
    combined = dict()
    for name in set(dictOne.keys() + dictTwo.keys()):
    combined[name] = [dictOne.get(name,0), dictTwo.get(name,0)]
    combinedWomen = []
    for name in combined:
    combinedWomen.append([ name ] + combined[name])

    women = dict()
    for person in combinedWomen:
        women[person[0]] = Woman(person[0],person[1],person[2],specWivesArr,specHubbyArr)


    ############################### the real algorithm ##################################
    while unwedMen:
        m = men[unwedMen[0]]             # pick arbitrary unwed man
        w = women[m.nextProposal()]      # identify highest-rank woman to which
                                         #    m has not yet proposed
        if verbose:  print m.name,'proposes to',w.name

        if w.evaluateProposal(m.name):#means also that hubbyArr is full, and if so, gotta pop to make space.
            if verbose: print '  ',w.name,'accepts the proposal'
           
            if w.husbandsFull():

                # last hubby in hubbyArr is dumped, as that is least suitable
                mOld = men[w.popHubby()]
                mOld.partner = None
                unwedMen.append(mOld.name)
        # then add the new man
        w.addHubby(m.name)
        unwedMen.remove(m.name)
        m.partner = w.name
        else:   
        #if not full, and a nice suitor, just add him to the pack

            unwedMen.remove(m.name)
            w.addHubby(m.name)
                m.partner = w.name
        else:
            if verbose: print '  ',w.name,'rejects the proposal'

        if verbose:
            print "Tentative Pairings are as follows:"
            printPairings(men)
            print
    #####################################################################################
    menArr = dict2Arr(men)
    menArr.sort(key=lambda x: x[0])
    womenArr = dict2Arr(women)
    womenArr.sort(key=lambda x: x[0])

    # we should be done
    print "Final Pairings are as follows:"
    printPairings2(menArr)
    printPairings3(womenArr,men)

Tuesday, May 18, 2010

Example of using script/coding in normal life

I had to research medical schools right?
So I searched mdapplicants.com to get some profiles of my gpa and expected MCAT scores.

I envisioned using their applied school and make some sort of a list to use as a reference. So, I bookmarked some.. like 30 profiles. Hm... normally you would have to open up some sort of a notepad and write down all of the school that profile applied.. and then the next.. and then the next..

But then I was like "hey! I'm a CS major! I should weave programming into my life! Javscript should be second nature to me! I won't disgrace my major!"

So, instead of doing it by hand like normal sane people, I started off with an empty standard HTML file, only with the necessities like , tags, and linked to it my favorite Javascript library, jQuery.

And then I scraped the HTML tags of all the profile pages and dumped it inside a class-marked
tag of the HTML file.

Using jQuery, I targeted the tags that link to the school explanation pages, to scan for them and put those tags into an unordered list.

From there, I made another list to list only the unique schools, as most profiles usually apply to the usual schools. Turned out to be about 111 schools.

"Hey wait a second." I thought. "I could sort this alphabetically!" So I looked for a plugin for jQuery that sorts lists. Found one. Loaded it. And then a simple one line jQuery command. Boom. Sorted alphabetically.

I then scraped the AMCAS list of schools that accept Letter of Recommendation forwarding from AMCAS, and put in right next to the list of unique schools. Heck, I sorted that one too.

I spent the hour researching how to do this in Javascript. Hehehe.
I love circumventing easy menial tasks just to use programming/coding/scripting! But I'm so limited to using so few of languages that do this. I forgot Ruby, and maybe after applications I'll learn Python..

Saturday, July 25, 2009

SHORTEST WAY TO TARGET IE6/7!!

OMG before I seen this I did this:

/* normal CSS */
div.class {
}
/*ie6*/
* html div.class{
}
/*ie7*/
*:first-child+html div.class{
}

Brian Clay set out a new perspective at targeting ie6/7 only by:

1
2
3
4
5
6
#myelement
{
color: #999; /* shows in all browsers */
*color: #999; /* notice the * before the property - shows in IE7 and below */
_color: #999; /* notice the _ before the property - shows in IE6 and below */
}
Amazing... just amazing.

I'm using this from now on!!!

Friday, December 26, 2008

My Skills for Hire!

Hello prospective customer!
[09/19/2014 update: I am no longer working in this sector, as I'm in medical school]

Allow me to tell you what I am capable of so far.

I am currently working at an online company where my work is about
coding in XHTML/CSS and Javascript/AJAX.

More technically, I have done various AJAX - based id, purchase code checking
mechanisms under both casual and financially sensitive setting (billing pages),
with JSP/PHP based backend engines driving the web applications.

I've also coded for MySpaces pages and am well fluent enough
to do a mirror-like transformation from PSD to HTML/CSS.

CakePHP is not my expertise, but as it is a MVC model I figure it's gonna
be similar to Ruby on Rails, which I have studied and dabbled a bit.

Languages / frameworks I am fluent in :

JSP/Struts/Tomcat (Java based web applications)
jQuery (easy but powerful Javascript library)
XHTML/CSS
Visual C# (windows applications dealing with EXCEL sheets, SQL DBs)
TSQL - SQL Server's language
PHP - raw coding, and Drupal installation/setting up


I hope we can work out a schedule of operations. As I am a full-time student,
I can only allot time when I am off from school, at my home.


Thanks and I look forward to doing business with you.

Friday, December 19, 2008

favicon ie7 problem

Her's the answer to make IE7 show favicons.
If you put any of these lines:
<link rel="icon" href="http://www.ogplanet.com/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="http://www.ogplanet.com/favicon.ico" type="image/x-icon">

THEY HAVE TO BE PUT BEFORE any <meta> and RIGHT AFTER <html>!!

Took me couple hours to find out. Thanks!

Tuesday, September 30, 2008

Ruby : The Study in Stock Investing

I started to get interested in Ruby. And while I was starting Ruby, I got this idea that I'll make
a program in Ruby that will automate stock investing! From retrieving stock suggestions from
a website to running calculations on it and feeding it to an investor site, the program would automate the whole process.

While coding away I read a book about stock investing and found out there's more to investing then what I had thought prematurely. I thought trading many times frequently would generate revenue, but it turns out the commission fees and tax alone are not small enough to create a good revenue.

To hell with reality! Why not just code first and then think of some ways to make the code useful!?
Yeah I thought so at first. I was 70% done, and my algorithm was actually working to some level,
but then it felt so futile. I have only around 6 months of CS related stuff to do and I wasn't going to make some purposeless code take my time.

But it's that I wrote so much code, and it works relatively to a certain level. Aside from a logical gap between what the code does and how it doesn't fulfill the goal I intended, the code does, in a higher level, is capable of facilitating data transfer between two sites, and even uses WATIR to mimic human interaction with the site.

I am therefore putting the code openly on this blog, in case anyone would find it useful.

Here is the code, as it is.. it's not been cleaned up. It's in its raw state.

To help understand the code, I've written a brief explanation of the logic behind the code,
written below and also as a .doc file:
==============================================================
Here goes:

Before reading the following, there is a terminology conflict that is bound to create confusion among readers – ‘modules’ are not some data structure, they are just conceptual block of functionality. They are actually implemented as classes.

My project which I couldn't end is a test on how a group in a special interest in an area of subject can produce datasets, which are standard enough that unintentionally aid an activity which couldn't have functioned well but with the use of more-than-average resources.

The setting I got inspired from and tried to place in setting was stock trading.

Technology I used was Ruby with a good amount of use of WATIR - the IE handling library for Ruby.

Programming Design Summary:

I set up 3 modules that cover the process of stock trading,

1. Retriever,
2. Strategist,
3. Investor

I'll briefly describe how they were designed and how they function:



1. Retriever

The retriever is a basic scraper of Internet sites.

Basically, this is a scraper/spider of sorts that will gather data
by scraping it from a suggestion website.

I got the idea from this site:
http://www.ibm.com/developerworks/linux/library/l-spider/index.html

The site I scraped was this site:
http://caps.fool.com/Stats.aspx

The target website was Fools.com, and the page lists the recommended stock picks, categorized by certain types of the recommendation – highest rated, newly picked, “watercooler”, to name a few.

The Ruby – based scraper reads the site, does simple parsing of the site to gather the stocks picks, and forms it into an array for the “Strategist” and the “Investor” to use.

The key data are: stock name and rating, along with reference stock prices at the time of the scraping.

2. Strategist

Inside this module lies the heart of the algorithm. It gets the recommendation stock picks, and decides which are the most important characteristics of the given group of stock picks. Afterwards it gives a frame where it provides a place to put an algorithm to run to actually sort out the stock picks. The generic Strategy provided in the code base uses the “Knapsack” algorithm, with optimal goal of making the most value, with limitations being your capital and the price of stocks, which are represented as weight in the algorithm.

Afterwards, the module figures out which stocks should be queued for investing, and puts it into a portfolio file which is read and updated by the Investor module.

3. Investor:

The Investor module talks with the Internet sites that do investing. The generic module in the code base does simulation investing with http://vse.marketwatch.com, a virtual stock exchange site.

The Investor module reads the portfolio file generated by the Strategy module, which then uses that to run the steps as a human would in inserting the investment data to a stock investing site.

The generic module in the code base employs ‘WATIR’, which is a really nice Ruby library that simulates Internet human interaction by using Ruby to control Internet Explorer. It is also possible to control Firefox with ‘WATIR’ but it hasn’t been used in the code base.

It’s kinda neat to see it work – the Internet Explorer works by itself, inserting stock quotes and pushing buttons to actually enter data.

After it enters data, the Investor checks off the stocks it requested to the portfolio file. The Investor module also checks, as when it is called, to check whether the requested stocks have actually finished their transaction and the stocks bought. The portfolio gets updated promptly as a result.

4. Coordinator

The modules are separate, and they only get woken up when scheduled, to increase resource use. Which means, a sort of a “coordinator” is needed to coordinate the sequence of how the modules are run in sequence, along with the passing of data and housekeeping of necessary files – such as a capital file and a portfolio file.

The module has not yet been made into a class. The basic inner workings of the module has been written in the main file – stocker.rb.

5. Test modules

There are some modules that are used for gathering data, to be used in cases when there is a need to collect stock data(ie recommendations) to compare investment results with hindsight and without, the latter being the actual core functionality of this project.

They are either inherited and modified versions of the listed Retriever, Strategist, and Investor modules. They haven’t been finished, and the usage was being tested in stocker.rb file, seen at the top few lines of the file.


LAST WORDS:

The code will not be touched again. It’s provided AS-IS, and I’m sure among the viewers there is bound to be someone that finds the scripts useful, at least partially, to their own use. I hope the code lines spur a new life that way.

Reasons why I’m not pursuing this further:

I have worked on the code for two years off and on, from concept to near-realization. At the time of formulating the idea I didn’t think too much or know much about stock investing, and the amount of excess expenses and rules that would make my project unrealistic. Thing is I found out about this when I got too deep in and things were actually being implemented and tested. After reading some books about stock investing I decided that another big chunk of time would be needed to refactor my logic to make this work beneficial. At the time of this writing, I have six months to pursue some project of my own before I have no spare time at all, and I decided I wouldn’t give it on this project.

I learned a lot about Ruby through this project, and I am rather sulking at the fact that I won’t be able to look into this code at least in the near future. That’s why I’m posting this online.

Thank you!

Work done in Work so FAR

Before I start my discussion on Ruby and my project,

I'd like to discuss what I have been doing at my work lately.
Finally I have been involved in some pretty heavy coding (webpage that is),
and so far I've coded 4 versions of a game site (teaser, closed beta, open beta, and commercial),
complete with CSS/HTML/JS (specifically, jQuery), almost 95% written by me.
Recently I'm near completion of a facelift version of our main portal site, which give or take
is around 75 web pages. That means a compiled CSS of around 2000 lines and around 300 lines of
Javascript(I should've written more but thanks jQuery!).

I even coded the MySpace page for the game in CSS hack sorta way, to resemble another
game site in MySpace which was designed and made by the actual MySpace team, of which
their work is around 10K a site, because they remove the ad on top. I take pride in that
the commercial, MySpace site of this game is nearly similar in design and layout to this game,
and it was done only by hacking the hell out of a personal MySpace profile!

Now I KNOW when I look at a .PSD file, of how to design the layout in CSS. I just KNOW.
I've even written a C# app to read in game character stats and generate it into HTML (took 3 hours to code it, and used it on 4 characters. So I spent 4 hours to code the data, where otherwise hand-coding would have taken a whole freeggin day).

Here are a list of techniques I employ for webpage coding:

1. CSS

-I use a technique of controlling the deployment of CSS styles on specific sub pages and main page
by listing the parent tags first and making more specific naming further on (details on a separate blog article)

-Targeting IE6 and IE7 CSS hacks specifically by concise hack method of '* html' and '*:first-child+html'

-Extensive use of Firebug inside Firefox to interactively do a WYSIWYG editing of CSS

-Striving to separate content from design. All CSS does is giving the look, and HTML alone just lays out the information clearly and simplies the viewing of it.

-Use of barebone CSS sets. These things are AWESOME! They make default paddings/borders/margins all to non-existent or zero so you don't have to worry about it.

-Standardizing the look of the website by creating what's called a "design theme," or translating it into CSS. For example, a website will have only two type of rounded corner boxes, warning messages are in blocks, always accompany an icon with a yellow text background, etc..

2. HTML

-Care is put into put data appropriately in tags that mostly fit the data. For example, menus or
similar types of a parent type are put into list tags, and written blocks inside paragraphs. That way, CSS can target it better and make it viewable even without CSS.

-NEVER, EVER put design parts into HTML. You don't need to put a
tag to create gaps between a title and paragraph. TABLEs never have background. Heck, images, unless dynamically needed, don't need to have specific image sources in HTML. Make HTML show
almost only content and layout, nothing else!

3. Javascript

- Use jQuery. Even Visual Studio will ship with jQuery, having Intellisense and everything!
It gets the nitty gritty part, especially AJAX and browser compatibility anal pains out of sight for you and sort of makes a setting to create high-level Javascript code. What took 70% overhead of environment setting and 30% functional, actual working algorithm for writing Javascript code is, with jQuery, almost 90% coding working algorithm! It's also sooooo concise. 3 lines of code and you create a content slide down and up. Beat that!

- Use more jQuery! Sure, Prototype, Mootools, Dojo are all significant frameworks to work with, but none can beat the overall simplicity with relatively good response time. I had to do research at work about the 4 frameworks and I didn't know any of them before. After research, I concluded jQuery is THE BEST FRAMEWORK .. for me.

-Bloated Javascript isn't that good. It takes a long time to load, and since Javascript is based half on event-based execution of code, sometimes if you are not careful you will create race conditions where a code will execute faster than the other, unintentionally.




For the past 2 weeks I've stayed up nearly every night to code the 70-plus page main portal.
Sure I think coding pages is a busy-work. With so much content, designers not 100% sure of their "design theme" and constantly changing/editing the .PSD files, the work can be highly
stressful, especially staying up all night and coding.. webpages. However, when everything's done, CSS is all tidied up, and presentation of webpages / UI are as I intended, it gives a satisfaction that trumps the work.



However, coding by itself is such a repetitive action that resembles other menial tasks like
stapling or pasting envelopes. If you fail to strive shortening coding and grow an aversion towards repetition, I don't think growth will happen.

Wednesday, August 27, 2008

Web Coding - Fun with Subversion

WINDOWS Subversion usage for casual Web-Coding team environment

Okay. This is going to be a terse walkthrough in how to set up a version-control
work environment for the web design/coding&UI teams.

Setting: Usually nowadays the trend is that there is a design team and a coding team, not to mention a web-dev team.

Normally, the workflow starts from the PM (P stands for what I dunno.. production? project?)s that think of what needs to be developed. Designers get sent the raw material and the design barebone layout and start working their magic to turn something with lines to something with graphics.

The UI/Code team gets this and implements the actual HTML version of the normally graphic
format of PSD files.

A couple revisions at this step, and the coded page is worthy of passing on the developers, where it actually gets implemented into Internet-ready pages.

Problem: Too many versions of the same thing.

Let me explain how our company's workflow is:
  1. They give me the design. I code.
  2. I put the finished code for review into the networked drive. So, I have to manage 2 copies.
  3. Then again, some things are different for the actual deploy version of the code. So I copy again into another folder. 3 copies.
  4. If the developers put them on the servers, that also is counted, so 4 copies.
If changes need to be made, I have to change my source code for testing, overwrite the copies on the networked drives for other members to test, AND update it to the server.
Do you know how long this takes? 40 minutes.
Do you know how many points of access where I can stupidly delete stuff? ALOT.

So, I decided to try Subversion. Now, I won't explain what Subversion is because that is
documented so well in their site as well as good portion of Google search results.

What I want to describe is exactly how I used scripts and programs to create a easy-learning, transparent, version-controlled work environment.

Here are what each quality means:
  1. Easy learning: virtually the implementation speaks for itself.
  2. Transparent: I don't add another layer of access for version control - the codes are what is seen, the version-control parts are really non-visible and non-intrusive.
  3. Version-controlled: I'll just say that equals to less than 10 minute maintaining versions and the other free 30 minutes divulging into more fun stuff(er, activities) @ work.
So let's get down to it!

  1. First, follow this link and do EXACTLY what it says. You'll be installing Subversion, Apache Server, and TortoiseSVN(a GUI client for Subversion). Come back when you are done!
....
Good! Okay. Now there can be 2 problems that might occur with this configuration. First, TortoiseSVN uses a different Subversion client than the Subversion installed with Apache. Meaning, Subversion 1.5.X and 1.4.X are NOT compatible!! Just keep it mind that

At the Tigris Subversion site, the package for Windows for Apache Server comes with 1.4.6 of Subversion, and TortoiseSVN is packed with Subversion 1.5.X

.. which would cause problem for those that has this occured.

Eventually the Subversion 1.5.X installing would make this problem go away.

Anyways, you've checked in your codes, and you feel good.
But how should you deal with making a copy on the networked drive?
Sure, checkout another copy over there too. But.. don't you feel like you'd what it to
automate the update process of the copy on the networked drives?

So you won't have to do the couple clickings of the mouse just to get the codes updated?
Well, onto the next step:

2. Synchronizing via Scheduling Task Manager

It's really simple.
Map the networked folder to a drive. For this example, it'll be W:
Make a batch file (XXXX.bat).
Inside the batch file, type:


W:
cd Folder1
cd Folder_THAT_HAS_VERSION_CONTROLLING
svn up

That's it! Save and double click. You'll see that the networked folders are updated. Voila~

But don't you think the black command shell box is a bit intrusive? What doesn't need to know, doesn't need to show.

Make a YYYY.vbs file, inside the folder that has the .bat file for simplicity.

Inside, write:



CreateObject("Wscript.Shell").Run """XXXX.bat""", 0, False


Yep. Double click that, and the same batch file would run, but it would run in the background. No black windows!

3. Scheduling.

Start->Programs->Accessories->System Tools has the 'Schedule Tasks' program. Click it.
You know how to manage adding a new schedule right? If you want extra description, ask, I'll do it.
Add a schedule to run, like every 30 minutes. The program to run is the YYYY.vbs file.


4. Done!

I just implemented this workflow with this project I'm working on, and I am totally psyched about it. Now, I don't need to figure out which file to update, which file to leave, which file to copy over, which to just get some code lines from it... NO! I have Subversion and my scripts to do that for me!!

WOOT

Monday, August 04, 2008

How to Code Newsletters with CSS

This method works in following clients:

Yahoo! Mail: all images show
Google Mail: all images show
Outlook/Hotmail: if you allow it, all images show. If not, the text/HTML based newsletter shows!

At work, I had to code newsletters given by designers.

I wanted every possible way of not touching their artwork,
as it is my goal to code for perfection.

I read these good tutorials:
http://www.sitepoint.com/article/code-html-email-newsletters/2
http://www.reachcustomersonline.com/content/2004/11/11/09.27.00/index.php


My goal in coding this was to provide readability to as much people as possible over
various methods of reading emails.

That meant for those that can, show the newsletter in its original image form, and
for those who block any and all images, show the text-based version, which would be
gracefully replace the images automatically, by them filtering the images.

Let's think about that a moment.
What kind of methods are there to accomplish replacing images with text? Via presentation
filtering images? I will just lay out all the ones that failed first. Let me know if you want to know
how I tried only to fail. For those reasons I won't go into detail.

1. Position:absolute inside a Position:relative block, layering the image on top of text
2. "margin-top:-width" method to cover the text by pulling up the image by its height
3. Variations on these (image tag before div tage, vice versa) to make them work.

I couldn't do it! I mean if I get it working in YahooMail, GoogleMail wouldn't show anything. Outlook/Hotmail always displayed no images, but they showed the text all right. I only focused on those 4 methods of mail-viewing as I assumed they grasped the major market of mail-viewers.

Well, I tried floating the image.

So here are the basic steps I found out after couple tests.
1. Follow the link and read about the basic setup of a newsletter.

2. Follow and make/copy the code so you get rid of all the style tags and make it still work with inline CSS.

3. Basically you'll be using TABLEs to represent content. In a is where you'd show the sliced up newsletter images. Now that has no info whatsoever, and that same place is where you put the text-based content as well.

4. Inside that :
  1. Make a DIV tag, which will be wrapper for your content.

  2. Inside it, place your image first. Float it, block it.
    you don't need to give it dimension.

  3. After the IMG tag, Make a
    as same height as your image, and put content in.
    **make sure the text based content won't be taller than the image. It's gonna show gaps if so.

  4. THAT'S IT!!!!!!!!!!!
Here's how it looks:



TESTING:
I use this site to send me some test letters: http://www.mailchimp.com

It's a pretty good site, and they are very informative on things.


EVALUATION:

This method works in following clients:
Yahoo! Mail: all images show
Google Mail: all images show
Outlook/Hotmail: if you allow it, all images show. If not, the text/HTML based newsletter shows!

Monday, June 09, 2008

My accomplishments so far in OGPlanet.com

I have been working at a small game-publishing company in El Segundo, LA.
Called OGPlanet.com.

I love the job I'm doing. I'm an assistant web programmer, and that's basically what I do all
day.

Code websites all day. It's awesome. I've been dreaming about this kind of lifestyle - the life
of a coder - since the last few months of my last year at UCLA as undergrad.

Let me tell what I do:

Designers design the websites, and based on the producer's intention I have to follow through
and convert the stoic, PSD based files into websites.

Moreover, I get to code/learn Javascript and CSS.

Sure I don't get paid much($30,000 a year), but I'm actually doing what I wanted to do.

I've coded so much CSS styles that now I'm getting better and better at making neat,readable
stylesheets. I pretty much memorized hacks for FF, IE6, and IE7 and use them. I know,
I should create code that shouldn't use hacks. But I'm thinking I'm getting better at it.

I got to know jQuery - the best duct tape tool for Javascript. It makes coding in Javascript
what Ruby does to scripting languages - super easy, focus on logic rather than syntax.

... aside from assignments, I have a lot of time for idle developments, and this is what
is best about this job! I normally get around a day a week of nothing to do except acting busy.

So since this is my first job, I never would allow myself to actually do NOTHING. I took upon
myself to enforce a habit of coding - you know, like the policy they have at Google, where
you are required to use 20% of work time for research/project of your own.

Here are some of the little side projects I've made so far:

  • In our company we send newsletters weekly to the registered users that play our games. So, the designers always send me little zipped files to process. Without going into details, I made a Visual C# Windows application that would automatically process the files, upload it to the server, and open up the browser for me to check. I'm sure this will be beneficial to the designers and also it'll free up my time considerably - in the area of 20 minutes.
  • Anyone know Processing? It's a language used by media artists for artsy projects using databases. Sort of a visualization language for Java applets. Well, I overheard a PM (Project Manager) wishing there would be a real-time sales display of sales made in games, like in a bar chart that is constantly updating. I've made the thing using Eclipse and Processing - where it would function both using logged sales history and also in realtime. It is really nice - nice colored bar chart that moves every second, and basic graphical aesthetics (jittering, zooming, color fading, alpha blending) for cool effects. It's like a prototype for the big display-based system I'm having in mind. Since Applets can increase in size by setting window dimensions, a 42" display on a plasma screen is plausible.
  • I've noticed the company manages a lot of game sites - a game site would have from 20 to 30 pages. Every week there are 4,5 image/flash files that need to be uploaded to the static file server and sometimes links should be changed to the javascript that handles menus. I've made a Visual C# Windows app where I can drag the file to upload, select which of our sites it belongs to, which context it is - eg) left_ad_banner - and the filename should one want to change the default filename. I press upload, and voila! It shortened the task which took around 20 minute down to 2 minutes and relieved me of the anxiety of manual uploading which is possible to make mistakes due to high freedom of access.
  • Each Visual C# apps are password protected, and object-oriented - meaning I made classes that are in namespaces so if I want to make more company-related apps, I can easily inject the inner workings of access - since it's already object oriented.
So that's what I do until 6:00PM. Back home, if I'm not tired, I have a couple of my own projects:

1. Music Album via Buzz and Linux based Music Studio(UbuntuStudio)
2. Team-based employment site
3. Stock - related research


God I love my life!

Thursday, May 01, 2008

3 New Projects

First of all, I got hired at www.ogplanet.com as an Assistant Web Programmer,
and the job is as I have expected: coding websites.

I got a chance to use and learn cool new script libraries such as jQuery,
and the job is pretty fun and the thrill of coding on the clock is just mind-blowing!! :)

The project development flow was pretty cool too. I am experiencing
real-life execution of website developing that includes powerpoint based
functionality overview by the producer, and getting the design by the designers,
and finally coding the entire thing by yours truly.

As a side project and to regurgitate what I have learned in terms of project management,
I hereby announce, to myself and whatever random people that will see this post,

3 Projects that I intend to finish within one year.

[1]: Music band site
==============
My good friend Bang and I go a long way back, and that includes million what-ifs of
forming a band. Our dreams, even though we live in separate continents now, never
sorta phased out. I have my stockpile of lyrics, and he has his poems.

This will be like our 4th attempt at making something using the Internet, and this time
it will be something, as our school-years ended for the time being.

It will host a multi-genre band, comprised of me and .. Bang, with songs of Christian and secular.
We are both Christians, whether it's up to God and people if I am devout or not,
and personally for me what fuels my lyrics is all my relationship with God and His grace for
a hypocrite like me.

I'm excited and this will be a chance for me to use CSS/JS(jQuery)/Open Source tools for
web development,
and LINUX - based music production environment that I've always wanted to make an excuse
for learning :).

Ghetto - style music production setup in my dorm room.........using donated used laptops...
..........how more cool can this get!!?!

So, that's that and let's see where this goes!! ^.^

[2]:"Gig".com
==========
My friend from college and I thought this one up. I've lost him to a very rich and evil company

but hopefully he won't sell his soul there. haha.
Anyways, this is a social-team-based recruiting site where
employers will be looking for a "team", not an individual worker.

This is a new concept because what with the economy so bad as it is,
people will be pressured to outsource whatever things could be,
and those wanting their foot in the job-pool would want more protection,
and a team-based gig proposal, in my opinion is better than an individual.

... Plus it has that reality-zing to it. A website where.. new bonds among members are met..
and old bonds.. broken.

Anyways it's a site for Korean 20's in Korea. You'd think getting a job in the states is bad..
in Korea it's way worse than here. This will be sorta my charity work for Korea.

I'm still pondering whether I should code the whole thing or use Drupal.. I'm gonna have to
see if I really want to code everything by myself. And if by me, I'm gonna use CakePHP - as
people say that is pretty good for OOPHP programming, which I've always wanted to learn.

Hope I can get this baby off the ground soon. The idea was created 1 year ago already.

[3]:Stocker
========
This is a concept I am working on, regarding stock infos and speculations. I would have more
to say if I have more concrete direction of the development but currently I'm stuck
by my lack of knowledge in Ruby.

I'll just say I am using Ruby and making it interact with the Internet ^___^;

--------

So, that is that and I'll try to update faster from now on.. since I would like to see this blog
in high traffic as well.

Saturday, December 08, 2007

www.ciyring.com

[ANOTHER failed attempt at lauching a site]
www.ciyring.com was to be the dream of mine.
'Cuz It's Your Ring - a ring customization site.

I'm embarrassed about this experience so I won't really
go into explaining why I made it. Just know that
I had to do it, my friend asked me, and now I ditched it.

Again, I spent way too much time deciding every
single minute detail that went into this design.
Is it going to be like this for every design of websites?
Gosh..

Here's a brief spec:
1. Idea: Ring customization site, in accordance a jewelry shop.
2. Backend: a basic ecommerce, Ruby based app made by yours truly
3. Time: good 3 months from start to disastrous end

Ruby coding was just enhancing the tutorial they had in the book,
Agile Programming in Ruby or something like that. The famous
one by Pragmatic?

I honestly say I have learned alot about Ruby on Rails, but the whole
thing is still new to me and a bit overboard. I don't think I'll have
the balls to implement such a thing again. Why do that when
there are other well developed open source engines?

Here's the image:


If you go to the site, I still left the debugging mode for Ruby open so it's
gonna take time to load.

Sucks cuz I lost the whole thing behind this one because my laptop hdd
failed on me. I really don't know what to do with this one..
Could I possibly sell this on eBay or something?

Onmorie - the newly revamp, rest in my hdd forver.

The design and also the chosen backend system will never see the
light on the Internet, and what the hell am I gonna do with this
highly specialized design? I can't use it on anything else.
I mean, it's not like I have a showcasing site of my own that
displays my web designs.
CRAP.

Well, I will think about that later. Right now, just laying out the
specifics on this site will vent some much-stored steam of mine.

Developing environment:

I went for an offline development this time.
After my past developing experiences with site-development,
The time-consuming step of uploading and editing and uploading again
just seemed, finally, too wasteful for a developer like me that
develops websites as just a hobby.
Hey when you start it, you gotta finish it, and when you finish it,
it's only worthwhile only if it turns out good, right?

So, I searched for some methods to make an offline setup.
I thought about LAMP. But even though Linux is a good environment,
it was too overhead to change a computer setup to make one decent web site.
Then I hit on WAMP - the Windows version of LAMP.

The overall setup turned out to be very concise and easy to manage.
I had a PHP, MySQL, phpMyAdmin, Apache-based server running in my
Vista in no time!

Then, I had to choose the backend engine:
My dad's business is teaching how to be creative. He is a guest lecturer,
employed by a Korean personnel training company. Generally, the site
was in focus for creating more lecturing opportunities - a chance
for him to show his ideas on creativity and a place to connect with those
interested or wanting to affiliate.

Therefore, this called for a blogging engine.

Now, if it's in English, I would take no time in choosing the Wordpress engine.
Sure, I even tried the Korean version of Wordpress as the backend in
www.onmorie.com/wordpress.
However, the writing/managing experience was all in English!
I wasn't really a fan for half-baked translation, and plus I wanted this site
to be fully manageable by my dad, so I ditched that idea.

I went for Tattertools - a very good blogging software in Korean.
I'm serious, if there is Wordpress for the Western languages, there is
Tattertools for Korean! It's that good.
And it's based on Korean so all the utf-8 setup is ready from the get go.
It's open source as well, is followed by much devoted coders, bloggers,
and all that,
and the best thing is that all the posts made using the engine gets
an option to be posted to Eolin - the Korean blogosphere-equlivalent
of [Put ur favorite blog-aggregating site here].

Okay, all the ingredients are set. Off I went on designing.

God what a pressure it was to think about a design for a site about creativity.
It has to informative, fluid, and show that concept of "thinking outsite the
box."

I generally start by jotting down notes like above ideas. Well, I jot down 30%
of ideas and the other 70% I just roll it around in my head for a while.

Fluidity. Informative. Creative. Out of the box.
And I'm just a freakin line-thinkin noob coder.
Here is the train of my thoughts:
out of the box => break out of the borders somewhat
meaning overlayed transparent png..
color: nothing bold, official, office like, but more showing fluid, acceptance, free-living
overall tone of color had to show inceptual concepts, ideas, fountain of ideas

I had to think of a cool logo too.
It had to show the concept of Onmorie - using the right and the left part of brain
to synnergize a new idea, a new creation. Well, I didn't go into researching further.
Creativity is similar to idea to a fluid type font,
Logic is similar to angular type font.
I also wanted to make a trendy statement, so I tried on a Web 2.0 type badge as well.
After a couple more playing around in GIMP, I got this:

Yes.. that was my attempt in making a logo, and well, it's just my biased opinion
but I like it :) Mix of fluid font styles, with the center font of angular, rigidness
shows the concept of the site in somewhat clear voice.

Next up was the overall layout of the site.

I decided on a simple 2 column layout, because that meant less CSS-headaches later on.
Plus, after checking out the engine, the sites that were created by it generally sported a
2-column anyways. Good for me.

God I SPENT 2 FULL DAYS just deciding on the borders of the layout!
2 FULL Days of answering this question: To round or not to round the borders?

If the corners are rounded, that's for the overall outer border of the layout,
my final judgment was that it would mean ideas are finalized, and it wouldn't
reflect the fluidness of ever-evolving creativity as the site was supposed to persuade.
A basic, minimal graduated background color of the layout sounded more
appealing at the time. I have no confidence in this decision. I mean, I'm a perfectionist and an
owner of small balls. I have to set these decisions over 2 days, what can I say :)?
................
God you CANNOT image the sleepless nights and countless aggravation and stress I went
through to decide each and every detail of the design of the site.
Even now, I think I couldn't have done a better job, because I suck at design and color-
coordinating. This is the best I can do. I gained a whole new level of respect for
CSS-web designers like those in CSSZengarden. Cudos for you guys. You guys ROCK!
Here's a shot of my final design:
Rightside top of the design has the outline of a guy lifting his arm, pointing with his
index finger. Yeah, that guy is having a Eureka! moment. My expression of
what creativity is, as is well the balloons exhibiting expressions.

I did my best man, I did my best. And then I chopped this into CSS,
and this time I followed the book I bought from CSSZengarden to
make the CSS as formal and pristine as possible. To make it really
CSS-compliant. I'm really happy how the CSS turned out.

As for putting the skin into backend, it wasn't really a time-consuming
experience as only minimal details needed to be put into the overall
HTML files. And having a local WAMP server to see it didn't hurt the process either.

Monday, November 27, 2006

PHP Form generator

http://www.tele-pro.co.uk/scripts/contact_form/

Hiatus notes - word replacer

Just another source of useful tools in web development/SEO/content generation..

well, ethically this wouldn't be a just way of creating content.

But someone made it for some use, so maybe it'd be useful.

http://www.wordreplacer.com/

go and check it out.

Also.. I should make a mashup site, just to learn AJAX and mashing up.. sites.
Creating self-perpetuating(relatively in my part) content on the web that is
useful for me and visitors.. it would be an interesting project and a milestone to be reached,
I guess in my course of being a serious web developer.
That and making linux from scratch..

Tuesday, November 21, 2006

Someone made a similar app as mine

My program makes rounded cornered content css styles,
his makes just the generic content sheet I think.

http://forwardlogic.net/dev/css.php

also is a real-time Font viewer:

http://www.fonttester.com/