In my last post, I mentioned using index cards to write down the past qualifying exam questions. And I did indeed write about 50 of them before saying, you know what, screw this.
I'm now putting them into Access. You can't easily represent formulas in Access, so what I've done is set it up so that I put in TeX code for the problem statements, and then I wrote some code in Access so that it will spit out a TeX file with my problems (in a variety of orders).
I feel pretty awesome about that, and I've now entered about as many problems as I had written on index cards. The process is much faster and the results are way better.
Go me!
Showing posts with label computer science. Show all posts
Showing posts with label computer science. Show all posts
Wednesday, May 18, 2011
Thursday, July 16, 2009
Stupid Consultant Tricks
A couple of weeks ago, I finished up the beta version of a data importer that a client (the representative of whom I'll call "Rick") had asked for. Specifically, he wanted a way to automate monthly well production and test data imports from their oilfield management software into their reserves database for Aries (the economics software we use). Rick asked "Jim" (one of the engineers I work for) if we could whip something like this up for them, and Jim asked me, because he knows I can do tricky technical/coding things.
It was a pretty fun project. They sent us sample data in Excel, and I learned enough VBA to write a nice little program in Access. Basically, you click a button to start the import, and it asks you where the Excel file is, sucks the data in, determines what data is duplicate and what data is new, asks you if you want to update existing records, then if you want to add new records, does all of those things, and outputs a form of log letting you know exactly what was done.
Unfortunately, after Rick (the client) had a chance to play with what we sent him, he sent Jim this email:
And at first I felt quite annoyed with Rick. Why the hell would you send sample data in Excel if you weren't intending to import the data from Excel? I mean, I worked with what I was given. Stupid client!
But, no. This is actually my fault. I mean, I have most of an entire degree in software engineering. I know better than to just go off half-cocked and write a bunch of code without doing even a minimal amount of requirements engineering. (It's probably not appropriate to write up an entire set of requirements for this project, but a simple email to the client clarifying his needs would have been prudent.) It is not the client's job to know how to unambiguously ask for what he wants.
Stupid consultant! ;-)
It was a pretty fun project. They sent us sample data in Excel, and I learned enough VBA to write a nice little program in Access. Basically, you click a button to start the import, and it asks you where the Excel file is, sucks the data in, determines what data is duplicate and what data is new, asks you if you want to update existing records, then if you want to add new records, does all of those things, and outputs a form of log letting you know exactly what was done.
Unfortunately, after Rick (the client) had a chance to play with what we sent him, he sent Jim this email:
Looking back on our initial email, I thought we were looking at a loading process from our production database into the Aries database. Both are in Access so it would seem that there should be a way to link the tables with some type of load query. Your current load process is workable for other areas but it would be a huge benefit if the we could do this loading internally within Access.Apparently what he had wanted was an import from one Access database to another, not from Excel into Access. Although this is not a gigantic change, and is in some ways easier to code, it wasn't what I thought we were doing.
And at first I felt quite annoyed with Rick. Why the hell would you send sample data in Excel if you weren't intending to import the data from Excel? I mean, I worked with what I was given. Stupid client!
But, no. This is actually my fault. I mean, I have most of an entire degree in software engineering. I know better than to just go off half-cocked and write a bunch of code without doing even a minimal amount of requirements engineering. (It's probably not appropriate to write up an entire set of requirements for this project, but a simple email to the client clarifying his needs would have been prudent.) It is not the client's job to know how to unambiguously ask for what he wants.
Stupid consultant! ;-)
Tuesday, March 10, 2009
The One We Left Blank
Last week, I had a test in Principles of Programming Languages. I knew I wasn't fully prepared, but I had gone through my notes and looked for ways to review the things I would have to do on the test. (The whole test was "do this" types of questions - no factual questions at all. It was nice, actually. And it was open notes.)
The last question on the test was about recursive descent parsing. We were supposed to write some code to go with some existing code to do a little piece of it, and I just...couldn't. I couldn't figure out how to access the variables I would have needed from the code block I was to write, and I wasn't sure how it was supposed to work anyway. I wrote a couple of lines and then gave up, essentially leaving it blank. Time was up anyway - I had spent most of the two-hour class period doing the first 7 problems.
So I was expecting a B.
Last night, when I got the test back, I had scored 55/56, or 98%.
"I didn't grade Question 8," the professor said. "By the time I got there I was just like ... eh. This is enough. No, not really. It's just, I looked, and most of the answers were blank. And the rest were...varying degrees of pseudocode that...yeah. So I decided not to grade it."
It seems fair. Our class has no textbook or any other kind of outside material. If basically nobody can make a decent attempt at answering a test question, it seems likely that you didn't actually teach the material.
And, of course, I was personally pleased to be one of many fuck-ups rather than an individual unique fuck-up.
The last question on the test was about recursive descent parsing. We were supposed to write some code to go with some existing code to do a little piece of it, and I just...couldn't. I couldn't figure out how to access the variables I would have needed from the code block I was to write, and I wasn't sure how it was supposed to work anyway. I wrote a couple of lines and then gave up, essentially leaving it blank. Time was up anyway - I had spent most of the two-hour class period doing the first 7 problems.So I was expecting a B.
Last night, when I got the test back, I had scored 55/56, or 98%.
"I didn't grade Question 8," the professor said. "By the time I got there I was just like ... eh. This is enough. No, not really. It's just, I looked, and most of the answers were blank. And the rest were...varying degrees of pseudocode that...yeah. So I decided not to grade it."
It seems fair. Our class has no textbook or any other kind of outside material. If basically nobody can make a decent attempt at answering a test question, it seems likely that you didn't actually teach the material.
And, of course, I was personally pleased to be one of many fuck-ups rather than an individual unique fuck-up.
Friday, February 13, 2009
Clever Programming
There are certain programming language features that my Principles of Programming Languages professor disapproves of. For instance, in C (and, to a slightly lesser extent, Java), the operator
will do the something if a is equal to b, and not otherwise. On the other hand, the operator = sets one value to be equal to another. For instance,
However, the
This sets a equal to b and does something if b was true. Unfortunately, it also leads to rampant errors, because when people type
So, my professor is against using
I would be saying "If k is equal to three (and, by the way, after you do that, increment k by 1)..", but if I wrote
I would be saying "Increment k, then if it's equal to 3..."
Clever! It saves you a whole line of code, and makes your code harder to maintain and more error-prone at all once!
A guy in my class (who looks like a young, evil Vincent D'Onofrio) argued back, saying that he always uses such methods when possible. He argued that anyone who knows the language should be able to read a statement like
so that he is not worried that it won't be understood. He doesn't work with CS1 students, after all. Someone who wouldn't understand these basic language features is worthy only of contempt, he suggested.
What I think he's missing is that maintenance makes up most of the costs associated with code, and every time that it takes someone 10% longer to read a line of your code, or even 5% more likely to make an error in maintaining it (not to mention your own increased chances of error in writing it), it un-pays for itself. And what was the benefit to begin with? Occasionally getting to skip some typing? Feeling clever by combining statements?
I think it's foolish.
== is used to compare two things. For instance,if (a == b) {
(do something)
}will do the something if a is equal to b, and not otherwise. On the other hand, the operator = sets one value to be equal to another. For instance,
a = b will take the value in b and store it in a.However, the
= operator also returns the value of b, so if you want to be clever, you can do something likeif (a = b) {
(do something)
}This sets a equal to b and does something if b was true. Unfortunately, it also leads to rampant errors, because when people type
if (a = b) they almost always meant if (a == b), and if = did not return a value, then the compiler would let you know you were making a mistake.So, my professor is against using
= in an if statement; it's the kind of clever thing that leads to mistakes. He also inveighs against things like using the ++ operator in an expression. If you write a++ it will increment a by 1 (so it is the same as a = a + 1). No problem there. ++a does the same thing. But where they are different is that they each return a value, but ++a increments a before returning it, and a++ increments it after returning. So that if I said something likeif (k++ == 3)I would be saying "If k is equal to three (and, by the way, after you do that, increment k by 1)..", but if I wrote
if (++k == 3)I would be saying "Increment k, then if it's equal to 3..."
Clever! It saves you a whole line of code, and makes your code harder to maintain and more error-prone at all once!
A guy in my class (who looks like a young, evil Vincent D'Onofrio) argued back, saying that he always uses such methods when possible. He argued that anyone who knows the language should be able to read a statement likeif (a = ++k)so that he is not worried that it won't be understood. He doesn't work with CS1 students, after all. Someone who wouldn't understand these basic language features is worthy only of contempt, he suggested.
What I think he's missing is that maintenance makes up most of the costs associated with code, and every time that it takes someone 10% longer to read a line of your code, or even 5% more likely to make an error in maintaining it (not to mention your own increased chances of error in writing it), it un-pays for itself. And what was the benefit to begin with? Occasionally getting to skip some typing? Feeling clever by combining statements?
I think it's foolish.
Thursday, January 22, 2009
New Classes
Since my new classes started yesterday, here is a brief overview.
Higher Geometry II
This course covers affine and projective geometry. Last night we went over groups, abelian groups, and fields, which are abstract algebra concepts. (A field, which is the highest level of this particular hierarchy, is something like the real numbers - a set with two operators comparable to addition and multiplication, with associativity, commutativity, distributivity, identities, and reciprocals.) The prof (a grad student) told us not to worry if we felt like we were drinking from a firehose. He called this "Abstract Algebra in an hour."
15% of our class grade will be based on problems that we individually present in class, 15% on problems that we turn in, 25% on a paper that we have to write (15% for the paper, 10% for a presentation based on the paper), and the remainder on the three exams (no cumulative final). For the exams, we have a choice of take-home (several new problems) or oral (problems from the book or handed out in class), and we have to choose an oral exam for at least one of them.
Oral exams and all of the presentations are graded as Perfect (100%), Good (95%), Fair (75%), or Poor (35%). He suggested that he will not be very harsh with the grading and if you do a decent job you will probably get the 95%.
Principles of Programming Languages
This is an upper-division CS course, pretty standard at most schools, that discusses the different paradigms of programming languages, their features, and something about their implementation. The professor was funny and charming.
There will be 7 coding assignments that will take about 2 weeks each. These are graded pass/fail, and at the deadline we must have turned in a "serious effort." He'll give it back and if he requests additional work or fixes on it, we have a week to turn it back in with the fixes. These coding assignments are worth 7 points each for the total course grade. The remainder of the points come from 3 exams (again no cumulative final) that are worth 17 points each.
Apparently the professor used to let people turn in their assignments whenever, but he discovered (unsurprisingly) that this just encouraged students to prioritize classes that did have deadlines. So now, barring "both of your grandparents dying in a horrible blimp accident [and if anyone's grandparents have died in a horrible blimp accident I'm sorry, didn't mean to be insensitive]" he'll only accept one assignment up to a week late per student.
There is no textbook for this class. He's used several, including (many times) the most popular one, by Sebesta, but he finds that he uses them mostly to make fun of how bad and wrong they are. Also, he said that for us having a textbook just means thinking, "Oh, there's this thing I should be reading, but I don't." And that sounds about right; I haven't actually read a CS textbook yet. He plans to attempt to produce whatever materials he wants us to read, which will be necessarily brief given that he has to produce them.
It's going to be a fun but difficult, I think, semester.
Higher Geometry II
This course covers affine and projective geometry. Last night we went over groups, abelian groups, and fields, which are abstract algebra concepts. (A field, which is the highest level of this particular hierarchy, is something like the real numbers - a set with two operators comparable to addition and multiplication, with associativity, commutativity, distributivity, identities, and reciprocals.) The prof (a grad student) told us not to worry if we felt like we were drinking from a firehose. He called this "Abstract Algebra in an hour."
15% of our class grade will be based on problems that we individually present in class, 15% on problems that we turn in, 25% on a paper that we have to write (15% for the paper, 10% for a presentation based on the paper), and the remainder on the three exams (no cumulative final). For the exams, we have a choice of take-home (several new problems) or oral (problems from the book or handed out in class), and we have to choose an oral exam for at least one of them.
Oral exams and all of the presentations are graded as Perfect (100%), Good (95%), Fair (75%), or Poor (35%). He suggested that he will not be very harsh with the grading and if you do a decent job you will probably get the 95%.
Principles of Programming Languages
This is an upper-division CS course, pretty standard at most schools, that discusses the different paradigms of programming languages, their features, and something about their implementation. The professor was funny and charming.
There will be 7 coding assignments that will take about 2 weeks each. These are graded pass/fail, and at the deadline we must have turned in a "serious effort." He'll give it back and if he requests additional work or fixes on it, we have a week to turn it back in with the fixes. These coding assignments are worth 7 points each for the total course grade. The remainder of the points come from 3 exams (again no cumulative final) that are worth 17 points each.
Apparently the professor used to let people turn in their assignments whenever, but he discovered (unsurprisingly) that this just encouraged students to prioritize classes that did have deadlines. So now, barring "both of your grandparents dying in a horrible blimp accident [and if anyone's grandparents have died in a horrible blimp accident I'm sorry, didn't mean to be insensitive]" he'll only accept one assignment up to a week late per student.
There is no textbook for this class. He's used several, including (many times) the most popular one, by Sebesta, but he finds that he uses them mostly to make fun of how bad and wrong they are. Also, he said that for us having a textbook just means thinking, "Oh, there's this thing I should be reading, but I don't." And that sounds about right; I haven't actually read a CS textbook yet. He plans to attempt to produce whatever materials he wants us to read, which will be necessarily brief given that he has to produce them.
It's going to be a fun but difficult, I think, semester.
Monday, December 22, 2008
Waterfall vs. Iterative Models
Most people only know one way to run a project; they use a structure that in software development is called a "waterfall model." In a waterfall model, each stage of the project is finished in order, and the results enable the next stage, until you are finished.
For instance, in writing a term paper for school, you might choose a topic, gather some references about the topic, read them while taking notes or making notecards, produce an outline for your intended paper, write a first draft, and then produce a final paper. I think this is the basic process we were all taught in school, and sometimes teachers would even make you turn in intermediate steps just to make sure you were using the process.
An "iterative" model is a different way of doing things, and I think for some types of projects it is superior. In an iterative model, rather than finishing an entire stage before moving onto the next, you divide your project into iterations. At the finish of each iteration, you will have done some of all of the appropriate kinds of work, and ideally you will have some kind of product.
If you applied an iterative model to writing a term paper, your first iteration might result in a very rudimentary draft. You would have gathered only a few sources and skimmed them, produced a very sketchy outline, and put together the bare bones of the paper. The goal should be to end up with a crappy paper at the end of this first iteration. From having done the work so far, you should now know what kind of sources you need and want, and have a good idea where the paper is going. The next cycle will incorporate more sources and be much more complete, and will result in the next draft. You can continue this process of refinement indefinitely (or until the paper is due).
I'm only sketching this out in a very basic way, but there are a few obvious advantages of using an iterative model. First, as soon as you've finished the first iteration, you are always ready to turn in something. Even that horrible first draft can probably get you some grade. In software development, this makes even more sense - even a very "sketchy" program that runs allows people to see visible progress.
Second, you learn a lot during each iteration. When your users or clients see the sketchy program, they will be filled with ideas about what it should do, or you may learn that it wasn't what they wanted after all. Even writing an extremely rough draft of a paper often gives you a very good idea of how it should proceed.
Third, an iterative model prevents the major drawback of a waterfall model - that you may never finish a stage to your satisfaction. If you have to have the whole paper planned out before you begin, you might not get there. If you can't hammer out a complete set of requirements for your software project, you could lose weeks or months or even years that you could have been making progress on other fronts.
Ed taught a computer science class last semester, and many of his students turned in a final project that didn't run. I can't help but think some of them would have been helped by using an iterative model (as well as starting earlier and all of the other usual student tricks). It's better to turn in the 2nd generation code that runs than to turn in the niftier 3rd generation code that doesn't. Using an iterative model lets you hedge your bets this way - at nearly every stage you've produced something of value.
For instance, in writing a term paper for school, you might choose a topic, gather some references about the topic, read them while taking notes or making notecards, produce an outline for your intended paper, write a first draft, and then produce a final paper. I think this is the basic process we were all taught in school, and sometimes teachers would even make you turn in intermediate steps just to make sure you were using the process.
An "iterative" model is a different way of doing things, and I think for some types of projects it is superior. In an iterative model, rather than finishing an entire stage before moving onto the next, you divide your project into iterations. At the finish of each iteration, you will have done some of all of the appropriate kinds of work, and ideally you will have some kind of product.
If you applied an iterative model to writing a term paper, your first iteration might result in a very rudimentary draft. You would have gathered only a few sources and skimmed them, produced a very sketchy outline, and put together the bare bones of the paper. The goal should be to end up with a crappy paper at the end of this first iteration. From having done the work so far, you should now know what kind of sources you need and want, and have a good idea where the paper is going. The next cycle will incorporate more sources and be much more complete, and will result in the next draft. You can continue this process of refinement indefinitely (or until the paper is due).
I'm only sketching this out in a very basic way, but there are a few obvious advantages of using an iterative model. First, as soon as you've finished the first iteration, you are always ready to turn in something. Even that horrible first draft can probably get you some grade. In software development, this makes even more sense - even a very "sketchy" program that runs allows people to see visible progress.
Second, you learn a lot during each iteration. When your users or clients see the sketchy program, they will be filled with ideas about what it should do, or you may learn that it wasn't what they wanted after all. Even writing an extremely rough draft of a paper often gives you a very good idea of how it should proceed.
Third, an iterative model prevents the major drawback of a waterfall model - that you may never finish a stage to your satisfaction. If you have to have the whole paper planned out before you begin, you might not get there. If you can't hammer out a complete set of requirements for your software project, you could lose weeks or months or even years that you could have been making progress on other fronts.
Ed taught a computer science class last semester, and many of his students turned in a final project that didn't run. I can't help but think some of them would have been helped by using an iterative model (as well as starting earlier and all of the other usual student tricks). It's better to turn in the 2nd generation code that runs than to turn in the niftier 3rd generation code that doesn't. Using an iterative model lets you hedge your bets this way - at nearly every stage you've produced something of value.
Thursday, October 25, 2007
The Schooling
I took this semester off from school, which was painful but necessary in light of having surgery. (I already work full time. School or surgery seems doable, but not both.)
I have four classes left before I can graduate, as follows:
This means I should graduate in December of 2008. I've been in school for a long time, and I do want to keep taking math courses basically forever, but graduating would be great.
I have four classes left before I can graduate, as follows:
- Software Engineering Practices (my Senior Experience course)
- Principles of Programming Languages
- Linear Algebra
- Abstract Algebra or (more likely) Probability & Statistics
This means I should graduate in December of 2008. I've been in school for a long time, and I do want to keep taking math courses basically forever, but graduating would be great.
Wednesday, June 27, 2007
Ed's Thesis & Geek Love
Sunday night, Ed did some work on his thesis at my place. He had brought over his computer to hook up to my monitor, keyboard, etc., so that he could do work. I got to watch over his shoulder some.
Ed's thesis work is basically (in my highly generalized understanding) about how to make computers or other devices in a network communicate with each other peer-to-peer if each knows its own location but not necessarily the location of every other one. When he was explaining it to me, I used the goofy analogy of an array of penguins, each drifting around on its own ice floe with a walkie-talkie. If Flippy wants to get a message to Pete, he broadcasts on the channel that any other penguin within range can receive. With his message, he sends his own location. Somehow, given this information, each penguin that receives the message decides whether to pass it on or let someone else handle it. They don't know where Pete is, but only the path the message has followed so far. Somehow given their own location, and Flippy's location, they can figure out how to route the message so that it eventually reaches Pete.
Ed is doing this with some version of the right-hand rule for navigating mazes. This rule (which doesn't work in all cases) says that you can navigate a maze by always cleaving to the right-hand wall. Once you reach a dead end, of course, the old left-hand wall is the right-hand wall, so for many maze configurations, this will eventually result in a full traversal of the maze.
Anyway, Ed was stuck at some point, so I suggested he explain his problem to me. Many people find that explaining a conceptual problem to someone (even if the "someone" is a dog or other noncomprehending beast, which I expected to be) can give them some insight into solving it.
"Do you prefer lined or unlined paper?" I asked. Unlined (score!) ".5 or .7?" He knew I meant lead size (of course) and he had a strong preference. God I love us geeks.
So he explained the above to me, with some sketches, and started telling me about his problem, which was kind of a vector calculus one. (At least, it was material I learned in vector calc that enabled me to understand it; there wasn't any actual calculus involved.)
"It really turns me on to watch you draw diagrams and write math," I said at some point.
He looked at me and blinked.
"You'd feel the same way if it were me," I said.
He thought for a minute. "Yes, I would!" he said, surprised.
Ah, geek love.
(Comic from xkcd.com)
Ed's thesis work is basically (in my highly generalized understanding) about how to make computers or other devices in a network communicate with each other peer-to-peer if each knows its own location but not necessarily the location of every other one. When he was explaining it to me, I used the goofy analogy of an array of penguins, each drifting around on its own ice floe with a walkie-talkie. If Flippy wants to get a message to Pete, he broadcasts on the channel that any other penguin within range can receive. With his message, he sends his own location. Somehow, given this information, each penguin that receives the message decides whether to pass it on or let someone else handle it. They don't know where Pete is, but only the path the message has followed so far. Somehow given their own location, and Flippy's location, they can figure out how to route the message so that it eventually reaches Pete.
Ed is doing this with some version of the right-hand rule for navigating mazes. This rule (which doesn't work in all cases) says that you can navigate a maze by always cleaving to the right-hand wall. Once you reach a dead end, of course, the old left-hand wall is the right-hand wall, so for many maze configurations, this will eventually result in a full traversal of the maze.
Anyway, Ed was stuck at some point, so I suggested he explain his problem to me. Many people find that explaining a conceptual problem to someone (even if the "someone" is a dog or other noncomprehending beast, which I expected to be) can give them some insight into solving it.
"Do you prefer lined or unlined paper?" I asked. Unlined (score!) ".5 or .7?" He knew I meant lead size (of course) and he had a strong preference. God I love us geeks.
So he explained the above to me, with some sketches, and started telling me about his problem, which was kind of a vector calculus one. (At least, it was material I learned in vector calc that enabled me to understand it; there wasn't any actual calculus involved.)
"It really turns me on to watch you draw diagrams and write math," I said at some point.
He looked at me and blinked.
"You'd feel the same way if it were me," I said.
He thought for a minute. "Yes, I would!" he said, surprised.
Ah, geek love.
(Comic from xkcd.com)
Friday, May 04, 2007
Hiding Assumption Lists & Parnas Partitioning
I'm posting about this both because I think it is interesting and because "hiding assumption lists" is a really poor name, such that I can never remember what it refers to. I don't think you have to know anything about programming to get the gist of this post.
When designing software, one idea that everyone basically subscribes to is making the software "modular." That means instead of having one giant clump of code, you have many smaller clumps. Ideally, each clump kind of does one thing, and doesn't contain too much code. The smallest level of clumps can clump together to form larger modules.
This modularity can mean a lot of specific things in terms of how code is organized, because it takes place on a number of levels and partly depends on what type of programming language you're using, but the more important general question is, how do you decide what things to lump together (or, alternately, what things to separate out)?
A general design principle is that you want to have high cohesion and low coupling. "High cohesion" means that each module handles one thing and not several things. "Low coupling" means that the modules are not interweaved together.
For instance, if we compare the modules of a program to a group of people making dinner, it would be like this. Cohesion (which is good) would be something like one person making the salad, one person making the stir-fry, and another person making the bread. You might get even higher cohesion if you had one person doing all of the vegetable prep (cutting things up), one person running the stove, and another person managing the oven: this way each person's taks would be quite specific. Coupling (which is bad) means, how much do the people have to interact? It's OK if the vegetable prep person interacts once with each person - taking orders for vegetables and filling the orders. But it would be annoying if two people were working on different aspects of the same dish at the same time, so that they constantly had to interact with each other, passing information and ingredients back and forth. What you want is for each person to have a single, coherent task (high cohesion) and also for each person to interact with the others a minimum amount (low coupling).
But "hiding assumption lists" give you a different way to think about design. What you do here is think about what might need to be changed about your program later. Might it be ported to a different type of machine? Might the type of database it uses change? Might the user interface be improved? Your ideas about what changes might occur are the "hiding assumptions" (you assume such-and-such might need to change).
You then divide up your modules (this is the "Parnas Partitioning") such that the changes you assume might be needed will be as easy as possible. For instance, if you think that the form of output might change (maybe right now your program puts information on the monitor, but you think later it might just print everything out to a printer), you might respond by making sure all of your output functions are grouped together, rather than interleaved into all of the other code. That way you'd only have to go to one place to make those changes.
Going back to our dinner-makers, let's guess that we might want to change what type of salad is made. If we originally had the salad-making functions divided up between the veggie-prep person and the salad-maker, it could be annoying to have to tell them both that we now want a caesar salad. (This isn't so bad with humans, because they program themselves, but with code you have to write out - and thus later modify - exact instructions.)
We might have originally had a "make salad" function in both our veggie-prep person (it could say "chop up a head of iceberg lettuce, three tomatoes, and an avocado") and our salad-chef ("when veggie-prep gets you the vegetables, put the lettuce on the bottom, tomatoes and avocado layered on top like so"), and then we'd have to change both in order to change the type of salad. It would make more sense to have the veggie-prep person simply take orders ("5 cups of chopped romaine") and deliver the prepared veggies. That way we'd only have to change our instructions to the salad maker ("order romaine from veggie-prep", etc.), and the salad maker would just give a different order. We'd never have to worry about the veggie-prep person at all in making the change.
The design change I described also results in lower coupling, but the idea is that by thinking in terms of future changes, it's easier to see where the problems are in the design and which ones are most important to fix.
When we first learned about this, I realized that I think about my own code this way all the time. I've hardly done any design ever - I tend to design by coding, which works fine for tiny projects but very poorly for larger ones - but I do think about how easy it will be to change certain things without messing everything else up. I'm always pleased when a formal technique turns out to correspond to something I instinctively do, though it would make more sense to be pleased at the opposite - a new technique that gives a perspective I never thought about.
(Yes I realize the way I talked about people making dinner together is kind of an idiotic way to think about people - "you want a minimum of interaction", etc. - but I only meant it as a highly imperfect metaphor. I am really not like the Borg or anything. "Number 8, slice 2 carrots.")
When designing software, one idea that everyone basically subscribes to is making the software "modular." That means instead of having one giant clump of code, you have many smaller clumps. Ideally, each clump kind of does one thing, and doesn't contain too much code. The smallest level of clumps can clump together to form larger modules.
This modularity can mean a lot of specific things in terms of how code is organized, because it takes place on a number of levels and partly depends on what type of programming language you're using, but the more important general question is, how do you decide what things to lump together (or, alternately, what things to separate out)?
A general design principle is that you want to have high cohesion and low coupling. "High cohesion" means that each module handles one thing and not several things. "Low coupling" means that the modules are not interweaved together.
For instance, if we compare the modules of a program to a group of people making dinner, it would be like this. Cohesion (which is good) would be something like one person making the salad, one person making the stir-fry, and another person making the bread. You might get even higher cohesion if you had one person doing all of the vegetable prep (cutting things up), one person running the stove, and another person managing the oven: this way each person's taks would be quite specific. Coupling (which is bad) means, how much do the people have to interact? It's OK if the vegetable prep person interacts once with each person - taking orders for vegetables and filling the orders. But it would be annoying if two people were working on different aspects of the same dish at the same time, so that they constantly had to interact with each other, passing information and ingredients back and forth. What you want is for each person to have a single, coherent task (high cohesion) and also for each person to interact with the others a minimum amount (low coupling).
But "hiding assumption lists" give you a different way to think about design. What you do here is think about what might need to be changed about your program later. Might it be ported to a different type of machine? Might the type of database it uses change? Might the user interface be improved? Your ideas about what changes might occur are the "hiding assumptions" (you assume such-and-such might need to change).
You then divide up your modules (this is the "Parnas Partitioning") such that the changes you assume might be needed will be as easy as possible. For instance, if you think that the form of output might change (maybe right now your program puts information on the monitor, but you think later it might just print everything out to a printer), you might respond by making sure all of your output functions are grouped together, rather than interleaved into all of the other code. That way you'd only have to go to one place to make those changes.
Going back to our dinner-makers, let's guess that we might want to change what type of salad is made. If we originally had the salad-making functions divided up between the veggie-prep person and the salad-maker, it could be annoying to have to tell them both that we now want a caesar salad. (This isn't so bad with humans, because they program themselves, but with code you have to write out - and thus later modify - exact instructions.)
We might have originally had a "make salad" function in both our veggie-prep person (it could say "chop up a head of iceberg lettuce, three tomatoes, and an avocado") and our salad-chef ("when veggie-prep gets you the vegetables, put the lettuce on the bottom, tomatoes and avocado layered on top like so"), and then we'd have to change both in order to change the type of salad. It would make more sense to have the veggie-prep person simply take orders ("5 cups of chopped romaine") and deliver the prepared veggies. That way we'd only have to change our instructions to the salad maker ("order romaine from veggie-prep", etc.), and the salad maker would just give a different order. We'd never have to worry about the veggie-prep person at all in making the change.
The design change I described also results in lower coupling, but the idea is that by thinking in terms of future changes, it's easier to see where the problems are in the design and which ones are most important to fix.
When we first learned about this, I realized that I think about my own code this way all the time. I've hardly done any design ever - I tend to design by coding, which works fine for tiny projects but very poorly for larger ones - but I do think about how easy it will be to change certain things without messing everything else up. I'm always pleased when a formal technique turns out to correspond to something I instinctively do, though it would make more sense to be pleased at the opposite - a new technique that gives a perspective I never thought about.
(Yes I realize the way I talked about people making dinner together is kind of an idiotic way to think about people - "you want a minimum of interaction", etc. - but I only meant it as a highly imperfect metaphor. I am really not like the Borg or anything. "Number 8, slice 2 carrots.")
Monday, April 30, 2007
Review for the Quiz
Via Sally, in case you've been goofing off, and not reading my blog with the proper level of detail, here is a tag cloud via TagCrowd of the last ~40 days of my blog postings:
Guess I've been a bit focused on school lately, eh?
algebra anything asked best better bugs class course date design doing done dr either enough estimate ever feeling finish given going group guess homework hours idea likely lot math mathematica paper pretty probably problem project really risk software someone something stuff sure taking test totally useful usually week weekend whole
created at TagCrowd.com
Guess I've been a bit focused on school lately, eh?
Thursday, April 26, 2007
Group Work
The Software Engineering Principles course I'm currently taking is meant to prepare us for Software Engineering Practices, the "Senior Experience" course for CS majors (and for my made-up degree). The Practices course involves working on a big group project for the entire semester, doing all phases of the software development cycle (requirements, design, coding, testing, etc.). So to help us prepare for that, we've been doing a small group project in our current class.
It hasn't been very good. Our class only had five students, and one dropped out fairly early in the project after having an argument with me (a very civil argument over a mild question; I'm not sure why he got as angry as he appeared to, and I'm not at all sure this is why he dropped out).
Of the four we have left, there is me (smart, moderately diligent), W (smart, moderately diligent, extremely busy and with almost no time to put into school right now), H (smart, a total fuck-off), and B (learning-disabled, may have skills that have not yet been revealed, has not done any work to date). And Dr. P has been contributing to the project himself.
Nevertheless, it's been my best group project for school ever. When we talk about design issues in class, and really hammer them out, it's incredibly fun and feels really productive. I never thought working on a team could be like this. (I can only imagine what it would be like if I had teammates who ever did any work.)
Our project itself currently resides in a file repository managed by cvs. Basically cvs manages it so that multiple people can work on various files, sort of checking them out and then back in with changes. It stores all of the previous version of files, so if you need to revert to one that you didn't yet screw up, you can. When people make changes, they upload their changed files with a comment about what they did.
It's fun checking the repository every day for new stuff, and reading the history logs (the comments people made when they checked things in) on the rare occasions that someone has done something. (Actually, Dr. P does something fairly often, and I usually do some work a couple of times a week, but otherwise, almost nothing ever happens.)
Here are a few things I have learned about doing this kind of group work using a repository.
Donut offenses - Don't break stuff that other people need to do their work. In some workplaces, doing so is known is a "donut offense" and you owe one donut to each person whose work you interrupted.
Submit early - You shouldn't wait until you get your stuff (whatever you're working on) completely finished to put it on the repository. Just because you created a file doesn't mean it's "yours" - it's better to go ahead and upload it when you're at a stopping point so other people can work on it in the meantime. Relinquish ownership.
Group decisions - Design issues need to be ratified by the group. It's fine to go implement stuff on your own, or make mock-ups or prototypes of anything you think might be interesting, but you can't change the project design without consulting with your teammates. For instance, we have a database schema that has been fairly well hammered out in a lot of group discussions. I've written all of the code for the schema, but I can't just go adding stuff without discussing the design with the group.
No ego - A lot of the above relies on not having a lot of ego-attachment to your work. One way you can be productive, as I mentioned, is to make mock-ups or prototypes of things you think might be neat. But this only works if you understand that your prototype is probably not going to become the product, and your mock-ups may be totally trashed (gently) by your teammates. You have to do everything from the perspective of trying to be useful to the collective effort, rather than with the idea that your stuff is the best and will naturally be adopted. Or you have to at least fake it pretty well.
Avoid parallel play - Some people in our group always just do their own stuff without seeming to even check the repository or message boards first. Sometimes what they do has already been done by someone else, or someone else has made remarks that might influence the decisions you make. So even though it's OK to do some stuff totally on your own and then submit it to the group, it's good if you keep in the loop about what's going on in the project as a whole rather than just totally doing your own thing. ("Parallel play" is what they call it when tiny children, who aren't old enough for social interactions, play together. They basically just play alongside each other.)
Groups aren't useless - A few times now, we've had a design task (mostly around the database our product is based around), and I've spent time in advance thinking about it a lot, and have been pretty sure I had it nailed down. One time I wrote up a whole document with two approaches to something, and arguments about why one approach was superior. In that case, trying to explain it to the group, and discussing why one design or the other might be better, yielded a third design that was better than either of my original two. In every case, group discussion has resulted in better designs than anyone had come up with on their own. (A note about design: it's best IME to do design on your own and then hash it out in a group. You can't really design things "on the fly" - you get much better ideas if you think about it for a couple of days by yourself. So I'm talking about refining the design or choosing between alternatives.) This kind of goes against our common sense that groups just muddle things up and accomplish nothing.
Be a self-starter - Sometimes people in the group don't do anything because they feel like nobody told them what they were supposed to do. When you're working in a group of peers, you can't expect someone to tell you what to do. You know what's going on with the project - see what's needed and go do some of it. If you can't think of any defined tasks you can do, go do something you think might be helpful (remember: no ego attachment!) even if you're not sure it's "wanted."
It's sad that this crummy group has been my best group work experience ever, but the parts that have gone well (and even badly) have been real eye-openers.
It hasn't been very good. Our class only had five students, and one dropped out fairly early in the project after having an argument with me (a very civil argument over a mild question; I'm not sure why he got as angry as he appeared to, and I'm not at all sure this is why he dropped out).
Of the four we have left, there is me (smart, moderately diligent), W (smart, moderately diligent, extremely busy and with almost no time to put into school right now), H (smart, a total fuck-off), and B (learning-disabled, may have skills that have not yet been revealed, has not done any work to date). And Dr. P has been contributing to the project himself.
Nevertheless, it's been my best group project for school ever. When we talk about design issues in class, and really hammer them out, it's incredibly fun and feels really productive. I never thought working on a team could be like this. (I can only imagine what it would be like if I had teammates who ever did any work.)
Our project itself currently resides in a file repository managed by cvs. Basically cvs manages it so that multiple people can work on various files, sort of checking them out and then back in with changes. It stores all of the previous version of files, so if you need to revert to one that you didn't yet screw up, you can. When people make changes, they upload their changed files with a comment about what they did.
It's fun checking the repository every day for new stuff, and reading the history logs (the comments people made when they checked things in) on the rare occasions that someone has done something. (Actually, Dr. P does something fairly often, and I usually do some work a couple of times a week, but otherwise, almost nothing ever happens.)
Here are a few things I have learned about doing this kind of group work using a repository.
Donut offenses - Don't break stuff that other people need to do their work. In some workplaces, doing so is known is a "donut offense" and you owe one donut to each person whose work you interrupted.
Submit early - You shouldn't wait until you get your stuff (whatever you're working on) completely finished to put it on the repository. Just because you created a file doesn't mean it's "yours" - it's better to go ahead and upload it when you're at a stopping point so other people can work on it in the meantime. Relinquish ownership.
Group decisions - Design issues need to be ratified by the group. It's fine to go implement stuff on your own, or make mock-ups or prototypes of anything you think might be interesting, but you can't change the project design without consulting with your teammates. For instance, we have a database schema that has been fairly well hammered out in a lot of group discussions. I've written all of the code for the schema, but I can't just go adding stuff without discussing the design with the group.
No ego - A lot of the above relies on not having a lot of ego-attachment to your work. One way you can be productive, as I mentioned, is to make mock-ups or prototypes of things you think might be neat. But this only works if you understand that your prototype is probably not going to become the product, and your mock-ups may be totally trashed (gently) by your teammates. You have to do everything from the perspective of trying to be useful to the collective effort, rather than with the idea that your stuff is the best and will naturally be adopted. Or you have to at least fake it pretty well.
Avoid parallel play - Some people in our group always just do their own stuff without seeming to even check the repository or message boards first. Sometimes what they do has already been done by someone else, or someone else has made remarks that might influence the decisions you make. So even though it's OK to do some stuff totally on your own and then submit it to the group, it's good if you keep in the loop about what's going on in the project as a whole rather than just totally doing your own thing. ("Parallel play" is what they call it when tiny children, who aren't old enough for social interactions, play together. They basically just play alongside each other.)
Groups aren't useless - A few times now, we've had a design task (mostly around the database our product is based around), and I've spent time in advance thinking about it a lot, and have been pretty sure I had it nailed down. One time I wrote up a whole document with two approaches to something, and arguments about why one approach was superior. In that case, trying to explain it to the group, and discussing why one design or the other might be better, yielded a third design that was better than either of my original two. In every case, group discussion has resulted in better designs than anyone had come up with on their own. (A note about design: it's best IME to do design on your own and then hash it out in a group. You can't really design things "on the fly" - you get much better ideas if you think about it for a couple of days by yourself. So I'm talking about refining the design or choosing between alternatives.) This kind of goes against our common sense that groups just muddle things up and accomplish nothing.
Be a self-starter - Sometimes people in the group don't do anything because they feel like nobody told them what they were supposed to do. When you're working in a group of peers, you can't expect someone to tell you what to do. You know what's going on with the project - see what's needed and go do some of it. If you can't think of any defined tasks you can do, go do something you think might be helpful (remember: no ego attachment!) even if you're not sure it's "wanted."
It's sad that this crummy group has been my best group work experience ever, but the parts that have gone well (and even badly) have been real eye-openers.
Thursday, April 19, 2007
The Nano-Date
In our software engineering class, we've been reading Waltzing with Bears (by DeMarco and Lister), a book about risk management. It's geared towards software development, but a lot of the ideas would be the same no matter what kind of project you're running.
The basic idea about risk management is that the odds of nothing "unexpected" occurring to delay your (non-trivial) project are very small, and by not acknowledging that, you are lying to yourself and other stakeholders and unjustifiably relying on luck to let you finish within the time and budget you've allotted.
When most people are given a project to accomplish, and asked how long it will take, they either guess (this is bad) or estimate (this is better) using an assumption that nothing will go wrong. In the software industry, there are tools like COCOMO for estimating how long a project should take. In your own life of doing projects, you probably have a sense of how long things should take you under normal circumstances. This is the date most people report as their answer.
DeMarco and Lister call this "the nano-date" because, given that it's basically the earliest date you might finish, so that the odds of finishing before that date are nil, the odds of finishing on that date are very very small. According to their research, the distribution of completion dates looks like this:

