DaedTech

Stories about Software

By

You Aren’t God, So Don’t Talk Like Him

Queuing Up Some Rage

Imagine that you’re talking to an acquaintance, and you mention that blue is your favorite color. The response comes back:

Acquaintance: You’re completely wrong. Red is the best color.

How does the rest of this conversation go? If you’re sane…

Acquaintance: That’s wrong. Red is the best color.
You: Uh, okay…

This, in fact, is really the only response that avoids a terminally stupid and probably increasingly testy exchange. The only problem with this is that the sane approach is also perceived as something between admission of defeat and appeasement. You not fighting back might be perceived as weakness. So, what do you do? Do you launch back with this?

Acquaintance: That’s wrong. Red is the best color.
You: No, it is you who is wrong. You’d have to be an idiot to like red!

If so, how do you think this is going to go?

Acquaintance: That’s wrong. Red is the best color.
You: No, it is you who is wrong. You’d have to be an idiot to like red!
Acquaintance: Ah, well played. I’ve changed my mind.

Yeah, I don’t think that’s how it will go either. Probably, it will turn out more like this:

Acquaintance: That’s wrong. Red is the best color.
You: No, it is you who is wrong. You’d have to be an idiot to like red!
Acquaintance: You’re the idiot, you stupid blue fanboy!
You: Well, at least my favorite color isn’t the favorite color of serial killers and Satan!
Acquaintance: Go shove an ice-pick up your nose. I hope you die!

Well, okay, maybe it will take a little longer to get to that point, perhaps with some pseudo-intellectual comparisons to Hitler and subtle ad hominems greasing the skids of escalation. If you really want to see this progression in the wild, check the comments section of any tech article about an Apple product. But the point is that it won’t end well.

Looking back, what is the actual root cause of the contention? The fact that you like blue and your acquaintance likes red? That doesn’t seem like the sort of thing that normally gets the adrenaline pumping. Is it the fact that he told you that you were wrong? I think this cuts closer to the heart of the matter, but this ultimately isn’t really the problem, either. So what is?

Presenting Opinions as Facts

The heart of the issue here, I believe, is the invention of some arbitrary but apparently universal truth. In other words, the subtext of what your acquaintance is saying is, “There is a right answer to the favorite color question, and that right answer is my answer because it’s mine.” The place where the conversation goes off the rails is the place at which one of the participants declares himself to be the ultimate Clearinghouse of color quality. So, while the “you’re wrong” part may be obnoxious, and it may even be what grinds the listener’s teeth in the moment, it’s just a symptom of the actual problem: an assumption of objective authority over a purely subjective matter.

To drive the point home, consider a conversation with a friend or family member instead of a mere acquaintance. Consider that in this scenario the “you’re wrong” would probably be good-natured and said in jest. “Dude, you’re totally wrong–everyone knows red is the best color!” That would roll off your back, I imagine. The first time, anyway. And probably the second time. And the third through 20th times. But, sooner or later, I’m pretty sure that would start to wear on you. You’d think to yourself, “Is there any matter of opinion about which I’m not ‘wrong,’ as he puts it?”

In the example of favorite color and other things friends might discuss, this seems pretty obvious. Who would seriously think that there was an actual right answer to “What’s your favorite color?” But what about the aforementioned Apple products versus, say, Microsoft or Google products? What about the broader spectrum of consumer products, including deep dish versus thin crust pizza or American vs Japanese cars? Budweiser or Miller? Maybe an import or a microbrew? What about sports teams? Designated hitter or not? Soccer or football?

And what about technologies and programming languages and frameworks? Java versus .NET? Linux versus Windows? Webforms vs ASP MVC? What about finer granularity concerns? Are singletons a good idea or not? Do curly braces belong on the same line as a function definition or the next line? Layered or onion architecture? Butter side up or butter side down? (Okay, one of those might have been something from Dr Seuss.)

It’s All in the Phrasing

