Shriphani ‘PSP’ Palakodety

Weblog of an Aspiring Computer Scientist

Shriphani ‘PSP’ Palakodety header image 1

WAV Files, Spring Semester, Research Hopes, IPL,

May 26th, 2009 · python

UPDATE 02/13/2010: Most recent version of this script is now moved to: http://shriphani.com/blog/listener.

EDIT: An updated version of this script along with tools to improve the user experience can be obtained at http://shriphani.com/Shriphani_Website/Listener.html

After an looooong time, I’ve decided to put finger on keyboard (I think that sounds stupid). Considering that I now use BOSE headphones which cut me off from the outside world when I am listening to anything (I use the triport headphones; not the Quietcomfort), it has been a bit hard to respond to all the calls for attention over here (no one usually wants me to pay attention and that’s how it works best). So I decided that it would be better if I could use the mic on my mac to check if someone was calling me. This is the first time I have tinkered with .wav files and I am sure that I am doing loads of things wrong. First, I decided to use PyAudio, PortAudio’s Python bindings, to record audio from the microphone, save it to a wav file and then open it and analyze etc. So with help from the Examples that come bundled with PyAudio, here is the code to record from the inbuilt microphone:

Recording:

def record():
    ‘Records Input From Microphone Using PyAudio’
    duration = 1 #record for 1 second. Pretty long duration don’t you think
    outfile = "analysis.wav"

    p = pyaudio.PyAudio()

    inStream = p.open(format=pyaudio.paInt16, channels=1, rate=44100,input=True, frames_per_buffer=1024)

    print "recording has begun"
    out = []
    upper_lim = 44100 / 1024 * duration #upper limit of the range we record to. 44100 / 1024 sized chunk * 5 seconds

    for i in xrange(0, upper_lim):
        data = inStream.read(1024)
        out.append(data)

    #now the writing section where we write to file

    data = .join(out)
    outFile = wave.open(outfile, "wb")
    outFile.setnchannels(1)
    outFile.setsampwidth(p.get_sample_size(pyaudio.paInt16))
    outFile.setframerate(44100)
    outFile.writeframes(data)
    outFile.close()

Then, I opened the wav file and read the first 2000 values from it and obtained the root mean square amplitude and then obtained the intensity of sound using the following snippet:

Analyzing

def analyze():
    inFile = wave.open("analysis.wav", "rb") #open a wav file in read mode
    sample_rate = inFile.getframerate()
    total_samples = inFile.getnframes()
    fftLength = 128
    fft_num = (total_samples/fftLength) -2
    vals = inFile.readframes(2000)
    results = struct.unpack("%dh"%(2000), vals)
    results = [x**2 for x in results]
    intensity = 20 * numpy.log10(numpy.sqrt(sum(results)/2000))
    if (intensity > 55):
        print "Someone might be calling you"
        curtime = time.localtime()
        print "Current Time: %d:%d:%d"%(curtime[3], curtime[4], curtime[5])
        print "Intensity: "+str(intensity) + " dB\n"
    inFile.close()

I chose 55 dB because well 55 dB seems to be the right intensity of sound you would hear if you were conversing with someone 1 meter away.

The next thing to do would be to repeat this action over and over again. I decided to use something like:

while True:
    record()
    analyze()
    sleep(2.0)

I am not sure what went wrong there but when it ran the second time it gave me an “internal PortAudio Error” which pissed me off. However, using BASH to handle the endless loop worked and I could achieve the desired functionality using something like:

while [ "true" ]
do
  python audio_analysis.py
  sleep 2
done

This might be the wrong way to go about it but it works at least…..

Also, I thought growl would be something cool to have and I decided that I would go out there and get it use Growl to notify me but for some screwed up reason I cannot build Growl’s Python bindings using the Enthought Python Distribution which I use. I can however build it using Python 2.6 (and I still use the Numpy that comes with EPD). I get errors like:

running install
running build
running build_py
running build_ext
building '_growlImage' extension
gcc -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -g -L/usr/local/lib -L/Library/Frameworks/Python.framework/Versions/4.3.0/lib -bundle -undefined dynamic_lookup build/temp.macosx-10.3-fat-2.5/growlImage.o -o build/lib.macosx-10.3-fat-2.5/_growlImage.so -framework Cocoa
ld: in /Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/Python.framework/Versions/4.3.0/lib/libz.1.dylib, file is not of required architecture for architecture ppc
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccNgltEc.out (No such file or directory)
error: command 'gcc' failed with exit status 1