I wasn't able to label the vertical axis, but it represents the probability of finishing on a particular date. The area under the curve adds up to 100% - you're certain to finish overall, but the exact date is uncertain. N is the nano-date, and from the graph you can see why the odds of finishing on that date are so small. The right skew (the way it's higher on the left side and then slopes more gently on the right) is because projects that finish before their "most likely date" (the top of the hump) are likely to finish only a little before, while late projects can drag out forever.
According to their research, the range of very likely completion dates goes from about 250% to 300% of N. That is to say, if your "best case" says your project will take 10 months, it will probably in reality take 25 to 30 months.
That sounds terrible! But if you turn it around, it means that, given a realistic estimate of when your project will probably be done, it might be done in as little as 1/2 - 1/3 of that time. Your project could be way early if you do a good job estimating the probable effects of things that might go wrong and use that estimate to pad your original distribution curve properly. And if you apply proper risk management, you can also avoid, mitigate, or contain your risks, but that's for another post.
Meanwhile, here are the top five risks DeMarco and Lister have identified for software projects, in order from worst to uh...best? (They studied how much harm these factors usually do to a project, and this is based on that average damage.)
schedule flaw: the original estimate of the schedule (from whence N and the rest of the unrisked distribution should derive) was totally bankrupt to begin with, and not because other things went wrong later, but because it was just an incompetent estimate of how long a project should take in your organization.
requirements creep: the client (internal or external) keeps adding new things they want the product to do. The U.S. Department of Defense did a study in which they estimated that the size of a software project grows by about 1% per month.
turnover: important people leave your organization & this messes up your schedule
specification breakdown: negotiations with your client totally break down, and the whole project is cancelled. DeMarco and Lister have found this happens to about 1 in 7 projects. Obviously this isn't an incremental risk like the others - it's just a flat risk. Once you get past a certain point - where everything important has been absolutely nailed down and signed by all parties - this risk disappears.
underperformance: the people working on your project don't work as effectively as they reasonably would be expected to. This risk actually breaks even - sometimes you get overperformance instead (as you'd expect, given the nature of estimation).
The two takeaway ideas I have from this so far are...
1. Don't give the nano-date as your estimate of when a project will finish, no matter what the size of the project is. Recognize that there is a distribution of when you might finish, and use a more likely point in that distribution as your commit date. (A useful heuristic: given your estimate, is there a good chance you'll finish early? If not, your estimate is a lie.)
2. You can get a list of risks (perhaps from problems encountered on previous projects) and use estimation of their average effects to pad your estimates.
Soon I'll try to post about strategies for dealing with the risks themselves.
The basic idea about risk management is that the odds of nothing "unexpected" occurring to delay your (non-trivial) project are very small, and by not acknowledging that, you are lying to yourself and other stakeholders and unjustifiably relying on luck to let you finish within the time and budget you've allotted.
When most people are given a project to accomplish, and asked how long it will take, they either guess (this is bad) or estimate (this is better) using an assumption that nothing will go wrong. In the software industry, there are tools like COCOMO for estimating how long a project should take. In your own life of doing projects, you probably have a sense of how long things should take you under normal circumstances. This is the date most people report as their answer.
DeMarco and Lister call this "the nano-date" because, given that it's basically the earliest date you might finish, so that the odds of finishing before that date are nil, the odds of finishing on that date are very very small. According to their research, the distribution of completion dates looks like this:

I wasn't able to label the vertical axis, but it represents the probability of finishing on a particular date. The area under the curve adds up to 100% - you're certain to finish overall, but the exact date is uncertain. N is the nano-date, and from the graph you can see why the odds of finishing on that date are so small. The right skew (the way it's higher on the left side and then slopes more gently on the right) is because projects that finish before their "most likely date" (the top of the hump) are likely to finish only a little before, while late projects can drag out forever.
According to their research, the range of very likely completion dates goes from about 250% to 300% of N. That is to say, if your "best case" says your project will take 10 months, it will probably in reality take 25 to 30 months.
That sounds terrible! But if you turn it around, it means that, given a realistic estimate of when your project will probably be done, it might be done in as little as 1/2 - 1/3 of that time. Your project could be way early if you do a good job estimating the probable effects of things that might go wrong and use that estimate to pad your original distribution curve properly. And if you apply proper risk management, you can also avoid, mitigate, or contain your risks, but that's for another post.
Meanwhile, here are the top five risks DeMarco and Lister have identified for software projects, in order from worst to uh...best? (They studied how much harm these factors usually do to a project, and this is based on that average damage.)
schedule flaw: the original estimate of the schedule (from whence N and the rest of the unrisked distribution should derive) was totally bankrupt to begin with, and not because other things went wrong later, but because it was just an incompetent estimate of how long a project should take in your organization.
requirements creep: the client (internal or external) keeps adding new things they want the product to do. The U.S. Department of Defense did a study in which they estimated that the size of a software project grows by about 1% per month.
turnover: important people leave your organization & this messes up your schedule
specification breakdown: negotiations with your client totally break down, and the whole project is cancelled. DeMarco and Lister have found this happens to about 1 in 7 projects. Obviously this isn't an incremental risk like the others - it's just a flat risk. Once you get past a certain point - where everything important has been absolutely nailed down and signed by all parties - this risk disappears.
underperformance: the people working on your project don't work as effectively as they reasonably would be expected to. This risk actually breaks even - sometimes you get overperformance instead (as you'd expect, given the nature of estimation).
The two takeaway ideas I have from this so far are...
1. Don't give the nano-date as your estimate of when a project will finish, no matter what the size of the project is. Recognize that there is a distribution of when you might finish, and use a more likely point in that distribution as your commit date. (A useful heuristic: given your estimate, is there a good chance you'll finish early? If not, your estimate is a lie.)
2. You can get a list of risks (perhaps from problems encountered on previous projects) and use estimation of their average effects to pad your estimates.
Soon I'll try to post about strategies for dealing with the risks themselves.
Friday, March 30, 2007
Strange Energy
This morning on my drive to work, I felt a kind of weird energy, like a slight charge of anticipation and excitement. It's the kind of feeling you might have after a promising first date. I'm not sure what it's about, but let's speculate.
"Wet bus stop, it's raining, his car is warm and dry"
I got a ride downtown from my professor last night after class, since it was snowing. (It's been very warm lately and then blam! spring snow!) It wasn't that exciting, but I couldn't pass up the opportunity to quote Sting.
Project
My software engineering principles class is working on a project, and it hasn't been going that well for a couple of weeks, but last night we really sat down to design our database schema. I love designing databases, so it was right up my alley. But what was more salient was another thing, which is that the one other smart, diligent person in my class (out of the five of us), Warren, was the main one arguing with me about all of the decisions. (Only three of us even showed up - me, Warren, and a guy who isn't too bright.) So Warren, Dr. Paul, and I spent basically two hours hammering out a lot of this database design, and it was wonderful how it worked, the way that Warren and I were able to argue cogently with each other and bring up all kinds of possible situations in which one design or the other might be superior. It's rare that I've had this kind of experience in any group, much less a school project. I've respected Warren for a while, so this was just like a little capper.
Weekend Plans
Near the end of that class, we each committed to "deliverables" for Tuesday. I volunteered to write the code (PHP) to create the database that we hammered out. (Our design of it is not completely finished, but we did complete a lot of the schema.) This is a big deliverable (to judge by the reactions to my suggestion that I would do it), and it should take me a while, but it feels very doable - I know how to do it, and it's just a matter of actually doing it.
Meanwhile, in my Geometry class, we got another problem set. It's due next Thursday, and I'll probably need to spend a fair number of hours on it. Like the exam, the problem sets usually take a lot of both working time and non-working time where my brain can just mull on the difficult problems, so I need to work on this early and often. (If you're curious, you can see the problem set here.)
Meanwhile, our grant project will be winding to a close soon (there are about six weeks left in the semester), and we haven't accomplished much this semester, though overall we've accomplished what seems (from the outside) like a fair amount. Dr. Paul, who is also the advisor for that, wants us to write a small paper for a conference he thinks we can get into, and we need an abstract for that paper next week. So the idea at this point is to figure out what the paper should say (we actually do have enough material/ideas to write a small paper), write the abstract, and then figure out, based on what the paper should say, what we absolutely have to finish to be able to write the paper. (In other words, if the paper should contain a screen shot of a particular thing, we need to make the thing that will create the screen shot.) This is as good a way to organize our remaining work as anything, and a bonus of writing the paper (besides possibly getting into the conference, which publishes a journal of its proceedings) is that we should be able to fairly easily rework it into our final report for the funding agency.
This all adds up to a lot of work I need to do this weekend. Unlike what you might think, I feel pretty energized thinking about getting up tomorrow morning and tackling this stuff.
Friday!
It's Friday! In addition to the usual Fridayness that everyone can appreciate, Friday night is when I have my date with Mosch. Mosch and I don't get to spend enough time together lately, and he was in Houston all last week, so I'm especially looking forward to hanging out tonight.
Not-Quite-Date
I'm meeting another friend (Ed) for dinner Saturday night. It's not quite a date, but should be fun anyway.
My iPod, which plays random stuff from my entire music collection on my desk at work all day, has been choosing mostly Bob Dylan, Leonard Cohen, and Tom Waits all morning. It seems like it's trying to tell me something, but I'm not sure what. (Be more cynical?)
"Wet bus stop, it's raining, his car is warm and dry"
I got a ride downtown from my professor last night after class, since it was snowing. (It's been very warm lately and then blam! spring snow!) It wasn't that exciting, but I couldn't pass up the opportunity to quote Sting.
Project
My software engineering principles class is working on a project, and it hasn't been going that well for a couple of weeks, but last night we really sat down to design our database schema. I love designing databases, so it was right up my alley. But what was more salient was another thing, which is that the one other smart, diligent person in my class (out of the five of us), Warren, was the main one arguing with me about all of the decisions. (Only three of us even showed up - me, Warren, and a guy who isn't too bright.) So Warren, Dr. Paul, and I spent basically two hours hammering out a lot of this database design, and it was wonderful how it worked, the way that Warren and I were able to argue cogently with each other and bring up all kinds of possible situations in which one design or the other might be superior. It's rare that I've had this kind of experience in any group, much less a school project. I've respected Warren for a while, so this was just like a little capper.
Weekend Plans
Near the end of that class, we each committed to "deliverables" for Tuesday. I volunteered to write the code (PHP) to create the database that we hammered out. (Our design of it is not completely finished, but we did complete a lot of the schema.) This is a big deliverable (to judge by the reactions to my suggestion that I would do it), and it should take me a while, but it feels very doable - I know how to do it, and it's just a matter of actually doing it.
Meanwhile, in my Geometry class, we got another problem set. It's due next Thursday, and I'll probably need to spend a fair number of hours on it. Like the exam, the problem sets usually take a lot of both working time and non-working time where my brain can just mull on the difficult problems, so I need to work on this early and often. (If you're curious, you can see the problem set here.)
Meanwhile, our grant project will be winding to a close soon (there are about six weeks left in the semester), and we haven't accomplished much this semester, though overall we've accomplished what seems (from the outside) like a fair amount. Dr. Paul, who is also the advisor for that, wants us to write a small paper for a conference he thinks we can get into, and we need an abstract for that paper next week. So the idea at this point is to figure out what the paper should say (we actually do have enough material/ideas to write a small paper), write the abstract, and then figure out, based on what the paper should say, what we absolutely have to finish to be able to write the paper. (In other words, if the paper should contain a screen shot of a particular thing, we need to make the thing that will create the screen shot.) This is as good a way to organize our remaining work as anything, and a bonus of writing the paper (besides possibly getting into the conference, which publishes a journal of its proceedings) is that we should be able to fairly easily rework it into our final report for the funding agency.
This all adds up to a lot of work I need to do this weekend. Unlike what you might think, I feel pretty energized thinking about getting up tomorrow morning and tackling this stuff.
Friday!
It's Friday! In addition to the usual Fridayness that everyone can appreciate, Friday night is when I have my date with Mosch. Mosch and I don't get to spend enough time together lately, and he was in Houston all last week, so I'm especially looking forward to hanging out tonight.
Not-Quite-Date
I'm meeting another friend (Ed) for dinner Saturday night. It's not quite a date, but should be fun anyway.
My iPod, which plays random stuff from my entire music collection on my desk at work all day, has been choosing mostly Bob Dylan, Leonard Cohen, and Tom Waits all morning. It seems like it's trying to tell me something, but I'm not sure what. (Be more cynical?)
Tuesday, February 27, 2007
Finished My Round-Trip Project
My project for my software engineering class for the past five days was to use three technologies (Apache, PHP, and MySQL) to make a webpage that would take data from a form, store it in a database, and another webpage that would read it from the database and display it. This "round trip" is a part of the technical backbone for our group project.
I worked hard on this all weekend, got most of it done by Sunday night, and finished up the rest last night. It took me a lot of work and many parts of it were pretty fiddly, so I feel like a super stud for getting it to work.
Since the purpose of my work was to make this process faster and easier for the rest of the group (which consists of the entire class; there are only 5 of us), I also wrote up a 9-page document with installation instructions, tips, the code that I used, and screenshots of the web pages. I'll bring copies of that to class tonight.
I worked hard on this all weekend, got most of it done by Sunday night, and finished up the rest last night. It took me a lot of work and many parts of it were pretty fiddly, so I feel like a super stud for getting it to work.
Since the purpose of my work was to make this process faster and easier for the rest of the group (which consists of the entire class; there are only 5 of us), I also wrote up a 9-page document with installation instructions, tips, the code that I used, and screenshots of the web pages. I'll bring copies of that to class tonight.
Friday, February 23, 2007
Software Project
My Software Engineering Principles class has so far been rather like a seminar. There are only five students, and typically we just meet, and everyone should have read up on the topic we're going to discuss, and then we discuss the topic and what we've read. Sometimes we have to write a little reflection or some "nuggets" (pithy statements on a topic), but pretty much it's just been reading & talking. I like it!
But, since the follow-up class to this (Software Engineering Practices, my "senior experience" course) is all about working on a big software project, we're going to have a miniature software project for this class, and we started on that Tuesday.
Dr. Paul's idea, which nobody vetoed, is that we should write a requirements management tool. (Requirements are very precise statements about what a piece of software is meant to do and not do. They essentially form the contract between developers and customers/clients. Requirement engineering is what you do before you start working on design or actual coding, in theory.) The most commonly used requirements management tool is probably, alas, Microsoft Word.
I am not one of those anti-MS people, but the problem with keeping requirements in Word (or any word processing software) is that it limits them to being a flat document. What you really want is for requirements to be "live", to facilitate tracking changes over time, to allow for dependency relationships between different requirement statements, and to be able to link requirements to specific parts of the design and the actual code. And of course you also want to be able to produce them as a document.
What Dr. Paul would like is for our application to be open source, web-based, and backed by a database, and for it to support the Volere shell and template. (Volere is basically a style of requirements - sort like how APA or MLA are styles for writing papers.) He suggested (though this is up to us, ultimately) that we could use CSS (cascading style sheets, into which you feed HTML files that it then formats in a consistent way, so that you can take the same HTML pages and show them different ways), PHP (a scripting language that generates HTML pages), and mySQL (an open source database) to solve our technology needs.
Of course, in our first meeting on this (the day he told us about it), we all started jumping in talking about coding the thing, and he sort of interrupted us to say, essentially, "Uh, how about using proper software engineering practices since that's what this class is about, dummies." So we discussed our software lifecycle model (settling on a risk-based iterative model, for now), and started working on requirements. (Too bad we don't have a web-based, open source requirements management tool! Oh yeah.)
So as of this moment we have a pretty good list of proto-requirements. Near the end of class last night we discussed deliverables for Tuesday, so that everyone would have something to work on. Warren is going to get our proto-requirements partly into the Volere template (which has the dual purpose of making our requirements nicer while increasing familiarity with the Volere template) and think about a database schema. Nobody else volunteered for a specific responsibility (despite the suggestion from Dr. Paul that we do so) besides me.
My job is to download PHP, mySQL, set up an Apache server on my own machine, and figure out how basically to make the round trip from a web page where you enter something, to a database, and back out to a display page. I should have this done by Tuesday and be ready to show the class the code and process for how this is done.
(What I mean by "make the round trip" is to code up a page that has blanks where you type stuff in, and then it takes the typed in stuff and stores it in the database, and then you can go to another page to see what is in the database.)
I've never worked with PHP or mySQL before, or really done any web-based stuff at all, so this should be a fun challenge to put together by Tuesday.
But, since the follow-up class to this (Software Engineering Practices, my "senior experience" course) is all about working on a big software project, we're going to have a miniature software project for this class, and we started on that Tuesday.
Dr. Paul's idea, which nobody vetoed, is that we should write a requirements management tool. (Requirements are very precise statements about what a piece of software is meant to do and not do. They essentially form the contract between developers and customers/clients. Requirement engineering is what you do before you start working on design or actual coding, in theory.) The most commonly used requirements management tool is probably, alas, Microsoft Word.
I am not one of those anti-MS people, but the problem with keeping requirements in Word (or any word processing software) is that it limits them to being a flat document. What you really want is for requirements to be "live", to facilitate tracking changes over time, to allow for dependency relationships between different requirement statements, and to be able to link requirements to specific parts of the design and the actual code. And of course you also want to be able to produce them as a document.
What Dr. Paul would like is for our application to be open source, web-based, and backed by a database, and for it to support the Volere shell and template. (Volere is basically a style of requirements - sort like how APA or MLA are styles for writing papers.) He suggested (though this is up to us, ultimately) that we could use CSS (cascading style sheets, into which you feed HTML files that it then formats in a consistent way, so that you can take the same HTML pages and show them different ways), PHP (a scripting language that generates HTML pages), and mySQL (an open source database) to solve our technology needs.
Of course, in our first meeting on this (the day he told us about it), we all started jumping in talking about coding the thing, and he sort of interrupted us to say, essentially, "Uh, how about using proper software engineering practices since that's what this class is about, dummies." So we discussed our software lifecycle model (settling on a risk-based iterative model, for now), and started working on requirements. (Too bad we don't have a web-based, open source requirements management tool! Oh yeah.)
So as of this moment we have a pretty good list of proto-requirements. Near the end of class last night we discussed deliverables for Tuesday, so that everyone would have something to work on. Warren is going to get our proto-requirements partly into the Volere template (which has the dual purpose of making our requirements nicer while increasing familiarity with the Volere template) and think about a database schema. Nobody else volunteered for a specific responsibility (despite the suggestion from Dr. Paul that we do so) besides me.
My job is to download PHP, mySQL, set up an Apache server on my own machine, and figure out how basically to make the round trip from a web page where you enter something, to a database, and back out to a display page. I should have this done by Tuesday and be ready to show the class the code and process for how this is done.
(What I mean by "make the round trip" is to code up a page that has blanks where you type stuff in, and then it takes the typed in stuff and stores it in the database, and then you can go to another page to see what is in the database.)
I've never worked with PHP or mySQL before, or really done any web-based stuff at all, so this should be a fun challenge to put together by Tuesday.
Monday, September 11, 2006
"Rsch Case-Based Reasng Web App"
Since I might as well work for credits in addition to money, I signed up for independent study credits in conjunction with my CREU grant project. Dr. Paul and I got the form filled out and submitted just right before (literally the day before) the census date for the college, which is the last date you can register for anything, and by the day after census it had not appeared in my online registration info, so I thought it might not have actually been processed in time, but apparently it was, because I just had to pay $200 for the 2 credits and now I have the course title above in my unofficial transcript.

I just feel sorry for the person in the registrar's office who had to figure out how to abbreviate our original (very long) course title.
If you want to know more about our project, it has its own blog here: project.diatrack.com. No funny comments over there, please :-) It's a shared blog with Olga and Dr. Paul, though the only post (as of today) is by me.

I just feel sorry for the person in the registrar's office who had to figure out how to abbreviate our original (very long) course title.
If you want to know more about our project, it has its own blog here: project.diatrack.com. No funny comments over there, please :-) It's a shared blog with Olga and Dr. Paul, though the only post (as of today) is by me.
Friday, August 04, 2006
Tam Rules the School: CREU Grant
At the end of the last school year, my computer science advisor (Dr. Paul) asked me and another student to apply for a grant under this program ("Collaborative Research Experience for Undergraduates in Computer Science and Engineering" by CRA-W, part of the Computing Research Association). Under the program, you do some type of research/computer science project and receive a grant.
So we submitted a proposal. My partner Olga was interested in diabetes research (she was an endocrinologist in Russia), so we put together a research project about creating some type of a patient database to be used by different doctors remotely that would then use some type of artificial intelligence algorithm(s) to recommend treatments based on similar cases.
Well, it's been about a month since I thought we would be notified, but we finally found out that we got it! Yay!
At the time that we applied, the grant amount was supposed to be $1500 per student, but since then it has changed to $3000 per student, so that's extra exciting. We apparently were also awarded $500 for conference travel or other related project costs. (The money is exciting, partly because we had already decided to work on the project next year anyway, for general experience, resume building, and possible independent study credits. So it was a question of "work hard on something all year for intangibles" or "work hard on something all year and get money.")
We are required to keep a weekly journal of our efforts and an updated web site about our project. The three of us are (tentatively) going to meet the week after next to get started.
Edited to add this note: a semester of school costs me about $1000, so this is, in essence, a full scholarship for this upcoming year for me.
So we submitted a proposal. My partner Olga was interested in diabetes research (she was an endocrinologist in Russia), so we put together a research project about creating some type of a patient database to be used by different doctors remotely that would then use some type of artificial intelligence algorithm(s) to recommend treatments based on similar cases.
Well, it's been about a month since I thought we would be notified, but we finally found out that we got it! Yay!
At the time that we applied, the grant amount was supposed to be $1500 per student, but since then it has changed to $3000 per student, so that's extra exciting. We apparently were also awarded $500 for conference travel or other related project costs. (The money is exciting, partly because we had already decided to work on the project next year anyway, for general experience, resume building, and possible independent study credits. So it was a question of "work hard on something all year for intangibles" or "work hard on something all year and get money.")
We are required to keep a weekly journal of our efforts and an updated web site about our project. The three of us are (tentatively) going to meet the week after next to get started.
Edited to add this note: a semester of school costs me about $1000, so this is, in essence, a full scholarship for this upcoming year for me.
Thursday, July 27, 2006
Computer Science & Work
I realized today that one of the things that bugs me about my job is that my workflow resembles a bad kind of data structure (in the computer science sense).
Many jobs resembles a queue - when you receive new work, it goes to the back of the line, to be handled after current work is done. In some jobs this is literally true, like if you check groceries or work on an assembly line. For other jobs, it's true because nothing that you do is of specifically high priority, so you just process things as they show up.
Most office jobs probably resemble a priority queue - a line in which the order is determined by priority. If an assignment comes in that is higher priority than one you already have, it goes in front of that one. This can require some effort to keep track of, but it's basically functional.
But my job resembles a stack - a structure that is "first in, last out." Oh, in theory my job is a priority queue like it should be, but in fact, it always seems to happen that whatever I am asked to do needs to be done right now, even before the thing I was given to do right now a few minutes ago. I think the main person who gives me work does not mean to structure it in this way, but has kind of a short attention span, so that's how it works out. It means I am continually interrupted in the middle of one task to start a new one, and have to battle to get back down the stack to all the unfinished projects that are waiting.
It makes me a little nutty.
In regular life, tasks that appear as a stack are very hard for me to get started on. What I mean are things where your thinking goes like this:
I need to do a load of dark laundry. Oh, but first I need to gather up all the dark laundry. Oh, but first I'll have to mend that pair of dark pants I wanted to have in that load that are in the drawer. Oh, but first I need to disassemble the chest of drawers so I can get that drawer to open. Oh, but first I need to get my tool chest back from the neighbor who borrowed it.
I tend to give up somewhere around the third "oh, but" and just not do the task. (My example is a little silly, but sometimes household tasks do present in this way.) I don't know if everyone is like this, but the fact that I'm like this makes it even harder, I think, for me to deal with my job in a productive way.
Many jobs resembles a queue - when you receive new work, it goes to the back of the line, to be handled after current work is done. In some jobs this is literally true, like if you check groceries or work on an assembly line. For other jobs, it's true because nothing that you do is of specifically high priority, so you just process things as they show up.
Most office jobs probably resemble a priority queue - a line in which the order is determined by priority. If an assignment comes in that is higher priority than one you already have, it goes in front of that one. This can require some effort to keep track of, but it's basically functional.
But my job resembles a stack - a structure that is "first in, last out." Oh, in theory my job is a priority queue like it should be, but in fact, it always seems to happen that whatever I am asked to do needs to be done right now, even before the thing I was given to do right now a few minutes ago. I think the main person who gives me work does not mean to structure it in this way, but has kind of a short attention span, so that's how it works out. It means I am continually interrupted in the middle of one task to start a new one, and have to battle to get back down the stack to all the unfinished projects that are waiting.
It makes me a little nutty.
In regular life, tasks that appear as a stack are very hard for me to get started on. What I mean are things where your thinking goes like this:
I need to do a load of dark laundry. Oh, but first I need to gather up all the dark laundry. Oh, but first I'll have to mend that pair of dark pants I wanted to have in that load that are in the drawer. Oh, but first I need to disassemble the chest of drawers so I can get that drawer to open. Oh, but first I need to get my tool chest back from the neighbor who borrowed it.
I tend to give up somewhere around the third "oh, but" and just not do the task. (My example is a little silly, but sometimes household tasks do present in this way.) I don't know if everyone is like this, but the fact that I'm like this makes it even harder, I think, for me to deal with my job in a productive way.
Friday, May 19, 2006
Spring Semester Wrap-Up
Final grades from the spring semester were available by web today. I got an A in both classes that I took - an online geography class, which required a minimal amount of work, and Computer Science 3.
CS3 was the interesting one. It was a tough class that required a lot of work, and a lot of thinking. Writing complex programs (complex relative to one's skill level, that is) makes for tricky homework, because you really cannot put it off until the last minute. A project that takes 15 hours to complete may have to be done in 15 sessions of 1 hour each just so that your brain can spend time inbetween working on the problems that it has to solve.
For the first half of the class, we finished learning the remaining data structures. (Data structures are abstract models of holding and accessing data, and can be implemented in any language - most were invented decades ago - but this class used Java and C++. An example of a data structure is a queue, where the first item in is the first out.) There were four major programming projects - three in Java and one in C++. Every project involved writing not only the functional code, but also other code to extensively test that code. I got full credit on all of these assignments.
For the last few weeks of the class, we had a group project. Ours was to create a graphing calculator. (We chose this ourselves.) As with all such things, it soon devolved into the Project from Hell. The other people in my group seemed, variously, incompetent, lackadasical, disorganized, distracted, and unmotivated. (If you watch any reality TV at all, you learn that whenever you think your groupmates are all incompetent, it invariably means you are actually the problem person in the group. So, hmm...) But we did get some kind of a project sort of done. Scarily, I think our group might have done better than the other two groups.
Then there was the final, which was kind of a fiasco. Half was multiple choice, and it was straightforward. The other half was free response, mostly problems where you had to code something new. There was not nearly enough time to finish, and everyone basically bombed it. I probably got about 40% of it done - or, you know, 60% of it done, and 2/3 of what I did was actually right.
I went to talk to Dr. Paul afterwards about something else, and found a crowd of CS3 students outside his door (keep in mind only 9 of us even took the final) with pitchforks and torches. After they all left, he was somewhat distressed because, in his opinion, the test was something we should have been able to handle, and the fact that we weren't indicated that he had failed to teach the class properly. (Presumably this is worse than merely finding out that you wrote an unreasonably hard test.)
Anyway, prior to getting my grades today, I hadn't gotten any more information, like a grade on the project or the final. (I got a 92 on the midterm, which I failed to mention earlier. That was 25% of the grade, the final was 45%, and all the homeworks and projects were 30%.) I was pretty sure that if he applied a curve, I would get an A based on my percentile in the class. But I also thought a B would have been fair considering that there were areas where I could have put in more effort, and certainly my numerical average would not have been an A.
I just found out tonight that one of my teammates - the other one out of us four who actually did a substantial amount of work on the project - got a D. This means he'll have to retake the class, since only C's and up count toward your major. Bummer for him.
CS3 was the interesting one. It was a tough class that required a lot of work, and a lot of thinking. Writing complex programs (complex relative to one's skill level, that is) makes for tricky homework, because you really cannot put it off until the last minute. A project that takes 15 hours to complete may have to be done in 15 sessions of 1 hour each just so that your brain can spend time inbetween working on the problems that it has to solve.
For the first half of the class, we finished learning the remaining data structures. (Data structures are abstract models of holding and accessing data, and can be implemented in any language - most were invented decades ago - but this class used Java and C++. An example of a data structure is a queue, where the first item in is the first out.) There were four major programming projects - three in Java and one in C++. Every project involved writing not only the functional code, but also other code to extensively test that code. I got full credit on all of these assignments.
For the last few weeks of the class, we had a group project. Ours was to create a graphing calculator. (We chose this ourselves.) As with all such things, it soon devolved into the Project from Hell. The other people in my group seemed, variously, incompetent, lackadasical, disorganized, distracted, and unmotivated. (If you watch any reality TV at all, you learn that whenever you think your groupmates are all incompetent, it invariably means you are actually the problem person in the group. So, hmm...) But we did get some kind of a project sort of done. Scarily, I think our group might have done better than the other two groups.
Then there was the final, which was kind of a fiasco. Half was multiple choice, and it was straightforward. The other half was free response, mostly problems where you had to code something new. There was not nearly enough time to finish, and everyone basically bombed it. I probably got about 40% of it done - or, you know, 60% of it done, and 2/3 of what I did was actually right.
I went to talk to Dr. Paul afterwards about something else, and found a crowd of CS3 students outside his door (keep in mind only 9 of us even took the final) with pitchforks and torches. After they all left, he was somewhat distressed because, in his opinion, the test was something we should have been able to handle, and the fact that we weren't indicated that he had failed to teach the class properly. (Presumably this is worse than merely finding out that you wrote an unreasonably hard test.)
Anyway, prior to getting my grades today, I hadn't gotten any more information, like a grade on the project or the final. (I got a 92 on the midterm, which I failed to mention earlier. That was 25% of the grade, the final was 45%, and all the homeworks and projects were 30%.) I was pretty sure that if he applied a curve, I would get an A based on my percentile in the class. But I also thought a B would have been fair considering that there were areas where I could have put in more effort, and certainly my numerical average would not have been an A.
I just found out tonight that one of my teammates - the other one out of us four who actually did a substantial amount of work on the project - got a D. This means he'll have to retake the class, since only C's and up count toward your major. Bummer for him.
Subscribe to:
Posts (Atom)




















