Monthly Archives: March 2012

CS371p: Making Studying Fun

One of the reasons I am able to survive in Computer Science is that I can study while also sating my short attention span.  Playing with the compiler and trying every permutation of const, int, *, and & is not the most pleasurable way to spend an afternoon studying for an exam, but it is as much a necessity as practicing flash cards in another human language.  Also, it’s certainly more engaging than studying diagrams of protein blobs cooperating with each other to move around a cell, which is what a lot of studying Biology was like, back when that was my major.

If I am having particular trouble with a concept, I sometimes try to engineer my own ways to study.  For example, I have had trouble getting C++ constructors and destructors to stick in my head, so I borrowed from Professor Downing’s quiz structure to make a little environment where I can try out different things:

#include  // cout, endl

using namespace std;

struct A{

	A(double d){ cout << " "; }

	A(){ cout << "p"; }

	A(int i){ cout << "r";}

	A(char a) { cout << "o"; }

	A(const A&){ cout << "g";}

	A(double* dp){ cout << "r";}

	A& operator = (const A&){ cout << "a"; return *this;}

	~A(){ cout << "m";}

	};

 struct B : A{

 	B(){ cout << "i"; }

 	B(int x){ cout << "n";}

 	~B(){ cout << "q";}

 	};

 struct C{

 	C(){ cout << "g";}

 	C(double* dp){ cout << "s" ;}

 	~C(){ cout << "f"; }

 	C(const C&){ cout << "u" ;}

 	C& operator = (const C&){ cout << "n";}

 	};

 struct D : C{

 	D(){ cout << "k"; }

	D(double* dp){ cout << "!";}
 };

 int main (){
 	{
 	const std::size_t s = 4;
 	B b = B(); 	
 	A abs[s] = {B(), B(), A(3)};
 	}
 	{
 	double d = 1.0;
 	double* dp = &d;
 	D dd = D(dp); 		
 	C c = C();			
 		{
 		D dee = dd;
 		dd = D(dd);		
 		}
 	}					
 	cout << endl;
 	return 0;

 }

 }

After spending more than an hour trying to elegantly print “programming is fun” using as few calls to constructors as possible, I eventually gave up and just started typing random calls and trying to guess what non-sequiturial character sequence would display.
The above main method surprised me with its output.  I originally expected the following:

  1. the call to B’s default constructor is interrupted by a call B’s parent’s default constructor, A, outputting “p”, then “i” when B is returned to, then A’s default destructor is called, outputting “m”; total output is “pim”
  2. the same series of calls as 1 happens twice, then A(3) is called, outputting “r”, then A() is called once more, outputting “p” to fill the array; total output is “pimpimrp”
  3. at this point there are 3 Bs and 2 As, and they are going out of scope, so destructors will run for all 5; total output is “qqqmm”
  4. the next constructor call is to D’s double* constructor which is interrupted by C’s double* constructor, which produces “g”; next, a new D is produced, which outputs “!”, and finally C’s destructor runs, outputting “f”; total output is “g!f”
  5. a C is made, outputting “g”
  6. a smaller scope is created and a new D, dee, is initialized and assigned to dd; this runs the D default constructor, which calls the C default constructor, producing “g”, followed by “k” for D() and “f” for ~C().  Then, the copy constructor for D is called, which is the inherited copy constructor from C, which first outputs “n” because of the copy assignment operator, and then “u” from the copy constructor itself.  Finally, a destructor for D is called, which calls on ~C and outputs “f”; total output is “gkfnuf”
  7. dd is reassigned to a copy of itself; this calls the copy constructor, which calls the copy assignment operator which together produce “nu”; then a destructor is called on the former dd, outputting “f”;  total output is “nuf”
  8. the two Ds go out of scope, calling ~C() twice and outputting “ff”
  9. c and dd from the inner scope within main get destroyed when this scope is exited; this calls C’s destructor twice and produces “ff”

If my initially evaluation was correct, the output would be pimpimpimrpqqqmmg!fggkfnufnufffff but in actuality it was:

pipigqmpigqmrpmmmmqmg!guunffff

It appears I have some studying to do.

Lessons from Spiceworks

Friday was my last day as a Software Engineer in Test Intern at Spiceworks.  If I wanted to work in Austin as a software tester, I absolutely would have stayed, but it is not a pursuit I currently have in mind.  I recommend anyone looking for a software internship in Austin to consider applying there. It was a memorable, influential experience and I am grateful to the company for providing me with the opportunity.   I learned a lot there, which I want to put into words.

Understanding the Company   