I think that I am unable to generate a universal binary there and as a result I can’t use Growl. Anyway, I have two screens and I can leave a terminal window open on one of those to see what’s going on in the surroundings. So sample run:

cm92:scripts shriphani$ ./repeat.sh
Someone might be calling you
Current Time: 11:55:22
Intensity: 56.9166929341 dB

Someone might be calling you
Current Time: 11:55:33
Intensity: 72.6820018669 dB

Someone might be calling you
Current Time: 11:55:51
Intensity: 56.7505666696 dB

Someone might be calling you
Current Time: 11:55:54
Intensity: 55.571208569 dB

Someone might be calling you
Current Time: 11:55:58
Intensity: 60.0388858371 dB

Someone might be calling you
Current Time: 11:56:1
Intensity: 56.3460220002 dB

These results were obtained in the following situations:

  • The TV running.
  • My mom calling me.

Anyway, in other news, I managed to end up with a GPA of 3.85 overall thanks to a series of mistakes towards the end of the semester and lost the 4.0…….. it is depressing, but I’ll just put that behind me for now.

And I’m also trying to find a spot in Prof Kihara’s computational bio lab….. I hope I get to do some research next semester.

The spring was not full of disappointment, I got to meet some awesome professors in the honors seminar (in which I skipped most of the student presentations except the one I was supposed to speak in). I got to meet Prof. Wagstaff who has a prime number named after him, I got to meet Prof Kihara and others.

Congrats to the Deccan Chargers for their excellent performance in the Indian Premier League. Thanks for rewarding our unyielding support by bringing the trophy to Hyderabad.

Now I’ve got to go and entertain myself with Combat Arms.

UPDATE: The script can be obtained at: Script to Record+Analyze and Script to Repeat action.

→ 1 CommentTags:

Dual Display Setup

April 13th, 2009 · Uncategorized

 

So, I decided to go ahead and my computing experience a bit richer. I of course had an apple LED cinema display in mind but at $900 for 24” and $1800 for 30”, I could have as well purchased a new macbook. So, I decided to buy an Acer monitor on tigerdirect.com and after parting with $150, I had in my possession a beautiful 22” display and after unpacking it and plugging it into my macbook pro’s DVI port, I was working with two monitors. Of course, it is a PITA to function with two monitors and the macbook pro keyboard. So I started looking for a mac compatible keyboard and mouse (i already have a wired mighty mouse). For $60, I found the mac compatible logitech wave and it certainly improved my computing experience. The wave is stylish, comfortable and quite thin contrary to what the pics suggest. I of course get a delete key, three freely programmable keys, ability to get to expose and dashboard with one keystroke and some ergonomic features but I am no expert in this area since most of the keyboards I’ve used are pretty crappy ones (except for the keyboard on my macbook pro that is). So, here are initial pics of my setup before my keyboard and mouse arrived:

New Screen Connected to MBP

New Screen Connected to MBP

 

And of course, the duo:

 

Macbook Pro Connected to External Display

Macbook Pro Connected to External Display

 

With my logitech wave cordless keyboard and mouse combo, my perfect setup is now complete. I can soon look forward to code in peace and watch HD vids on my new screen. Wee, c y a later. Too many exams queueing up to bite my ass.

→ No CommentsTags:

Hebb’s Rule

February 9th, 2009 · College, Computer Science, Mathematics, python

This post is slightly psychology influenced. Well, in the Psychology class I have been taking this semester (Introduction To Cognitive Learning), I was taught about Neural Networks and a certain Hebb’s Rule which allows a network to remember a previous configuration and use this configuration to interpret new information. We use the following model to represent a cell:

1. A cell (neuron) has only two activation states: On or Off.

  • On: Cell has high firing rate. (High number of action potentials fired in unit time).
  • Off: Cell has low firing rate.

2. Cell weights are reciprocal. Weights symbolize the size of the synapse between two cells. Greater size = greater strength.

