Tuesday, January 13, 2015
Changes 1/13/15 - EIMACS Trees
Today I learned about binary trees, which are a lot like LinkedLists (in the implementation EIMACS is using) except that they have two "next node" values instead of just one: a left and a right value. This means that pretty much every method I've had to code for the exercises so far has been recursive.
Monday, January 12, 2015
Changes 1/12/15 - Liskov corrections, Bottle stuff
After the post I made on Friday (1/9/15), Kevin emailed me to clarify some Liskov Substitution stuff.
First of all, shout out to Kevin for reading my blog:

He wanted to make sure it was clear that you need to look at the specification rather than the implementation of a method in order to verify that a subclass method does not violate the LSP.
Kevin gave three examples of the same method with different specification. In the first two examples, #get_number has been stubbed out (given a return value that fits its expected behavior without actually containing any functionality). We need to look at the specification for the method, not the implementation, for clues on obeying LSP.
Implementation 1:
In this example, it is easy to define a subclass that obeys the LSP - you just need to implement it such that the range of possible outputs for #get_number is less than or equal to the numbers 0 to 100.
Implementation 2:
Just like in Implementation 1, a subclass overriding #get_number would need to take into account the specification given in the method.
Implementation 3:
In this example, it is impossible to determine what is expected of a subclass' overridden method--there is nothing to go off of. This is very bad! Obviously the method is expected to be overridden but offers no other information.
Also, for the record, I didn't come up with all this on my own, I pretty much just paraphrased Kevin's email. I think I definitely understand the concept better now.
He also put this in the email, and I thought it was worth sharing:
Today I also helped Aki and Dylan with some Bottle stuff. They're trying to push HTML form data into an sql database using Bottle, which is something I did in math-drill last year. I showed them my code as an example, but unfortunately it's a bit more complex than what they need. My code actually generates the form using python, which isn't something they need to worry about and just makes it harder for them to understand. If they need my help, hopefully they'll ask...
First of all, shout out to Kevin for reading my blog:
He wanted to make sure it was clear that you need to look at the specification rather than the implementation of a method in order to verify that a subclass method does not violate the LSP.
Kevin gave three examples of the same method with different specification. In the first two examples, #get_number has been stubbed out (given a return value that fits its expected behavior without actually containing any functionality). We need to look at the specification for the method, not the implementation, for clues on obeying LSP.
Implementation 1:
In this example, it is easy to define a subclass that obeys the LSP - you just need to implement it such that the range of possible outputs for #get_number is less than or equal to the numbers 0 to 100.
Implementation 2:
Just like in Implementation 1, a subclass overriding #get_number would need to take into account the specification given in the method.
Implementation 3:
In this example, it is impossible to determine what is expected of a subclass' overridden method--there is nothing to go off of. This is very bad! Obviously the method is expected to be overridden but offers no other information.
Also, for the record, I didn't come up with all this on my own, I pretty much just paraphrased Kevin's email. I think I definitely understand the concept better now.
He also put this in the email, and I thought it was worth sharing:
Today I also helped Aki and Dylan with some Bottle stuff. They're trying to push HTML form data into an sql database using Bottle, which is something I did in math-drill last year. I showed them my code as an example, but unfortunately it's a bit more complex than what they need. My code actually generates the form using python, which isn't something they need to worry about and just makes it harder for them to understand. If they need my help, hopefully they'll ask...
Friday, January 9, 2015
Changes 1/9/15 EIMACS and more NSF meetup stuff
Sam, Finn, and I took EIMACS test 23, which was on Sets and Maps. It was pretty easy.
At NSF, Kevin and I also talked about something he had asked earlier, which was about the EIMACS ListQueue class. This is the earlier blog post I had written. When I was thinking of the answers to his questions, I was assuming that the implementation of ListQueue was empty (the first implementation I listed in this post), whereas Kevin was thinking of the second implementation listed in that post, where methods of LinkedList are actually overridden.
It turns out that the class, even with the listed overriden methods, does fulfill the Liskov substitution principle, because the re-implemented methods have the exact same functionality as the parent methods as defined in LinkedList.
Kevin also mentioned that in order to fulfill this prinicple, the range of valid inputs for your method should be larger than that of the method you are overriding, while the range of outputs should be the same or smaller than the overridden method. This prevents code that is using your object as though it is its superclass (for example, calling code expecting a LinkedList<Object> and passing in a ListQueue) from being "surprised" by differences in functionality.
A concrete example of this:
The NarrowNumberGenerator has a narrower range of outputs (0 to 5 inclusive) than its parent, so a class which uses a NarrowNumberGenerator in place of a NumberGenerator doesn't need to worry about the differences in behavior. All the outputs of NarrowNumberGenerator are also valid outputs of NumberGenerator.
At NSF, Kevin and I also talked about something he had asked earlier, which was about the EIMACS ListQueue class. This is the earlier blog post I had written. When I was thinking of the answers to his questions, I was assuming that the implementation of ListQueue was empty (the first implementation I listed in this post), whereas Kevin was thinking of the second implementation listed in that post, where methods of LinkedList are actually overridden.
It turns out that the class, even with the listed overriden methods, does fulfill the Liskov substitution principle, because the re-implemented methods have the exact same functionality as the parent methods as defined in LinkedList.
Kevin also mentioned that in order to fulfill this prinicple, the range of valid inputs for your method should be larger than that of the method you are overriding, while the range of outputs should be the same or smaller than the overridden method. This prevents code that is using your object as though it is its superclass (for example, calling code expecting a LinkedList<Object> and passing in a ListQueue) from being "surprised" by differences in functionality.
A concrete example of this:
The NarrowNumberGenerator has a narrower range of outputs (0 to 5 inclusive) than its parent, so a class which uses a NarrowNumberGenerator in place of a NumberGenerator doesn't need to worry about the differences in behavior. All the outputs of NarrowNumberGenerator are also valid outputs of NumberGenerator.
Thursday, January 8, 2015
Changes 1/8/15 - UMD Contest and Laptop Issues
I was having laptop issues in class today. Since my laptop is really a tablet, it has a battery in the tablet itself and a second battery in the keyboard. The keyboard battery was at 0% and the tablet would try to switch to the keyboard battery and instantly shut off since it had no power. Jack helped me out by removing the tablet battery, which let us see a boot message that said the power adapter I was using wasn't outputting enough voltage for the computer. So thanks, Jack.
Also, at NSF I talked with Kevin and Sam about UMD problem #5. The solution given makes use of a data structure called a directed graph, which can be used to find the shortest path between data points. This is important because the problem asks you to predict the outcomes of battles between Avengers (and Catwoman, I mean come on what were they thinking? Get it straight, UMD!) based on their past battles. So basically, if Thor beats Loki and Loki beats Catwoman, the algorithm should show Thor beating Catwoman. Directed graphs make this possible.
Tomorrow I will try to look into the code behind the UMD solution, as well as take EIMACS test 23.
Also, at NSF I talked with Kevin and Sam about UMD problem #5. The solution given makes use of a data structure called a directed graph, which can be used to find the shortest path between data points. This is important because the problem asks you to predict the outcomes of battles between Avengers (and Catwoman, I mean come on what were they thinking? Get it straight, UMD!) based on their past battles. So basically, if Thor beats Loki and Loki beats Catwoman, the algorithm should show Thor beating Catwoman. Directed graphs make this possible.
Tomorrow I will try to look into the code behind the UMD solution, as well as take EIMACS test 23.
Wednesday, January 7, 2015
Changes 1/7/15 - UMD Contest problem
I'm starting to piece through number 5 on the 2012 UMD contest problems. First of all, Catwoman is not a Marvel character, so I don't know why they're fighting her. I also don't know how to do the problem. It's just really hard to visualize how to do what they are expecting me to do.
I'm focusing on doing the easier stuff first, so right now my code can determine the winner if the two combatants have already directly fought.
I'm focusing on doing the easier stuff first, so right now my code can determine the winner if the two combatants have already directly fought.
Changes 1/6/15 - canvas_spritesheet optimizations
Since the second half of the Snoop Dogg gif I'm using for my spritesheet is simply the reverse of the first half (in order to make it loop the creater put part of a video back to back with the reverse of that video), so the spritesheet can be cut in half by setting the frame counter to increment up to the final frame, then decrement back down to the first frame.
canvas_spritesheet.html
canvas_spritesheet.html
Monday, January 5, 2015
Changes 12/24/14 - 1/4/15 (Winter Break) - Javascript Canvas stuff
On my website, ahirschberg.github.io, if you click the button that says "Wot's this, m8?", images and gifs will start to shake across the screen. However, these elements are shaken by updating their positions on the page, which is pretty inefficient when being done over and over again for a large number of elements.
Last year, I had worked on a page that tested the basics of shaking an image using a canvas. It wasn't very impressive and didn't really capture what I was trying to do. Over winter break I started to work on a page that properly shook the images within the canvas.
This method of changing an image's position is much more efficient than my previous method of actually creating an image element and directly updating its position. For example, my computer at home can handle about 50 canvases all shaking elements, while it would start to lag long before that number of elements was reached directly updating image positions in the DOM.
Please try out the different buttons on the page and see what they do!
The main limitation of this method is that gifs no longer render past the first frame because javascript doesn't offer an easy way to choose which frame in a gif is drawn to a canvas using the drawImage() method. A lot of the shaker elements are gifs, so that's a big problem.
In order to help the viewer visualize this, I added a canvas below the main animation which illustrates the bounds of the spritesheet currently being drawn to the canvas.
Please try out the different buttons on the page and see what they do!
Last year, I had worked on a page that tested the basics of shaking an image using a canvas. It wasn't very impressive and didn't really capture what I was trying to do. Over winter break I started to work on a page that properly shook the images within the canvas.
canvas_shake2.html
It generates a set number of canvases (at the time of writing it's 10, but on the actual implementation it will probably be higher). Each of these canvases is assigned a random image from a pool of possible images. A tick function called using the javascript setInterval() function updates the canvases every 30 milliseconds. Each frame loads the image at a different position:Please try out the different buttons on the page and see what they do!
The main limitation of this method is that gifs no longer render past the first frame because javascript doesn't offer an easy way to choose which frame in a gif is drawn to a canvas using the drawImage() method. A lot of the shaker elements are gifs, so that's a big problem.
canvas_spritesheet.html
To work around this limitation, I started working on a canvas implementation that would create an animation using a spritesheet, an image with all the frames of a gif lined up like a film strip.
Please try out the different buttons on the page and see what they do!
Also, if your sound isn't on, turn it on! I set up the javascript so that it seamless(ish)ly loops a part of a song.
For both of these pages, there's a link to the proper github page where you can see the relevant code with proper syntax highlighting.
Subscribe to:
Posts (Atom)