With all of these things I’ve listed, particularly the ones about programming and others like them, do you find yourself lapsing into declarations of objective truth when what you’re really doing is expressing an opinion? I bet you do. I know I do, from time to time. I think it’s human nature, or at the very least it’s an easy way to try to add additional validity to your take on things. But it’s also a logical fallacy (appeal to authority, with you as the authority, or, as I’ve seen it called, confusing fact with opinion.) It’s a fallacy wherein the speaker holds himself up as the arbiter of objective truth and his opinions up as facts. Whatever your religious beliefs may be, that is a role typically reserved for a deity. I’m pretty sure you’re not a deity, and I know that I’m not one, so perhaps we should all, together, make an effort to be clear if we’re stating facts (“two plus one is four”) or if we’re expressing beliefs or opinions (“Three is the absolute maximum number of parameters I like to see for a method”).

Think of how you you would react to the following phrases:

  • I like giant methods.
  • I believe there’s no need to limit the number of control flow statements you use.
  • I would have used a service locator there where you used direct dependency injection.
  • I prefer to use static methods and especially static state.
  • I wish there were more coupling between these modules.
  • I am of the opinion that unit testing isn’t that important.

You’re probably thinking “I disagree with those opinions.” But your hackles likely aren’t raised. Your face isn’t flushed, and your adrenaline isn’t pumping in anticipation of an argument against someone who just indicted your opinions and your way of doing things. You aren’t on the defensive. Instead, you’re probably ready to argue the merits of your case in an attempt to come to some mutual understanding, or, barring that, to “agree to disagree.”

Now think of how you’d react to these statements.

  • Reducing the size of your methods is a waste of time.
  • Case statements are better than polymorphism.
  • If you use dependency injection, you’re just wrong.
  • Code without static methods is bad.
  • The lack of coupling between these modules was a terrible decision.
  • Unit testing is a dumb fad.

How do you feel now? Are your hackles raised a little bit, even though you know I don’t believe these things? Where the language in the first section opened the door for discussion with provocative statements, the language in this section attempts to slam that door shut, not caring if your fingers are in the way. The first section states the speaker’s opinions, where the language in the second indicts the listener’s. Anyone wanting to foster a cooperative and pleasant environment would be well served to favor things stated in the fashion of the first set of statements. It may be tempting to make your opinions seem more powerful by passing them off as facts, but it really just puts people off.

Caveats

I want to mention two things as a matter of perspective here. The first is that it would be fairly easy to point out that I write a lot of blog posts and give them titles like, “Testable Code Is Better Code,” and, “You’re Doin’ It Wrong,” to say nothing of what I might say inside the posts. And while that’s true, I would offer the rationale that pretty much everything I might post on a blog that isn’t a simple documentation of process is going to be a matter of my opinion, so the “I think” kind of goes without saying here. I can assure you that I do my best in actual discussions with people to qualify and make it clear when I’m offering opinions. (Though, as previously mentioned, I’m sure I can improve in this department, as just about anyone can.)

The second caveat is that what I’m saying is intended to apply to matters of complexity that are naturally opinions by their nature. For instance, “It’s better to write unit tests” is necessarily a statement of opinion since qualifying words like “better” invite ambiguity. But if you were to study 100 projects and discover that the ones with unit tests averaged 20% fewer defects, this would simply be a matter of fact. I am not advocating downgrading facts to qualified, wishy-washy opinions. What I am advocating is that we all stop ‘upgrading’ our opinions to the level of fact.

By

How to Create Good Abstractions: Oracles and Magic Boxes

Oracles In Math

When I was a freshman in college, I took a class called “Great Theoretical Ideas In Computer Science”, taught by Professor Steven Rudich. It was in this class that I began to understand how fundamentally interwoven math and computer science are and to think of programming as a logical extension of math. We learned about concepts related to Game Theory, Cryptography, Logic Gates and P, NP, NP-Hard and NP-Complete problems. It is this last set that inspires today’s post.

This is not one of my “Practical Math” posts, so I will leave a more detailed description of these problems for another time, but I was introduced to a fascinating concept here: that you can make powerful statements about solutions to problems without actually having a solution to the problem. The mechanism for this was an incredibly cool-sounding concept called “The Problem Solving Oracle”. In the world of P and NP, we could make statements like “If I had a problem solving oracle that could solve problem X, then I know I could solve problem Y in polynomial (order n squared, n cubed, etc) time.” Don’t worry if you don’t understand the timing and particulars of the oracle — that doesn’t matter here. The important concept is “I don’t know how to solve X, but if I had a machine that could solve it, then I know some things about the solutions to these other problems.”