3. If cells fire simultaneously, they develop positive weights. The active cells (activation = on) inhibit the inactive cells (develop negative weights.

4. The network organizes itself based on sensory input. And new sensory info is interpreted by previously developed weights.

5. The network updates itself one at a time.

6. The activation of a cell can be determined by the following formula:

1 if ∑wijaj > 0
0 otherwise

The weights lend a sort of memory to the network since weights influence the interpretation of subsequent sensory input.

Based on these rules, I wrote something that simulated a network that implemented the Hebb’s rule.

First, we need to describe a neuron. Our neurons represent an uppercase letter of the english alphabet. We also need a way to represent the weights with each of the other neurons.

So a basic class to describe a neuron:

class Neuron:
        def __init__(self, a, weight_dict):
                ‘A Represents The Cell’s Content

                self.content = a #what letter of the alphabet a cell represents
                self.weights = weight_dict #only contains contents of each neuron.
                self.state = 0 #activation state initially on.

        def __str__(self):
                return "Activation: "+str(self.state)+"\nWeights: "+str(self.weights)

Now, the network has a collection of neurons (26 in our case which signify each letter of the alphabet). Hence, the init method for the neuron class:

       def __init__(self):
                self.neurons = []
                self.flush = {} #weight calculator while updating activities
                self.possibilities = []

                for char in string.uppercase:
                        self.flush[char] = 0

                for letter in string.uppercase:
                        weights = copy.copy(self.flush)
                        weights.pop(letter)
                        a = Neuron(letter, weights)
                        self.neurons.append(a)

Now that we have a network that is populated, we need a method that receives input and figures out the changes in the weights between cells (or the strength of the connection between cells). This method is then fed by another method that figures out the overall change in the weights and computer which cells are active:

def recvInput(self):
                a = raw_input("Sensory Interface: ") #Get a word
               
                while a != "QUIT":
                        b = list(a)
                        for i in xrange(len(b)):
                                for neuron in self.neurons:
                                        char = b[i]
                                        if neuron.content == char:
                                                neuron.state = 1
                                                reqd_list = b[0:i]+b[i+1:]
                                                for char in string.uppercase:
                                                        if char in reqd_list:
                                                                neuron.weights[char]+=1
                                                        else:
                                                                if neuron.weights.has_key(char):
                                                                        neuron.weights[char]-=1
                                                                else:
                                                                        continue

                        self.checkInfo()
                        self.possibleInfo()
                        print "The possible interpretations of this input might be anagrams of the subsets of: \n"
                        print self.possibilities
                        a = raw_input("Sensory Interface: ")

        def checkInfo(self):
                output = []
                possibilities = {}
                for neuron in self.neurons:
                        if neuron.state == 1:
                                for info in neuron.weights.keys():
                                        self.flush[info] += neuron.weights[info]
                print self.flush
                                       
                for neuron in self.neurons:
                        if self.flush[neuron.content] > 0:
                                neuron.state = 1
                        else:
                                neuron.state = 0
               
                for char in self.flush.keys():
                        self.flush[char] = 0

        def possibleInfo(self):
                self.possibilities = []
                for neuron in self.neurons:
                        if neuron.state == 1:
                                self.possibilities.append(neuron.content)
 

Then we run this network with:

words = Network()

words.recvInput()
 

Before I run this, let me mention that this thing only accepts uppercase letters and breaks if a letter is repeated in a word. This is because neurons rarely have their own axon connected to their own dendrite (neurons are not connected to themselves).

So, a sample run:

tark-b-183:scripts shriphani\> python hebb.py
Sensory Interface: HELP
{'A': -4, 'C': -4, 'B': -4, 'E': 3, 'D': -4, 'G': -4, 'F': -4, 'I': -4, 'H': 3, 'K': -4, 'J': -4, 'M': -4, 'L': 3, 'O': -4, 'N': -4, 'Q': -4, 'P': 3, 'S': -4, 'R': -4, 'U': -4, 'T': -4, 'W': -4, 'V': -4, 'Y': -4, 'X': -4, 'Z': -4}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'H', 'L', 'P']
Sensory Interface: LOSER
{'A': -9, 'C': -9, 'B': -9, 'E': 7, 'D': -9, 'G': -9, 'F': -9, 'I': -9, 'H': -2, 'K': -9, 'J': -9, 'M': -9, 'L': 7, 'O': 0, 'N': -9, 'Q': -9, 'P': -2, 'S': 0, 'R': 0, 'U': -9, 'T': -9, 'W': -9, 'V': -9, 'Y': -9, 'X': -9, 'Z': -9}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'L']
Sensory Interface: HOMELY
{'A': -12, 'C': -12, 'B': -12, 'E': 9, 'D': -12, 'G': -12, 'F': -12, 'I': -12, 'H': 4, 'K': -12, 'J': -12, 'M': -1, 'L': 9, 'O': 4, 'N': -12, 'Q': -12, 'P': -6, 'S': -6, 'R': -6, 'U': -12, 'T': -12, 'W': -12, 'V': -12, 'Y': -1, 'X': -12, 'Z': -12}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'H', 'L', 'O']
Sensory Interface: LOSER
{'A': -17, 'C': -17, 'B': -17, 'E': 13, 'D': -17, 'G': -17, 'F': -17, 'I': -17, 'H': -5, 'K': -17, 'J': -17, 'M': -9, 'L': 13, 'O': 8, 'N': -17, 'Q': -17, 'P': -11, 'S': 1, 'R': 1, 'U': -17, 'T': -17, 'W': -17, 'V': -17, 'Y': -9, 'X': -17, 'Z': -17}
The possible interpretations of this input might be anagrams of the subsets of: 

