My Skills for Hire!

Sunday, February 08, 2015

Traveler's image / blog helper script in python

Due to my last year in medical school's requirement for global health electives, I'm currently in India. Exotic! And also many pictures were taken, which brought an interesting problem of the need to upload many pictures embedded in many blog posts.

Doing that by hand would be .. still be feasible, but sometimes the Internet at my particular site can be flaky and wouldn't work, which complicated and necessitated (?) the repetition of uploading.

As with any problems that remotely start being repetitive, I mulled if I can code a solution, while sipping my delicious chai with the delicious poha or anda bhurji.

I concluded it's possible, and it would actually save me a lot of time. And it did.

So what below script can get you:
You write a text file, and when you want to insert photos you just write the filename of that photo in its separate line. Save.

Then, when you run the script, it will upload the file, replace the filename with a  'img' tag which links to the url that corresponds to photo uploaded at imgur.com, and save it to another textfile.

After which you can copy/paste that text into your blog, in the mode where you can put HTML codes.

Here's how to get the script up and running:

1) List all the filenames of the pictures you want to post in your blog post textfile. I use Linux, and so naturally I open up a terminal in that photo folder, do a 'ls -l', and copy the list of photos. For windows, I guess I can do 'dir' in that folder with the photos.

2) Download Geany, the best text editor ever. Copy/Paste the list of photos. Press the control key while selecting only the part of the text column that has the filenames (eg 'IMG_2452.JPG') Be amazed by how pressing the Control key can do vertical selection of text. Now move it around, delete all the unnecessary text file.

3) Read https://github.com/Imgur/imgurpython and get all that is required (python, imgurpython library, authentication tokens ). If you don't know how, look it up as it is not the scope of this blog post.

4) Download my script: https://github.com/lovebes/imgur4blogging
 - and enter your personal client_id, client_secret, access_token, and refresh_token. 

5) In imgur, log in, and make an album where you want the script to upload all the travel photos. Get the id # of the album folder  (eg. m8F3b )

6) Use the script as such: go to commandline:
    type: python imgurupload.py -f /path/to/folder/of/photo/ -j /path/to/the/textfile.txt
7) Watch it go!, it will finish and create:  /path/to/folder/of/photo/ -j /path/to/the/textfile.txt_replaced.txt

8) Check if some of the pictures are converted to 'failedtoupload.jpg', which is when upload fails. You can run it again to see if they upload, or just leave it .. depends on you.



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!!!