It was a powerful concept that intrigued me at the time, but more with grand visions of fast factoring and solving other famous math problems and making some kind of name for myself in the field of computer science related mathematics. Obviously, you’re not reading the blog of Fields Medal winning mathematician, Erik Dietrich, so my reach might have exceeded my grasp there. However, concepts like this don’t really fall out of my head so much as kind of marinate and lie dormant, to be re-appropriated for some other use.

Magic Boxes: Oracles For Programmers

One of the most important things that we do as developers and especially as designers/architects is to manage and isolate complexity. This is done by a variety of means, many of which have impressive-sounding terms like “loosely coupled”, “inverted control”, and “layered architecture”. But at their core, all of these approaches and architectural concepts have a basic underlying purpose: breaking problems apart into isolated and tackle-able smaller problems. To think of this another way, good architecture is about saying “assume that everything else in the world does its job perfectly — what’s necessary for your little corner of the world to do the same?”

That is why the Single Responsibility Principle is one of the most oft-cited principles in software design. This principle, in a way, says “divide up your problems until they’re as small as they can be without being non-trivial”. But it also implies “and just assume that everyone else is handling their business.”

Consider this recent post by John Sonmez, where he discusses deconstructing code into algorithms and coordinators (things responsible for getting the algorithms their inputs, more or less). As an example, he takes a “Calculator” class where the algorithms of calculation are mixed up with the particulars of storage and separates these concerns. This separates the very independent calculation algorithm from the coordinating storage details (which are of no consequence to calculations anyway) in support of his point, but it also provides the more general service of dividing up the problem at hand into smaller segments that take one another granted.

Another way to think of this is that his “Calculator_Mockless” class has two (easily testable) dependencies that it can trust to do their jobs. Going back to my undergrad days, Calculator_Mockless has two Oracles: one that performs calculations and the other that stores stuff. How do these things do their work? Calculator_Mockless doesn’t know or care about that; it just provides useful progress and feedback under the assumption that they do. This is certainly reminiscent of the criteria for “Oracle”, an assumption of functionality that allows further reasoning. However, “Oracle” has sort of a theoretical connotation in the math sense that I don’t intend to convey, so I’m going to adopt a new term for this concept in programming: “Magic Box”. John’s Calculator_Mockless says “I have two magic boxes — one for performing calculations and one for storing histories — and given these boxes that do those things, here’s how I’m going to proceed.”

How Spaghetti Code Is Born

It’s one thing to recognize the construction of Magic Boxes in the code, but how do you go about building and using them? Or, better yet, go about thinking in terms of them from the get-go? It’s a fairly sophisticated and not always intuitive method for deconstructing programming problems.

nullTo see what I mean, think of being assigned a hypothetical task to read an XML file full of names (right), remove any entries missing information, alphabetize the list by last name, and print out “First Last” with “President” pre-pended onto the string. So, for the picture here, the first line of the output should be “President Grover Cleveland”. You’ve got your assignment, now, quick, go – start picturing the code in your head!

What did you picture? What did you say to yourself? Was it something like “Well, I’d read the file in using the XDoc API and I’d probably use an IList<> implementer instead of IEnumerable<> to store these things since that makes sorting easier, and I’d probably do a foreach loop for the person in people in the document and while I was doing that write to the list I’ve created, and then it’d probably be better to check for the name attributes in advance than taking exceptions because that’d be more efficient and speaking of efficiency, it’d probably be best to append the president as I was reading them in rather than iterating through the whole loop again afterward, but then again we have to iterate through again to write them to the console since we don’t know where in the list it will fall in the first pass, but that’s fine since it’s still linear time in the file size, and…”