['E', 'L', 'O', 'R', 'S']

So we observe that in the first case, four neurons were activated. The word “LOSER” led to H and P being deactivated because the synapse weakened. The next input “HOMELY” causes H and O to activate because O began developing positive weights with other cells and when LOSER was submitted as input and developed a strong enough connection when it was seen in another sensory input. When LOSER is flashed again, it leads to H being forgotten and causes R and S to activate.

Now, a particular case which (I think) indicates the use of this “learning” technique is when we are playing scrabble. Assume that I have words such as NEAR in my memory and when I see N and E on a board, I should be able to complete these words. Watch:

Sensory Interface: NEAR
{'A': 3, 'C': -4, 'B': -4, 'E': 3, 'D': -4, 'G': -4, 'F': -4, 'I': -4, 'H': -4, 'K': -4, 'J': -4, 'M': -4, 'L': -4, 'O': -4, 'N': 3, 'Q': -4, 'P': -4, 'S': -4, 'R': 3, 'U': -4, 'T': -4, 'W': -4, 'V': -4, 'Y': -4, 'X': -4, 'Z': -4}
The possible interpretations of this input might be anagrams of the subsets of: 

['A', 'E', 'N', 'R']
Sensory Interface: NE
{'A': 1, 'C': -6, 'B': -6, 'E': 4, 'D': -6, 'G': -6, 'F': -6, 'I': -6, 'H': -6, 'K': -6, 'J': -6, 'M': -6, 'L': -6, 'O': -6, 'N': 4, 'Q': -6, 'P': -6, 'S': -6, 'R': 1, 'U': -6, 'T': -6, 'W': -6, 'V': -6, 'Y': -6, 'X': -6, 'Z': -6}
The possible interpretations of this input might be anagrams of the subsets of: 

['A', 'E', 'N', 'R']
Sensory Interface:

Well, this semester, I have already been taught some insanely great stuff. I have a bunch of exams coming up. Great scores will be the perfect way to make an awesome semester even better.

The script can be downloaded here.
The material here was used from Professor Greg Francis’ notes on Neural Learning.

→ 4 CommentsTags:

Post’s Machine Emulator

January 17th, 2009 · Computer Science, Mathematics, python

