Friday, October 31, 2014

Changes 10/31/14

Ruby:

  • Began creating a new thread pool prototype which has separate "download" and "parse" threads, to see how this construct might work in the end program

Website:

Thursday, October 30, 2014

Changes 10/30/14

UMD Contest:

Ruby:

  • Clarified a previous blog post with Mr. Elkner.  I clarified why 20.times.each is redundant in ruby.  20.times returns an iterator, and calling .each on that iterator (or calling 20.times.each) just returns itself (the same iterator) again.

Wednesday, October 29, 2014

Changes 10/29/14

UMD Programming:

  • Worked on 2012 UMD programming contest question 1 (page 3 of the link), which involves error detection for 16 bit integers
  • My implementation is here
  • It actually ended up being an easy problem, the hard part was getting used to the environment.  They had a TryTest file which loaded preset integers and their check bits, but it took a while to figure out that this is how I was meant to test my file
  • Since Integer.toBinaryString(int i) doesn't allow you to specify the expected bits, I figured that I should append the missing zeros to the front, so an integer like 42 would return "0000000000101101" and not "101101".  In Python or Ruby, you could just do "0" * (16 - binary_string.length) + binary_string, but there is no way to do a string operation like this in Java as far as I could tell.  
  • I ended up writing a whole separate method to prepend the missing zeroes.  
  • In hindsight, I actually wasted a lot of time doing this, because only the ones are counted anyway.  Using the method I painstakingly created ends up being functionally equivalent to just calling Integer.toBinaryString(int i).
  • Line 11 can be replaced with Integer.toBinaryString() for an identical result.
  • I think my performance on this problem would have really benefited from a plan, rather than just jumping right in.  If I had thought about it more, I would have realized that Integer.toBinaryString() is sufficient for finding the number of '1's present in a binary integer.

Tuesday, October 28, 2014

Changes 10/28/14

Java:

  • Did the first Stringlist activity, where you are essentially creating a string-like class that follows the ADT list interface.  
  • I was unhappy because it forced me to use string concatenation where a StringBuilder would have been much more efficient.  
  • The underlying store of character data in the eimacs implementation was a String. Replacing this String with a StringBuilder make much more sense, as the object's implementation of List interface methods like #add() and #set() suggests that the underlying data will be modified quite a bit.
  • I also had some trouble during that activity because I couldn't figure out how to get the length of a string.
  • This caused me to realize that Java's naming conventions are really counter intuitive, and place too much emphasis on implementation details. 
    • To get the length of an array, you call Array[].length;
    • To get the length of a String, you call String#length();
    • To get the length of a List, you call List#size();
  • The reason I took 10 minutes trying to figure out how to get the length of a string was because I falsely remembered that you didn't need brackets after it.  A programmer really shouldn't need to care that the length of an array is a static field while the length of a String is a method, but Java forces you to know that because you must put brackets after #length when calling it on String.
  • Then, they take this and just throw it all out when implementing ADT list, making it #size() instead.  I was also falsely under the impression that the naming convention was .length when the length is a static field and #size() when the length must be found using a method, but this is not the case.
  • If I was using Eclipse or IntelliJ, I would have figured this out right away, but the eimacs web interface doesn't have tab completion. 

Life Skills:

  • Learned how to order pizza online, which I had never done before.  People were kinda mean about it though, and acted like I was stupid for not knowing exactly how to do my first time.
  • Learned that the Dominos website shows you coupons, which I guess is to make you feel like you are spending less on pizza.  One coupon cut our order from $30 to $20, and that $20 seems like much less when compared to the $30 than it might if that was the original order price.
  • I'm assuming that's what their going for, because it's kinda stupid that you can get the exact same order for a drastically different price depending on whether you click on the site a couple of extra times or not

Monday, October 27, 2014

Changes 10/27/14

Java:

  • Worked on some more exercises out of eimacs.  
  • Started working on a string class called StringList that implements the interface of a list.  However, it's stupid because they are making it extremely inefficient for the sake of simplicity, so methods such as #add() and #set() use the + operand on a string, so a new string must be returned for each operation.  This makes me not even want to bother writing it, because it's a really stupid design.

Saturday, October 25, 2014

Changes 10/23/14 (at NSF meetup) and 10/25/14

NSF Stuff:

  • Kevin showed me a really interesting video where a C# API developer wanted to make his interface very understandable, and to do this was trying to avoid returning null in a method to try to read a string from a file.  He felt that this would be inconsistent with the rest of his interface, as other methods that returned strings were guaranteed to not be null.  
  • He went through various different approaches, which should hold true (to some extent) in any language.
  • What he settled on was returning a Maybe, a collection guaranteed to have either 0 or 1 elements: 0 elements if the file couldn't be read, and 1 if it could, where the element was the string.  This way, he could write code to handle a case with 0 elements much more fluidly than just having a null check.
  • I also learned some stuff about C#!
  • I guess the string data type is a primitive, because it was written as "string" when declaring the return type for his methods.  If my memory is correct, I think you can write it as String as well.
  • I also learned about the out parameter in C#, which was used in one of the approaches to the problem, albeit one that the guy in the video didn't like.  It's still useful to know that you could have a specific variable be modified by a separate method, though.  I think that's pretty cool.

Ruby:

  • Updated code and committed to repo.
  • Fixed ThreadPool#join_all so that it works correctly.
  • Now, when called, it sets the finished flag to true, then does one of two things:
  • If there are still elements in the task queue, Thread#join is called on each of the worker threads.  Since the finish flag is now true, each worker thread continues to work as normal, but will abort once it completes a task and finds the task queue to be empty.  Once all worker threads have completed tasks and found the queue to be empty, the #join_all method will release the lock on the thread it is called in (the main thread, most likely) and the program can continue on.
  • If the task queue is empty when #join_all is called, ThreadPool#kill_all is called, which terminates all worker threads.  This prevents a deadlock where all the threads are waiting on the queue already, and therefore never check to see that the finished flag has been set to true.
  • I also cleaned up some things in the code, and learned some stuff along the way!
  • I had a while loop that was something like
    int i = 0
    while i < 20 do
      ...
      i+=1
    end
    However this is very un-ruby like.  I changed this to be
    20.times do |i| 
      ...
    end
    which is much cleaner and easier to read.  In doing this, I also realized that I had code that read:
    some_integer.times.each_with_index do |i|
    which is just awful. It can be rewritten with the exact same functionality as
    some_integer.times do |i|
    . I'm not sure why I thought I needed to call #each on that, let alone #each_with_index! (If #each is redundant, #each_with_index is doubly redundant because you are already using the integer as an index, so getting the index of that index makes no sense)

Thursday, October 23, 2014

Changes 10/23/14

Java:

  • Finished lesson on LinkedLists.
  • It was informative, they showed how adding a ListNode#getPrevious method and tail variable allowed much faster access to elements more than halfway into the list, since the list could now be iterated both backwards and forwards.
  • Learned about iterators, which optimize the traversal of lists based on what kind of list it is.  For example, a LinkedList iterator prevents you from needing to call LinkedList#get(i) when traversing, since #get() is an O( n ) operation.
  • For each loops in java (ex: for (Object o : list) ) actually use iterators when traversing
  • Learned about ListIterators, a subset of iterators that add more methods like #previous(), #add(E x) which adds at the current iterative position, and #set(E x) which sets the current item to x.  E is a generic type, meaning that the user sets the actual type when creating the list.  As an example, LinkedList<String>() would cause E to be a String.