And slow down there, Sparky! You’re making my head hurt. Let’s back up a minute and count how many magic boxes we’ve built so far. I’m thinking zero — what do you think? Zero too? Good. So, what did we do there instead? Well, we embarked on kind of a willy-nilly, scattershot, and most importantly, procedural approach to this problem. We thought only in terms of the basic sequence of runtime operations and thus the concepts kind of all got jumbled together. We were thinking about exception handling while thinking about console output. We were thinking about file reading while thinking about sorting strings. We were thinking about runtime optimization while we were thinking about the XDocument API. We were thinking about the problem as a monolithic mass of all of its smaller components and thus about to get started laying the bedrock for some seriously weirdly coupled spaghetti code.

Cut that Spaghetti and Hide It in a Magic Box

Instead of doing that, let’s take a deep breath and consider what mini-problems exist in this little assignment. There’s the issue of reading files to find people. There’s the issue of sorting people. There’s the issue of pre-pending text onto the names of people. There’s the issue of writing people to console output. There’s the issue of modeling the people (a series of string tuples, a series of dynamic types, a series of anonymous types, a series of structs, etc?). Notice that we’re not solving anything — just stating problems. Also notice that we’re not talking at all about exception handling, O-notation or runtime optimization. We already have some problems to solve that are actually in the direct path of solving our main problem without inventing solutions to problems that no one yet has.

So what to tackle first? Well, since every problem we’ve mentioned has the word “people” in it and the “people” problem makes no mention of anything else, we probably ought to consider defining that concept first (reasoning this way will tell you what the most abstract concepts in your code base are — the ones that other things depend on while depending on nothing themselves). Let’s do that (TDD process and artifacts that I would normally use elided):

public struct Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override string ToString()
    {
        return string.Format("{0} {1}", FirstName, LastName);
    }
}

Well, that was pretty easy. So, what’s next? Well, the context of our mini-application involves getting people objects, doing things to them, and then outputting them. Chronologically, it would make the most sense to figure out how to do the file reads at this point. But “chronologically” is another word for “procedurally” and we want to build abstractions that we assemble like building blocks rather than steps in a recipe. Another, perhaps more advantageous way would be to tackle the next simplest task or to let the business decide which functionality should come next (please note, I’m not saying that there would be anything wrong with implementing the file I/O at this point — only that the rationale “it’s what happens first sequentially in the running code” is not a good rationale).

Let’s go with the more “agile” approach and assume that the users want a stripped down, minimal set of functionality as quickly as possible. This means that you’re going to create a full skeleton of the application and do your best to avoid throw-away code. The thing of paramount importance is having something to deliver to your users, so you’re going to want to focus mainly on displaying something to the user’s medium of choice: the console. So what to do? Well, imagine that you have a magic box that generates people for you and another one that somehow gets you those people. What would you do with them? How ’bout this:

public class PersonConsoleWriter
{
    public void WritePeople(IEnumerable people)
    {
        foreach (var person in people)
            Console.Write(person);
    }
}

Where does that enumeration come from? Well, that’s a problem to deal with once we’ve handled the console writing problem, which is our top priority. If we had a demo in 30 seconds, we could simply write a main that instantiated a “PersonConsoleWriter” and fed it some dummy data. Here’s a dead simple application that prints, well, nothing, but it’s functional from an output perspective:

public class PersonProcessor
{
    public static void Main(string[] args)
    {
        var writer = new PersonConsoleWriter();
        writer.WritePeople(Enumerable.Empty());
    }
}

What to do next? Well, we probably want to give this thing some actual people to shove through the pipeline or our customers won’t be very impressed. We could new up some people inline, but that’s not very impressive or helpful. Instead, let’s assume that we have a magic box that will fetch people out of the ether for us. Where do they come from? Who knows, and who cares — not main’s problem. Take a look:

public class PersonStorageReader
{
    public IList GetPeople()
    {
        throw new NotImplementedException();
    }
}

Alright — that’s pretty magic box-ish. The only way it could be more so is if we just defined an interface, but that’s overkill for the moment and I’m following YAGNI. We can add an interface if thing later needs to pull customers out of a web service or something. At this point, if we had to do a demo, we could simply return the empty enumeration instead of throwing an exception or we could dummy up some people for the demo here. And the important thing to note is that now the thing that’s supposed to be generating people is the thing that’s generating the people — we just have to sort out the correct internal implementation later. Let’s take a look at main:

public static void Main(string[] args)
{
    var reader = new PersonStorageReader();
    var people = reader.GetPeople();

    var writer = new PersonConsoleWriter();
    writer.WritePeople(people);
}

Well, that’s starting to look pretty good. We get people from the people reader and feed them to the people console writer. At this point, it becomes pretty trivial to add sorting:

public static void Main(string[] args)
{
    var reader = new PersonStorageReader();
    var people = reader.GetPeople().OrderBy(p => p.LastName);

    var writer = new PersonConsoleWriter();
    writer.WritePeople(people);
}

But, if we were so inclined, we could easily look at main and say “I want a magic box that I hand a person collection to and it gives me back a sorted person collection, and that could be stubbed out as follows:

public static void Main(string[] args)
{
    var reader = new PersonStorageReader();
    var people = reader.GetPeople();

    var sorter = new PersonSorter();
    var sortedPeople = sorter.SortList(people);

    var writer = new PersonConsoleWriter();
    writer.WritePeople(people);
}

The same kind of logic could also be applied for the “pre-pend the word ‘President'” requirement. That could pretty trivially go into the console writer or you could abstract it out. So, what about the file logic? I’m not going to bother with it in this post, and do you know why? You’ve created enough magic boxes here — decoupled the program enough — that it practically writes itself. You use an XDocument to pop all Person nodes and read their attributes into First and Last name, skipping any nodes that don’t have both. With Linq to XML, how many lines of code do you think you need? Even without shortcuts, the jump from our stubbed implementation to the real one is small. And that’s the power of this approach — deconstruct problems using magic boxes until they’re all pretty simple.

Also notice another interesting benefit which is that the problems of runtime optimization and exception handling now become easier to sort out. The exception handling and expensive file read operations can be isolated to a single class and console writes, sorting, and other business processing need not be affected. You’re able to isolate difficult problems to have a smaller surface area in the code and to be handled as requirements and situation dictate rather than polluting the entire codebase with them.

Pulling Back to the General Case

I have studiously avoided discussion of how tests or TDD would factor into all of this, but if you’re at all familiar with testable code, it should be quite apparent that this methodology will result in testable components (or endpoints of the system, like file readers and console writers). There is a deep parallel between building magic boxes and writing testsable code — so much so that “build magic boxes” is great advice for how to make your code testable. The only leap from simply building boxes to writing testable classes is to remember to demand your dependencies in constructors, methods and setters, rather than instantiating them or going out and finding them. So if PersonStorageReader uses an XDocument to do its thing, pass that XDocument into its constructor.

But this concept of magic boxes runs deeper than maintainable code, TDD, or any of the other specific clean coding/design principles. It’s really about chunking problems into manageable bites. If you’re even writing code in a method and you find yourself thinking “ok, first I’ll do X, and then-” STOP! Don’t do anything yet! Instead, first ask yourself “if I had a magic box that did X so I didn’t have to worry about it here and now, what would that look like?” You don’t necessarily need to abstract every possible detail out of every possible place, but the exercise of simply considering it is beneficial. I promise. It will help you start viewing code elements as solvers of different problems and collaborators in a broader solution, instead of methodical, plodding steps in a gigantic recipe. It will also help you practice writing tighter, more discoverable and usable APIs since your first conception of them would be “what would I most like to be a client of right here?”

So do the lazy and idealistic thing – imagine that you have a magic box that will solve all of your problems for you. The leap from “magic box” to “collaborating interface” to “implemented functionality” is much simpler and faster than it seems when you’re isolating your problems. The alternative is to have a system that is one gigantic, procedural “magic box” of spaghetti and the “magic” part is that it works at all.

By

How Not to Be Blocked

In a recent post, I talked about how demoralizing it can be to sit around with nothing to do while waiting for someone else to finish a task that you need, fix something that you need, assign you something, etc. I think this is fairly universally known as “being blocked”. It seems nice to have an excuse to do nothing, but I think it makes anyone conscientious a little nervous that someone is going to come along and judge them for malingering, which is rather stressful.