I was bored as usual and since Combat Arms has begun to slip in my list of pastimes, I decided to write a Post’s Machine Emulator as described in the booklet by V. A. Uspensky titled “Post’s Machine” ( Amazon Link

This machine has a tape (infinitely long) and the reel has cells which can be marked or unmarked. I decided to represent a marked cell with a “1″ and an unmarked cell as “0″.

The head of this machine can move both ways and can mark and at the same time remove the mark from the other side.

The machine can be instructed using the syntax:

number, action, jump

The position of the head is indicated by a structure \”[]\” around the cell. Example:

Initial Stage
.....[0], 0, 0, 0, 0, .....

I used the “…..” to indicate that the remnant cells are all unmarked.

So here are the Head and Tape classes:

class Cell:
    ‘Class describing the cell of a tape’

    def __init__(self, mark=0):
        ‘Each cell is unmarked by default’
        self.mark = mark

    def setMark(self):
        self.mark = 1

    def remMark(self):
        self.mark = 0

class Tape:
    ‘Class describing the infinite reel in the machine’

    def __init__(self):
        ‘Each tape has an infinite number of cells both ways’
        self.reel = []
        for i in xrange(5): #we display only the required elements at a time
            cell = Cell()
            self.reel.append(cell)

    def __str__(self):
        printstr = "….."
        for cell in self.reel:
            printstr += str(cell.mark)+","
        printstr += "….."
        return printstr

class Head:
    ‘Class describing the head’

    def __init__(self, tape, position=0):
        self.position = position
        self.tape = tape

    def moveLeft(self):
        if self.position != 0:
            self.position -= 1

        else:
            extension = []
            extension.append(Cell())
            self.tape = extension + tape.reel

    def etchMark(self):
        self.tape.reel[self.position].setMark()

    def remMark(self):
        self.tape.reel[self.position].remMark()

    def moveRight(self):
        if self.position == len(self.tape.reel)1:
            self.tape.reel.append(Cell())
        self.position += 1

    def getPosition(self):
        return self.position

Then comes the Machine class which takes a tape as an argument. So that you can insert your own tape or use the default tape:

class Machine:
    ‘Class describing the Post Machine’

    def __init__(self, tape):
        self.tape = tape
        self.head = Head(tape)
        self.commands = {}

    def parseInstruction(self, number, action, jump):
        ‘Instruction is of form "[number, action, jump]"’
        self.commands[number] = [action, jump]

    def beginExecution(self):
        instruction = 0
        action = self.commands[instruction][0]

        while action != "exit":
            if action == "<":
                self.head.moveLeft()
            elif action == ">":
                self.head.moveRight()
            elif action == "mark":
                self.head.etchMark()
            elif action == "unmark":
                self.head.remMark()

            print self
            instruction = self.commands[instruction][1]
            action = self.commands[instruction][0]

        return

    def __str__(self):
        ‘This returns tape with the head displayed’
        a = str(self.tape)
        posn = self.head.getPosition()
        temp = "….."
        for i in xrange(len(self.tape.reel)):
            if i == posn:
                temp += "["+str(self.tape.reel[i].mark)+"], "
            else:
                temp += str(self.tape.reel[i].mark) + ", "
        temp += "….."
        return temp

Next comes a function that reads an input file for instructions:

def run(input_file):
    infile = open(input_file, ‘r’)
    b = infile.readlines()
    for instruction in b:
        try:
            splits = instruction.split(",")
            number = int(splits[0].strip())
            action = splits[1].strip()
            if action == "exit":
                a.parseInstruction(number, action, 0)
            else:
                jump = int(splits[2].strip())
                a.parseInstruction(number, action, jump)
        except KeyError:
            return
    infile.close()
    a.beginExecution()

A bunch of instructions which need to be written to some file:

0, >, 2
1, <, 0
2, >, 3
3, >, 4
4, >, 5
5, mark, 6
6, >, 7
7, exit

The output:

pal-178-222:~ shriphani$ python post.py
Initial Stage
.....[0], 0, 0, 0, 0, .....
File: input_file
.....0, [0], 0, 0, 0, .....
.....0, 0, [0], 0, 0, .....
.....0, 0, 0, [0], 0, .....
.....0, 0, 0, 0, [0], .....
.....0, 0, 0, 0, [1], .....
.....0, 0, 0, 0, 1, [0], .....
pal-178-222:~ shriphani$ python post.py

The full script can be obtained at http://shriphani.com/scripts/post.py

Well, later.

→ 2 CommentsTags:

RPN Calculator – Keeping Boredom Away

January 14th, 2009 · Daily life, Mathematics, python

Alright, those who know me well are bound to ask, 19 credit hours and you are bored? Answer: Yes. It is still the first week and we don’t seem to have gotten beyond the “introduce your loser self to the other non-interested members of the class” and since I have only 1 programming intensive course this semester, I should have lots of time to kill.

Well, my first script this semester is an RPN calculator. Totally useless for the vast majority of people out there but they know what to expect from someone who likes theoretical computer science.

So, I first began with a stack – in this case an array. I then keep populating it with numbers and every time the state of the stack changes, it prints out the current state.

If an operation is entered (only +, -, * and /), it performs the operation, replaces the appropriate positions in the stack and then prints out the current state.

Here is the code, Its been a while since I wrote any OOP stuff in Python and the “self” especially feels weird after an entire semester of Java…

#!/usr/bin/env python
#Author: Shriphani Palakodety
#Mail: shriphani@shriphani.com
#RPN Calculator

class Machine:
        def __init__(self, stack=[]):
                self.stack = []

        def modifyStack(self, element):
                ‘add to stack if input is float else run operation or complain’

                if self.isOperator(element):
                        self.operate(element)
                        self.printStack()
                elif self.isFloat(element):
                        self.stack.append(element)
                        self.printStack()

                else:
                        print "Only numbers and operators"

        def isFloat(self, char):
                ‘Checks whether the last item entered in the stack is a float or not’
                try:
                        float(char)
                except ValueError:
                        return False
                return True

        def isOperator(self, char):
                ‘Checks whether the last item entered in the stack is an operator or not’
                if char == ‘+’ or char == ‘-’ or char == ‘*’ or char == ‘/’:
                        return True
                else:
                        return False

        def operate(self, operator):
                ‘Perform the stated operation on the last two elements in the stack’
               
                operand1 = float(self.stack[-1])
                operand2 = float(self.stack[-2])

                self.stack.pop(-1)
                self.stack.pop(-1)

                if operator==‘+’:
                        self.stack.append(operand1+operand2)

                elif operator==‘-’:
                        self.stack.append(operand2-operand1)

                elif operator==‘*’:
                        self.stack.append(operand1*operand2)

                elif operator==‘/’:
                        self.stack.append(float(operand2)/float(operand1))

                else:
                        print "God only knows what operation you have typed in"
                        self.stack += [operand2, operand1]
                        self.printStack()

        def printStack(self):
                print self.stack

       
def kickOff():
        calc = Machine()
        while True:
                a = raw_input(‘Input: ‘)
                if a != :
                        calc.modifyStack(a)
                else:
                        calc.printStack()
                        raise SystemExit

print"Press Enter to Quit\n"
kickOff()
 

The calculator in action:

pal-179-083:~ shriphani$ python rpn.py
Press Enter to Quit

Input: 1
['1']
Input: 2
['1', '2']
Input: 3
['1', '2', '3']
Input: 4
['1', '2', '3', '4']
Input: 5
['1', '2', '3', '4', '5']
Input: +
['1', '2', '3', 9.0]
Input: h
Only numbers and operators
Input: -
['1', '2', -6.0]
Input:
['1', '2', -6.0]

In other news, I am really pissed with Picasa since I can’t see how many people have viewed my pics (http://picasaweb.google.com/shriphanip in case you are interested), I have begun filling my playlists with songs played at apple keynotes and in apple ads. Friends say this is an obsession with everything with the Apple stamp on it. I basically don’t care.

There has always been this one question bugging me since last semester. In Java:

 class Test
{
        public static void main(String[] args)
        {
                int a = 012345;
                System.out.println(a);
        }
}
 

When I run this:

pal-179-083:~ shriphani$ java Test
5349
pal-179-083:~ shriphani$

What is happening here?

Anyway, looking forward to this semester. Hope my GPA stays at 4.0

→ 17 CommentsTags:

2008, Fall ‘08, Life Update

January 4th, 2009 · College, Computer Science, Daily life, photography

Ok, this post is a few days late but since I have made a habit of thinking hard about personal stuff to blog about and coming up with nothing, I am sure this delay will cause no harm….

So, my fall semester worked out pretty good in the end. I managed a 4.0 GPA and now am in the CS honors program…. nothing surprising there.

A certain Project Euler problem I once solved was of great help in a CS exam, needless to say, euler does help.

I have owned an macbook pro for 3 months and I still read the applescript guide to do anything worthwhile with it.

Anyway, I paid a visit to the Jurong Bird Park (Singapore) and managed to shoot a few pics. Here are my favorite pictures:


Made with Slideshow Embed Tool

Apart from that, here is my course list for next semester:

1) CS 240 (Coding in C)

2) Calc 3