At Spiceworks, no matter what role you play, you have to understand the high-level mission of the company to some degree.  At its core, Spiceworks is two goals cohered together: to provide free high-quality network monitoring software and to provide a niche social network for IT professionals to interact.  My job was to help test the “Community” side which is a sort of Facebook-esque forum.  I wrote and edited automated tests using Ruby and Watir (Web Application Testing In Ruby) within the Rails framework.

Understanding my Role

After a part of the site is released or updated, a manual tester goes through the different potential user flows and tries to discover bugs.  Then, a software engineer automates those tests, writing out the flows so that they can be run nightly as regression tests.  I only did this once, and it took me the duration of Winter break.  Most of my time at Spiceworks was spent editing regression tests that had already been written and were failing due to an ID change in the DOM or the addition of a lightbox somewhere.  Occasionally the changes were more complex, such as when the user profile pages were overhauled, but most of the changes were minute.

For several reasons, there were many nonworking Community regression tests when I began working for the company in November.  While the Community and the monitoring software are both crucial to Spiceworks, development priority seems to be given to the software, and deservingly so.  Most (or at least, a very large portion) of the Community members also used Spiceworks to monitor the network where they worked, and if the monitoring software they are using doesn’t work, they have no reason to go to the Community and talk about the product.  More importantly, while the Community tests were breaking, they were usually due to subtle errors that rarely affected user experience.  Nonetheless, they needed to be fixed, making them the perfect job for an intern.

Ruby is Fun and Powerful

In a nutshell, my job was to look at static HTML in Internet Explorer and prod the page to make it simulate a user’s experience.  This is performed by wrapping a browser and manipulating it like you would any object.  I performed experimentation using interactive Ruby (irb) to make sure my code worked before putting it in the unit test file itself.  It can be a real game to find the most reliable and efficient way to identify an object.  For example, after using Watir to make a browser object that represents your IE instance, you can do something like:

ie.div(:class, “Jeff”).link(:id, “blog”).click

You can also use regular expressions:

ie.link(:text, /Jeff’s Blog/).click

While seemingly elegant, this is frequently a more volatile approach than going through the DOM tree because the order that text appears on a page can be nondeterministic when dealing with forums.  If there was a hyperlink with the text “Jeff’s Blog” at the bottom of the page, and someone made a post above it containing a hyperlink with the text “This page is not Jeff’s Blog”, the latter would be selected.

If I do any HTML scraping in the future I will probably use Watir because I find the syntax very intuitive.  The trickier issues arise when you want to do advanced things like mess with a predictive search bar, binary search a list of pages, or tinker with Javascript.

Creative Scope

Many people including myself select a career as a programmer because they want a job with creative freedom and individuality.  In contrast to this, working at a company usually puts you in a position where team members rely on you to act predictably so that they can black-box whatever project dependency you are working on and assume it is going to function.  I felt valued at Spiceworks because once I had proved I was reliable enough to fix small problems during my first couple months, I asked for and was provided a bigger assignment that allowed more creative freedom.  I got to spend Winter break writing my own test.  It was some of the most gratifying programming I’ve done, and since it was from scratch, I got to automate it however I wanted to.

The Value of Culture

As a company full of tech-savvy people making software for an audience of tech-savvy people, Spiceworks derives a lot of value from being human and outwardly facing.  This symbiosis between Spiceworks employees and product users requires a consistent, positive image that’s only attainable by being a great place to work.

I’ve thought a lot about whether a stated company culture shapes the personality of its employees or rather if the company personality is a natural composition of that of its employees.  I know at least the first is true; Spiceworks has left a lasting impression on me.

CS371 Week 6

On Wednesday, Chris and I began the day with Allocator mostly finished, except for the bulk of our testing. What this translates to in reality is that Chris and I were halfway done with the Allocator project. The concept of using the dummy class to test functions that are otherwise untestable was an invaluable learning experience, though we could have used more guidance about it.  That’s the cost of going out of town and missing class.

Much of the week has been spent learning about const, *, and &, and the attributes they give a variable based on how they are permuted during declaration and initialization.  It reminds me of the symbolic logic class I had in the exact same room several years ago.

Compelled by the shame of incorrectly answering two basic questions about arrays in class on Friday, I want to take a moment to review some things about them.

1. You can declare the size of an array by saying:

int[] revelation = new int[5];

2.  Arrays are objects in Java, and they go on the heap.

I’ve been developing a text-based game and have been amazed at how much this class has improved my approach to design. There is less overambitious hacking and more humble JUnit assertion. Fewer self-addressed e-mails of copy/pasted code and more git commitment. Less // and more /*. I didn’t even feel a twinge of pain when I forced myself to spend several hours refactoring my classes into packages, rather than the maligned “throw everything into src” approach.

I used Piazza.randomPartner() to find someone to work on for this assignment, following some advice I read that said I should work with new people instead of those I already know in order to gain more insight into the programming practices of others.