I didn’t really go into details there, but there are many ways to be active, rather than reactive, about being blocked (I think most would have said “proactive”, but I think I kind of hate that word for seeming bombastically redundant — but don’t mind me if you use it because I’m weirdly picky and fussy about words). Taking action not to be blocked has a variety of benefits: alleviates boredom, helps your company, boosts your reputation, opens up potential additional opportunities, etc. The way I see it, being blocked is something that you can almost always manage and opt out of. When I worked in retail many years ago, there was an adage of “if there’s time to lean, there’s time to clean.” I would say the equivalent in the world of software development is “if you’re blocked, you aren’t trying hard enough.”

Things to do when you’re blocked:

  1. Start a wiki or sharepoint site. There’s no company or domain out there that can’t use more documentation and information for onboarding and general reference. And these collaboration mechanisms are perfect since they’re designed to be imperfect at first and refined over the course of time.
  2. Get a subscription to pluralsight and polish your skills. Whether for the sake of the company or the sake of your own career, there’s no engineer that couldn’t use a few new useful tidbits.
  3. Get ahold of a backlog of defects or nettlesome issues for one of the pieces of software your group writes/maintains, create a playpen, and dive in. You’ll learn more about the code and you might even solve one or more issues that have plagued the team for a while.
  4. Identify a pain point for your fellow developers and do something about it. For instance, if merges constantly mess up a file in your code base, write a utility they can use to validate that file. It’s a lot more useful to the company than reading reddit or slashdot and it’ll boost your cred with your fellow developers as well (that is, help you pass “the second test“).
  5. Ask the people around you if they need a hand with anything. There are often people willing to offload a task or two, especially if it’s grunt work or if they’re stressed and you’re keeping yourself busy and earning some pennies in heaven doing this.
  6. Offer to go through an existing code base, adding or creating documentation for it. This has the useful dual purpose of improving documentation and helping you learn the code. When you know something well enough to explain it to others, you know it pretty well.
  7. Abstract, abstract, abstract. If it’s a development task, make an assumption about the info you’re waiting on, and code the rest of the system as if this assumption were true. Then code the system in such a way that changing your assumption is simple. For instance, don’t say “I can’t work until we decide what RDBMS to use — just write some kind of CRUD interface that your system uses with no implementation and go on your merry way.

I think that’s more than enough ammunition to ensure that you’ll always have some non-loafing task to do at the office. If you can find a situation where none of those things is an option, then my hat’s off to you or, perhaps more appropriately, my sympathy goes out to you because you probably need to find a new job. But maybe you can take steps to avoid being blocked in the first place. This list is a bit more abstract and a much less foolproof, but I’d suggest the following practices to avoid being blocked in general.

  1. Seek out situations where you have multiple assignments at once. This requires managing expectations and good organization and prioritization skills, but the end result is that you’ll have approved, productive work to fall back on even when waiting for answers.
  2. Cultivate a healthy knowledge of the problem domain you’re working on. In my experience, a lot of blocking results from needing someone to tell you what “Taking the EBE out of the PHG with the ERBD” means. The more domain knowledge you have, the more chance you have of deciphering cryptic acronyms and jargon code that prevents you from figuring out what to do next.
  3. Seek out areas in which you’re the main decision maker, however small they may be. I understand that you cant’t exactly promote yourself to VP of Engineering, but if you seek out being in charge of something, even if it’s just a small, low priority tool or something ancillary, you
    are unlikely to be truly blocked.
  4. Become resident expert in some technology, product, facet of the business or tool that matters. Generally people who are expects (e.g. the database expert or the source control expert) are in high demand and can fill any lulls with meetings and cooperative sessions with those seeking their expertise.

If you have other ways to avoid being blocked, I’d be interested to hear about them in the comments. I think avoiding blockages is critical not only for preserving your reputation, but preserving your sense of purpose and, on a long enough timeline, your engagement and work ethic. Don’t fall into the trap of checking out due to lack of stuff to do. Make sure you have stuff to do. And, if all else fails, move on. Or, to adapt an aphorism I’ve heard from enough places so as to be unsure of the original source, “change your work circumstances or… change your work circumstances.”

By

ASP Webforms Validation 101