3) Cognitive Learning and AI

4) Intro statistics

5) English

6) Teamwork (I am not sure what this is)

7) Freshmen honors seminar (something to do with where computing has been and where it will go from here).

I am out of writing material, I’ll write more later :)

→ No CommentsTags:

Boyer – Moore String Search (Good Suffix Shift)

December 7th, 2008 · Computer Science, python

The next string search algorithm I am going to cover seems pretty cool since the match is made in a reverse fashion. We check if the last character in the keyword equals some character in the text and decrease from that point on.As a result, a mismatch is detected extremely fast and this is also the reason why this algorithm is performs beautifully when the keyword is longer.

Now, when a mismatch occurs, the position where we look for the next character is determined by a table of values mapping each character in the keyword to an integer. Example, we find an “a” in the text which at a particular state is sitting atop an M in the keyword, we shift the position in the text by the corresponding number in our table and look again.

Here is how we generate the table:

bcs = {} #the table

def goodSuffixShift(key):

        for i in xrange(len(key)-1, -1, -1):
                if key[i] not in bcs.keys():
                        bcs[key[i]] = len(key)-i-1
 

Next, comes the actual search:

def search(text, key):
       
        i = len(key)-1

        index = len(key) -1

        j = i

        while True:

                print str(i) + ", " + str(j)

                if i == 0:
                        return j #if every character in the keyword matches, return current position in text

                elif j > len(text):
                        return "not found" #if we run out of the string while searching, there is no chance…

                elif text[j] != key[i] and text[j] not in bcs.keys():
                        j += len(key) #If there isn’t a match and we don’t have a switch value in our table, don’t bother looking for characters in the middle and start matching again
                        i = index

                elif text[j] != key[i] and text[j] in bcs.keys():
                        j += bcs[text[j]] #move forward as table says and start looking again
                        i = index

                else:
                        j -= 1 #in case a match is found, check for the character to the left
                        i -= 1

 