Today I’m going to delve into a topic I don’t know a ton about in the hopes that someone who knows less than me will stumble onto it and find it helpful. As I’ve alluded to here and there, I’ve spent the last couple of months doing ASP Webforms development, which is something I’d never done before. I’ve picked up a handful of tips and tricks along the way. Today I’m going to walk through the basics of validation.

Start out by creating a new ASP.NET Webforms project:

This gives you an incredibly simple Webforms project that we can use for example purposes. If you open up the login form, you’ll find a boilerplate login form laid out in markup. Let’s take a look at the User Name controls:

  • User name
  • What we’ve got here is the most basic form control validator, the required field validator. The “ControlToValidate” attribute tells us that it’s going to validate the “UserName” text box and the “ErrorMessage” attribute contains what will be displayed if the validation fails (i.e. there is nothing in the field when you submit the form):

    Pretty standard stuff. Let’s switch things up a little, though. Let’s add another label after the text box with something goofy like “is logging in.” This is something I bumped into early on as a layout issue and had to poke and google around for. Here’s the new look for the markup:

  • User name is logging in.
  • And here’s what it looks like:

    But that’s no good. We want this on the same line as the text box itself or it looks even goofier. Well, counterintuitive as it seemed to me, the validator field defaults to taking up the space that it would occupy if it were always visible. You can alter this behavior, however, by adding the attribute Display=”Dynamic” to the validator tag. Once you do this, the new label will appear on the same line–unless you mess up. Then the validator will resume taking up space, bumping the new label to the next line. Okay, okay, I’m no UX guru, but the important thing here is that you can set the space occupation behavior of your validators.

    The next lesson I learned was that I could use validators for comparing values as well as doing typechecks. This tripped me up a bit too because I would have assumed that there was some kind of TypeCheckValidator, but this isn’t the case. Instead, you have to use CompareValidator. Let’s say that we want users to have to log in with a decimal representing a valid currency. (“Why,” you ask? Well, because we’re insane 🙂 .) This is what it would look like:

  • User name is logging in.
  • The new validator shares some commonality with the existing one, but take special note of the “Operator” and “Type” attributes. Both of these fields are necessary. For anyone who has read my various rants about abstractions, would you care to guess why I found this completely unintuitive? Well, I don’t know about you, but I personally don’t tend to think of “DataTypeCheck” as an “Operator” (perhaps an “operation,” but even that seems like a stretch). I would have expected either a DataType validator or else the Compare validator simply to need the type specified, at which time it would do a type check. But, I digress.

    The next sticking point that I encountered was that I had a particular form where I wanted to validate something that wasn’t part of a text box. I thought I was dead in the water and would have to do something sort of kludgy, but CustomValidator was exactly what I needed. Let’s say that I wanted to verify that the weird label I’d created does not, in fact, contain the word “is.” (This isn’t necessarily as silly as it sounds if there’s code that alters this label dynamically based on other inputs.) If I point any validator at this control as the “ControlToValidate”, I’ll get an exception saying that it cannot be validated. But I can omit that property and specify an event handler.

    Add the custom validator to your markup and you get this:

  • User name is logging in.
  • And add the following to your code behind:

    public void PointlessLabelValidator_ServerValidate(object sender, ServerValidateEventArgs e)
    {
        var labelText =((Label)LoginControl.FindControl("PointlessVerb")).Text;
        e.IsValid = !labelText.Contains("is");
    }
    

    Now launch the web app again and type a number for the user name and something for the password and observe the new error message. It’s important to note here that you need to satisfy the other validation constraints because the custom validator operates a little differently. The validators we’ve added up until now work their magic by sending validation java script over the wire to the client and so validation is client-side and immediate. Here, we’re performing a server-side validation. This server-side custom validation will be short-circuited by client-side failures, which is why you need to fix those before seeing the new one.

    And that’s my brief primer on validators. This is neither exhaustive nor the equivalent of a nice book written by a Webforms guru, but hopefully if you’re here it’s helped you figure out a few basics of Webforms validation.

    By

    Old Programmer’s Guide to Practical Maths

    I’m writing this post to introduce another series of posts I intend to embark upon, to coexist alongside my “abstractions,” “design patterns,” and “home automation” posts. I’m going to post these under the category “Practical Math” and think of the series as being called “Practical Math for Programmers,” the title of this post notwithstanding. (Speaking of which, bonus Renaissance-Man points to the first commenter who knows what inspired the title.)

    Does Math Matter?

    This is a discussion that I’ve heard a lot over the years as a programmer, and it seems to be a slightly more muted and cordial debate than the typically contentious “computer science degree vs certifications” or “schooling versus self-taught” ones. Generally the accepted answer is the “architect answer” of “it depends.” I’ll see/hear consensuses such as, “well, you need it if you’re going to be doing really low level stuff or processing lots of data or designing compilers or something, but if you’re just writing basic line of business apps or if you’re more of a designer then you don’t need math.” I often like the architect answer because trending toward nuance and avoiding absolutes gives you the most chance of recovering from bad assumptions, but I’m going to go out on a limb here with more of a hard-line stance. I think that programmers do need and use math and that it doesn’t “depend” at all. It’s just that some are more trained in and aware of their usage of it while others do it by intuition, rote, or dependence on others.

    One thing that I think clouds the issue is what is meant by “math.” Many think back to derivatives or perhaps back further to trigonometry and algebra and realize that they don’t frequently hit the math libraries for things like cosine or solve for x. Sure, there are some basic arithmetic operations when laying out a page–addition, subtraction, etc., but that’s it. There’s a broad tendency to dismiss the basic arithmetic as too trivial for discussion and declare math unnecessary in these cases.

    But I think that this analysis tends to overlook two math concerns: missed opportunities to leverage math and lack of understanding that it’s even being used. For the first one, consider a scenario of laying out a form with simple arithmetic. Say there are three buttons that need to be evenly spaced on a form, and the form should have a fixed width, but you have some control over that. The visual, “non-math” way to do this might be to assign the buttons random horizontal locations and then move them around by trial and error. Time could be saved, however, with a simple algebraic solution of determining a ratio of padding to button, determining a form width, and solving for x–no trial and error and exactly right the first time.

    The second concern is a bit more subtle. Perhaps each of the aforementioned buttons have handlers and those handlers have some logic. If button 2 is clicked after button 1, and button 3 is red or else button 2 is blue, disable button 1. Is there any math there, or just a series of weird procedures? The answer is “both,” but you’re probably not thinking of or looking for the math. You’re intuitively constructing logic chains in your head and trying to figure out where the nested parentheses are going to go in your if statement. If you’re intuitively constructing scenarios and you think you’re not doing any math, it’s because you’ve never been exposed to truth tables or Boolean algebra.

    It Definitely Matters

    Boolean logic lies at the core of most things that any programmer does, and it isn’t alone. Arithmetic is obviously indispensable, if reasonably taken for granted, but at the core or arithmetic lies the cousin of Boolean algebra, which is algebra over real numbers. Pulling back from the more “fluid” concerns about real numbers with which we’re used to dealing, there is also a whole world of discrete/finite math that involves distinct values and forms the basis for concepts like sets, graphs, and basic data structures which are in turn assembled into algorithms and design patterns. From that emerges everything from the exotic, like cryptography, to the mundane, such as preconditions and functions. If you’re a programmer and haven’t had exposure to these things, you’re living in The Matrix, blissfully unaware that you could take a red pill and start to see everything you’re doing as a weird, dripping series of green symbols and digits on black background.

    Because I think that math matters a lot and because it’s fairly heavily in my background, I’m going to embark upon this series of posts. I’d like to cover things such as DeMorgan’s Laws/Boolean Inference, O-notation, formal methods, combinatorics, probability/game theory, etc. But if you find your eyes glazing over just reading that list, don’t worry–it won’t be a bumpy ride. And I’ll be in it with you, since my days of heavy exposure to theoretical math are, along with college and grad school, surprisingly far away in my rearview mirror. I’ll have some rust to shake off myself. These are going to be very elementary explanations of these concepts, along with practical concerns of why you as a programmer should care. I’ll also provide links to more information and formal reading along with perhaps examples of where you’re already using this and maybe not even realizing it. I’m going to keep these posts mainly language agnostic, and I might switch it up among C#, Java, and C++, depending on what I’m covering.

    Stay tuned if this kind of thing interests you.