Here are some sample runs:

key_list = ["POWER", "HOUSE", "COMP", "SCIENCE", "SHRIPHANI", "BRUAH"]

text = "SHRIPHANI IS A COMPUTER SCIENCE POWERHOUSE"

for key in key_list:
        goodSuffixShift(key)
        print key + " location: " + str(search(text, key))
        bcs = {}
 

The output:

tark-b-120:scripts shriphani$ python boyer_moore.py
POWER location: 32
HOUSE location: 37
COMP location: 15
SCIENCE location: 24
SHRIPHANI location: 0
BRUAH location: not found

You can get the entire script at http://shriphani.com/scripts/boyer_moore.py.

Got to get back to Psychology and GUI stuff in Java. Anyway, GUIs are for losers, CLI FTW !!!

→ 1 CommentTags:

Knuth Morris Pratt String Searching

December 6th, 2008 · Computer Science, python

I found some free time in the midst of extensive preparations ( for the end of semester examinations, I managed to salvage some time to write some Python code (I’ve written so much Java that Python now equals a rub on the temples).

Search:

A parallel comparision is made on the text to be searched and the keyword. That is, we go character by character and check if the ith character in the keyword equals the ith character in the text for i: 0 -> len(keyword). If we encounter a failure in our check, we restart from a particular point in the string which is determined by a table of values which tell us how far we need to backtrack to get the values.

So here is the search algorithm:

#!/usr/bin/env python
#Author: Shriphani Palakodety
#Mail: shriphani@shriphani.com
#Mail2: spalakod@purdue.edu

import make_table

def search(text, key):
        m = 0 #beginning of match in text
        i = 0 #position of the character in key
        t = make_table.makeTable(text) #the table that determines where a search must kick off after a failure

        while m+i < len(text):
                if key[i] == text[m+i]:
                        i = i+1
                        if i == len(key):
                                return m
                else:
                        m = m + i – t[i]
                        if i > 0:
                                i = t[i]

        return "not found"

Here is the snippet that helps backtrack:

#!/usr/bin/env python
#Author: Shriphani Palakodety
#Mail: shriphani@shriphani.com
#Mail2 = spalakod@purdue.edu
#File: make_table.py

def makeTable(text, num_list=[-1,0]):

        position = 2
        cnd = 0

        while position < len(text):
                if text[position – 1] == text[cnd]:
                        num_list.append(cnd +1)
                        position = position+1
                        cnd = cnd + 1

                elif cnd >0:
                        cnd = num_list[cnd]

                else:
                        num_list.append(0)
                        position = position + 1

        return num_list

Now, I’ve got to find more coffee and finish a discrete math worksheet…

→ No CommentsTags:

Life Update

December 1st, 2008 · College, Computer Science, Daily life, python

So, I am now trying to while away time in this totally freaking awesome thanksgiving break when its just too hard to find vegetarian food (I don’t know why people are hell bent on making life difficult for vegetarians, aren’t plants easier to grow than animals?), or people in this dorm. Well, here is a life update — I have managed to get into the A slot (not the A+ though :( ). I applied to an REU and got rejected after which I decided to wait it out and apply for an REU in spring, it sure would be nice to take grad school admissions head on (considering I am still a lazy freshman, I should probably keep that enthusiasm for later).

I’ve managed to make life difficult for TAs by conveniently neglecting to read the homework description. This discrete math class I was in had an assignment on modular arithmetic and it contained the brilliant RSA…… I like this great dude submitted a program and the output to the TA who then told me that I had made life infinitely more difficult for him and that I should have used a pen and paper like everyone else (I hate pens / papers / pencils, I can’t understand what I write myself). Here is the worst RSA implementation in the world: http://shriphani.com/RSA/rsa.html.

Then I applied for an REU and got turned down thanks to the fact that it was just my first semester… anyway, I just hope I manage an A in CS etc…..

Got to get back to finishing a GUI programming assignment, ascend the PE ratings and finish watching 30 rock season two. It is just weird, it is snowing outside and I’ve got a fan running at full blast in my room thanks to our hyperactive heater.

→ No CommentsTags:

Curious Fractions

November 14th, 2008 · Mathematics, python

While suffering from conjuctivitis, fever, a sore throat and what seems to be a case of swollen tonsils determined to make nutrition a pain for the next week or two, I decided to solve a problem on Project Euler. The question I picked was Problem 33: Find all fractions with the given unorthodox cancelling method (just click the fscking link for heaven’s sake!).

I thought this problem can be solved by beginning with a base fraction and adding a numbers in the tens place to both the numerator and the denominator, then adding a number in the units place to the numerator and the denominator, adding to the units place in the numerator and the tens in the denominator and the other way round.

The code needed (in Python2.6 – just love the Fractions module there):

#!/usr/bin/env python
#Author: Shriphani Palakodety
#Blog: http://shriphani.com/blog
#Mail: shriphani@shriphani.com

frac_list = []

from fractions import Fraction

prod = 1

def findLeft(num, den):
    ‘Given a denominator, numerator pair, return the double digit possibilities by appending chars to the left’
    global prod
    for i in xrange(1, 10):
        if i == num or i == den:
            continue
        else:
            if Fraction(10*i+num, 10*i+den)==Fraction(num, den):
                frac_list.append(Fraction(num, den))
                print num,den

def findRight(num, den):
    global prod
    for i in xrange(1, 10):
        if i == num or i == den:
            continue
        else:
            if Fraction(10*num+i, 10*den+i)==Fraction(num, den):
                print num, den
                frac_list.append(Fraction(num, den))

def findAlt(num, den):
    global prod
    for i in xrange(1, 10):
        if i == num or i == den:
            continue

        elif Fraction(10*num+i, 10*i+den)==Fraction(num, den):
            frac_list.append(Fraction(num, den))

        elif Fraction(10*i+num, 10*den+i)==Fraction(num, den):
            frac_list.append(Fraction(num, den))

for i in xrange(1, 10):
    for j in xrange(1, 10):
        if i==j:
            continue
        else:
            findLeft(i, j)
            findRight(i, j)
            findAlt(i, j)

prod = 1
for i in xrange(len(frac_list)):
    if frac_list[i] < 1/1:
        prod *= frac_list[i]

print prod

BTW, it is funny how total nutjobs with no clue about probes, payloads, science or physics take up the job of reporting the Chandrayaan’s progress.

Peace…..

→ 7 CommentsTags: