Saturday, August 30, 2008

Life lesson from Gilgamesh

If you've been reading my blog for a while, you probably know that I'm still pursuing my BS in Computer Science in the evenings. This being August, classes have started again, and with the new company blooming too I have never been busier.

One of my classes this semester is World Literature, and this week the assigned reading was the brief Sumerian myth "the Epic of Gilgamesh", which struck me with some timely wisdom that any ambitious individual would be wise to heed.

On the road to find Utnapishtim (with the intent of uncovering the secret of immortality), Gilgamesh is stopped by Siduri the alewife, who tries to dissuade him from his quest:

"that which you seek, you will never find. For when the gods created man they gave him death for his portion; life they kept for themselves. As for you, Gilgamesh, fill your belly with good things; day and night, night and day, dance and be merry, feast and rejoice. Let your clothes be fresh, bathe yourself in water, cherish the little child that holds your hand, and make your wife happy in your embrace; for this too is the lot of man"

Honestly, the parallel that came to my mind immediately was money; or, perhaps more accurately, the desire to have more than other people and to be free of money troubles. This pursuit is not one that's exactly smiled on by our society, and that's why people rarely explicitly proclaim their financial motivation, but I feel that almost everyone is susceptible to the lie that more money will make you a happier person. Working on this startup business, I'm especially vulnerable to that idea because there's always the slim chance that we'll cash in big a few years down the road, and the temptation is there to forsake everything else in my life to pursue that ideal of the big payday.

Anyone else who feels this way would be wise to heed the advice of Siduri: "that which you seek, you will never find". No matter how much you have, someone else will almost certainly have more, and a full bank account doesn't translate into a full life. If you are consumed by monetary-desire, you will never be free of it, and the pursuit of it will quash the other things in you life that DO make it full. So eat good things, love your family, enjoy your friends, and bathe once in a while, for this too is the lot of software developers.

Sunday, August 24, 2008

Life of a Startup Founder

This week, Research To Practice (the startup I'm working on) is reaching a big milestone: our first three big customers are coming on board and we'll be starting to actually generate revenue. This is a pretty exciting mile-marker, and on the eve of it's occurrence I've taken a minute to stop and reflect on the last 4 or 5 months that I've spent building this product. There were some expectations I had about working on a small company that turned out to be more or less inaccurate, and I thought I'd mention them here in order to provide some anecdotal substance for any readers considering moving to a startup. So here, listed below, are some of the things that I believed to be absolute about life in a startup company, and they're paired with my actual experience on the topic.

1. Startup work is much harder than corporate work

This one I feel is deceptive because it's very true, but not in the way I'd imagined. Prior to leaving my job as a Software Consultant, I pictured life in a startup as sort of a romantic-technological fantasy: I saw myself finding brilliant solutions to near-impossible technical problems that no-one else had solved, and spending lots of time tweaking complex algorithms to process data more efficiently. Truth be told, it's not like that; most of the technological problems and challenges I tackle are the same ones I ran into at every corporate programming job I had in the past, and inevitably they've already been solved by someone smarter than me, so really I'm just pulling together other peoples marvels into a new product. That's not particularly different from what I did before. What makes the startup life "harder" (in my opinion) is the lack of structure that many of us get used to behind our desks in big companies. On my current project, there isn't anybody handing me a spec regarding what features are needed with extensive use-cases, or a mockup showing me what the UI should look like. Even the "agile" shops I've worked in had "stories" that were written out for us to work off of. The environment of my current company is much more impromptu; we have one industry expert (who gives me input on what to build), one business expert (who gives me input on what's most important), and one technological expert (me), and with our commitments piled up our design discussions are quick verbal affairs that are scheduled on an as-needed basis. You've really got to be able to self-motivate to survive the workflow, and be good at asking the right questions to determine what features you REALLY need.

Also there's no-one to hand a problem off to if it's out of your depth. Database problem? Library not behaving as you'd expect? UI acting funky in different browsers? If something comes up that isn't your specialty, you have to be able to read up on it fast because nobody else is going to do it for you. This issue in particular has pushed my adaptability to the limit, and for me that's actually been very enjoyable, but if research into unfamiliar topics is something you deplore than you'd be well off to avoid the startup life at all costs.

2. Working on a startup is nothing short of an obsession. You will be consumed by the work, estrange your friends, and sleep under your desk more often than not.

I think there's a nearly-heroic idea that floats around out there of the super-hacker working around the clock to make up something unimaginably cool in an unbelievable amount of time. Certainly I'd heard my own share of war-stories from more experienced developers who put in that kind of time in the early stages of their companies. It can almost be seen as a badge of honor among programmers, proving what a work-a-holic you are, but I believe that it's both unhealthy and ultimately doesn't gain you any productivity. There have been a couple times where I've stayed up late a night or three in a row to deliver something on time, but it isn't the norm and shouldn't be necessary very often. Yes, you have to move fast if you want to become profitable before you run out of money; but in my personal experience I can usually get more work done in 6 focused hours than in 16 of the "marathon" variety, and it will probably be of higher quality since I won't be slapping irresponsible patches in just to "get it done" or glazing over stupid mistakes because of the hackers version of that zombie-like mindset you fall into after driving for 12 hours. Therefore I'm actually doing the business a favor by keeping a regular work-schedule, and I still get to see my wife in the evenings and attend my college classes a few nights per week. Everybody wins.

3. Startup founders are fabulously rich

Don't get me wrong here, I knew before I started this experiment that nobody becomes wealthy overnight; but even with that knowledge firmly in my head I can't keep out the mental pictures of people who hit home-runs with their startups and retired early. The fact of the matter is, the stipend I'm drawing right now for my living expenses is quite a pay-cut from the big bucks I was making before as a consultant. I'm having to watch my expenses again, something I'm not used to, and sometimes that makes me a little uncomfortable. So really, if you look at it in financial terms, I've actually taken a step backwards. Now, there IS the hope of a big payoff for the risks I'm taking right now with my financial situation: one day we might have a hugely-profitable business running under us that wold make my old corporate salary look like a pittance. But you know what? Even if that doesn't happen, I'm enjoying my life right now (working on interesting problems and having a big stake in the outcome) a lot more than I did when I was working in a nice office for a big salary. As cliche as it sounds, money won't make you happy.

Friday, August 15, 2008

Restful Controllers

Yesterday, a reader pointed out that Restful Controllers would be a great topic for a blog post since I had just mentioned how long controllers can be a problem in Rails applications. I would have liked to have obliged him today, but an emergency feature-change came up today on my start-up that needs fixing before our demo on monday (and since it's my anniversary, I can't work over the weekend. Family First!) Thus, I must back out of my promised post with the commitment to make public my thoughts on the subject come Tuesday. In lieu of my own material, I have below listed some links to other bloggers who have commented on Restful Rails. Enjoy!

Jeff Cohen

Erik Kastner

Daryn Holmes(This one's more of a series on Routing, but helpful nonetheless if you're just starting out with this stuff)

Thursday, August 14, 2008

Long-Controller-itis

I was working through my rails application today for my startup, and realized that something had to give. As I added another action to one of my controllers, I began to feel that uncomfortable sense of dread that occurs when you know something is wrong, and that what you're doing is only making it worse. It's tempting to just "get it working" for now, with the intent of coming back to correct the unpleasantness later, but in my experience later just never happens. Therefore, I spent my time this morning correcting one of the most common rails code smells (and also, fortunately, one of the easier ones to fix): the Long Controller.

The Long Controller is exactly what it sounds like: you originally built just a few controller classes to start your web app, and when you needed to add "just one more" piece of functionality later, you tacked it onto one of the existing controllers even though it might not have been a perfect fit. Subsequently, method after method gets added with the same intentions, and eventually you have a controller with 35 actions, all supporting a total of 6 distinct purposes. I'll present a contrived example for the sake of illustration (just pretend that each of the actions has implementation code written in it):


class HugeController < ApplicationController

def all_users
end

def add_user
end

def delete_user
end

def edit_user
end

def all_owners
end

def add_owner
end

def delete_owner
end

def edit_owner
end

def login
end

def welcome
end

def logout
end

end


Now, the problem here should be apparent: there's so much stuffed in here that it's hard to get a good feel for what this class's purpose is; it's just kind of a catch all for the functionality we need. This makes the controller difficult to parse visually (making it less understandable for people new to the code), it's a bit troublesome to slog through when trying to remember where that one action was you wanted to fix, and since it's already starting to drift towards disorganization it's just an invitation to a developer to sacrifice the controller further for more functionality if he's in a hurry (since it's already pretty bad, one more ugly hack won't hurt, right?).

Fortunately, the proper refactor from this point is fairly simple: determine what each separate logical group of functionality is, and then break them off into their own controllers. Above, we have several method relating to the manipulation of Users, then several related to Owners, and finally a few methods dedicated to basic navigation of the app: thus, from the above example, I'd probably produce a UserController, an OwnerController, and a MainController. So the above amorphous blob of code would become the cleaner and clearer following example:


class UserController < ApplicationController

def all_users
end

def add_user
end

def delete_user
end

def edit_user
end

end

class OwnerController < ApplicationController

def all_owners
end

def add_owner
end

def delete_owner
end

def edit_owner
end

end

class MainController < ApplicationController

def login
end

def welcome
end

def logout
end

end


And thus, the anxiety leaves as everything seems to be more or less "in the right place".

Monday, August 11, 2008

Centurytel: What an embarrassment

Welcome to my post regarding the problems I've had getting an internet connection hooked up at my office. I'm going to try really hard not to make this a rant, but no guarantees.

BEGIN RANT (oops, failed already)------------------

About a week ago, I made a phone call to Centurytel to try and get a DSL connection started at my office. Shouldn't have been a big deal, I thought, but I had no idea what I was getting myself into.

Don't get me wrong; I had my suspicions. While on the phone with the first sales representative, it took over 45 minutes just to set up an appointment for a technician to come out and install the service, and THAT should have been my first red-flag. You might ask: "Ethan, how is that possible? They only need a few pieces of information; you must be exagerrating!". Good Lord, I wish you were right. I have no idea how all that time was eaten up, but I remember the conversation going something like this (edited for dramatic effect):

ME: "Hi, I'd like to get a DSL connection for my office."

CENTURYTEL: "OK, I would love to help you with that sir!"

ME: "Great, what information do you need?"

CENTURYTEL: " Let's start with your address, and social security number......
(5 minutes of perfectly reasonable information gathering ensues)
......"

ME: "Is that everything?"

CENTURYTEL: "Yes, Sir. Thank you for that information!" (You can feel this persons smile radiating over the phone like a Stepford Wife on Cocaine)

ME: "Great, when will your technician be out?"

CENTURYTEL: "Just a moment, sir! We have an excellent offer for a toll-free number available for 99 cents a minute cost to you and no charge to your customers. Would you like me to add this now, or next month?"

ME: "Uh..I don't really want a toll-free number"

CENTURYTEL: "So would that be next month, then?"

ME: "No....never, thanks"

CENTURYTEL: "Very good, sir" (the sales representative now goes silent for approximately 7 minutes, and all I can hear is the clickity-clack of his keyboard as he furiously types away)

ME: "..................Sorry to interrupt, but when will the-"

CENTURYTEL: "Just a moment, sir-" (Clickity-clackity-clickity-clackity)
CENTURYTEL: "-We have a very special offer available right now that is 100% free to you where we lock down your long-distance" (The voice speeds up significantly here) "To-avoid-future-charges-accidentally-applied-to-your-account-where-other-long-distance-carriers-are-concerned-and-may-or-may-not-be-rerouting-your-line-to-one-of-many-other-locations-and-also-to-prevent-the-possible-consequences-ensuing-from-hurricanes-floods-or-infestations-of-vampire-bats-but-primarily-to-ensure-that-we-are-the-only-carrier-making-money-from-your-long-distance-calls-if-you-accept-this-service-please-say-yes-or-no-or-what?-any-of-those-answers-do-hearby-bind-you-and-your-children-to-our-company-for-life" (slowing down again) " and once again, sir, that service is ONE-HUNDRED-PERCENT free to you, so what do you say?"

ME: "What?"

CENTURYTEL: "Excellent, sir, I have noted that on your account......"

Those "Special Offers" continued to come up every 7-10 minutes until FINALLY I managed to interrupt long enough to say that I really REALLY just wanted a DSL connection, and when could he please have the bloody technician out to hook it up. After another monolouge interspersed with a very pointed collection of "Sir"s, he finally confessed that a technician would be out the next day between the hours of 8 and 5.

Now make sure you catch that last bit, because it's very important. From EIGHT....until FIVE. Centurytel has asked me to spend up to 9 hours (a full working day) in an empty office that has no internet connection. Basically, as a software developer trying to work on a live website, it will be very difficult to get much significant work done. Nevertheless, I need that connection to get any work done in the future, so I resign myself to assembling office furniture and improving my unit-test coverage the following day, albeit unhappily.

So the next day rolls around, and I get out my screwdriver to start putting together desks for the office staff. About halfway through the day, when I have seen no-one at my door bearing gifts of internet connectivity, I begin to grow worried. However, I gave them the benefit of the doubt and assumed that just MAYBE I was the last call on the route that day (Oh God, how I wish I had been the last call on the route that day). I'm sure you've already guessed, though, that if I had in fact just been a late-in-the-day service I probably would not be writing this blog post. 100% CORRECT! They did NOT show up that day, and THAT was what began my frustration.

The next day, I call Centurytel's customer service line to inquire as to the whereabouts of my connection to the world. I was polite on that call, as I know that it is not really that particular customer service representative's fault that my previous day had been so miserable, but what she told me truly began to strain my control on my attitude.

CENTURYTEL: "Hello, sir! How may I help you today, Sir?" (you'd think I was a freaking Admiral for all the bloody "Sir"s she was throwing at me)

ME: "Hi, I had an installation scheduled yesterday, and the technician never showed up"

CENTURYTEL: "Thank you, Sir! I would love to help you with that, Sir!" (shoot me before I have to listen to that phrase again)

ME: "...Great, thanks..."

CENTURYTEL: "Ah yes, Sir! Sir, that service has been rescheduled for Friday! How wonderful that I could be of service, sir!"

ME: "....Rescheduled?"

Now, stop me if you think I'm crazy here, but I'm of the distinct opinion that if they were going to reschedule that service, the most important person to inform of that change (after the technician of course) would be......ME! Yes, ME! The Person who was stuck in an internet-less office all day, waiting on somebody who had already decided that he would be here another day, wasting a full working-day's worth of my time! It would have been VERY HELPFUL INDEED to be informed of that change when it was made, and I can't think that it would have been too hard to do so because after my 45 minute conversation with Guy-Smiley the first day they had on file every single piece of contact information I've had since I was 12!!!!

But, I REALLY need that internet connection, so I don't cut them loose just yet:

ME: "....OK, was there anyway that I could have been told about that?"

CENTURYTEL: "Yes, Sir, I am making you aware of that right now, sir!" (You've got to be kidding me....)

ME: "....Fine......what time on Friday?"

CENTURYTEL: "Let's see, Sir. Our technician will be there between the hours of 8 and 5. So glad I could be of assistance, Sir!".

When did this "Between 8 and 5" crap become acceptable? Cell-phones are nearly ubiquitous now, is there no way that you could just, I don't know, call me an hour ahead and let me know that you're coming? No? Instead I'm just going to have to wait for you for 9 hours, knowing full well that you might just "Reschedule" without telling me and that I could again have spent an internet-less day with nothing to show for it? Oh well, I guess I just don't have a choice do I? No, because every other internet provider does the same thing. Why is the market putting up with this!!! It is unreasonable to expect somebody to take a full day off of work to be present for a 30 minute installation at their house, and it is unreasonable to expect a business owner to spend a full day without connectivity at an empty office waiting for the same service! Grab the pitchforks, people, it's time for a revolution!

However, I REALLY NEED that connection, so I show up again on Friday, thinking there's no way that this could happen twice in a row. Oh how wrong I was. At 5:00 pm on friday, I made yet another call to Centurytel.

CENTURYTEL: "Hello, sir! How may I help you today, Sir?"

ME: "Hi, I had an installation scheduled today, and AGAIN the technician never showed up"

CENTURYTEL: "Thank you, Sir! I would love to help you with that, Sir!" (They've GOT to get that out of the script)

CENTURYTEL: "Ah yes, Sir! Sir, you are the next call on that technician's list! How wonderful that I could be of service, sir!"

ME: "....OK....I believe that I heard this was going to take place 'between the hours of 8 and 5' "

CENTURYTEL: "Yes, sir. It was, but fortunately for our technicians, a service is not actually considered 'late' until the end of business hours"

ME: "...I was told '8 and 5', and it's after 5. Correct me if I'm wrong, but I believe that's the exact definition of 'Late'"

CENTURYTEL: "You might be led to believe that, sir, but you are incorrect because we said so. You see, we never said that we were using a 'wooden and literal' interpretation of time, and since you really don't have anything else you can do about it we've decided to reject this 'reality' that you live in and substitute our own version where 'Late' doesn't really mean the same thing."

ME: "........OK.....(trying not to yell).....when will it officially be 'Late'"

CENTURYTEL: "At the close of business, Sir."

ME: "...When is that, pray tell?"

CENTURYTEL: "When business hours are over, Sir."

ME: "You are clearly misunderstanding my question. I do not care about your business hours, your policies, your substituted definitions of common words, or your clear case of corporate mass-retardation. I want to know what time I can go home. Please, for the love of God, give me a time, or I swear I will forget my internal promise to not yell at you."

CENTURYTEL: "8:00 pm. "

Do you see a problem here? I don't even know what to say at this point. Suffice it to say that I stayed at the office all the way until the service was officially late in "Centurytel's other reality", and then I went home, still without an internet connection.

Today is monday. I called again. I got another drone who told me how glad she was to help me, and asked how she could be of service.

ME: "I didn't have a technician show up on Friday, and I was waiting from 8 until 8"

CENTURYTEL: "I'm sorry sir, that service was rescheduled"

ME: "Was there anyway I could have been notified of that!?"

CENTURYTEL: "Yes, Sir! I am making you aware of that now, Sir!" (ARGHGHGHGHRHRHR!!!!)

I told her everything that had happened so far, and began to sob as I asked her to please, please, tell me when I could get an internet connection in my office. She told me that it would be today between 8 and 5. How I would have loved to believe her and to just have hung up at that point, but I asked if she was sure about that, because I'd been through that experience twice already. She told me that she was NOT sure about that because the technicians had been working overtime since the last big storm and were several days behind on the tickets, and that in reality there was no way there were going to make it here today or tomorrow but that the most realistic expectation would be this coming Friday.

Now, I understand that completely. I know you only can complete so much work in the time you have. I understand if it can't be done until Friday, but FOR GOD SAKES WHY WOULDN'T YOU JUST SCHEDULE THE DAMN SERVICE FOR FRIDAY!?! This is what pushed me over the brink. That big storm had occurred days before my last missed service, and again it would have taken only a phone call to tell me that it would have to happen another time. But instead they were continuing to knowingly schedule services at times that were impossible to meet, and continuing as though nothing were wrong.

I am not proud of this, but I began to yell. I asked how it was possible that I was rescheduled three times without being told, how it was possible that they had wasted so much of my (and very probably other people's in my area) time, and I screamed to the mountain tops that a little communication on the front end would have made a VERY BIG DIFFERENCE.

Centurytel, you are an enormous embarrassment, and I am going to find somebody else to supply my internet even if I have to send HTTP requests by snail-mail.

RANT ENDS HERE---------------------------

Friday, August 8, 2008

Product Unveiled

OK, so I've had a lot of questions emailed to me asking just what the "new product" is that our company (Research To Practice) has just released to beta testing. Well, I'm happy to tell all of you, but I promise you will be underwhelmed. ; )

Here's the short version:

Public schools provide special education services to students who need them. Some of the students who receive those services are eligible for medicaid based on their parents income level, etc. When schools provide special education services to medicaid eligible students, the money they spend on that therapy can be billed to Medicaid for reimbursement. That's where we come in. In Missouri, at least, many school districts have elected not to bill back for these services in the past since the process is arduous and the requirements are unpleasantly stringent (welcome to true beraucracy). Our company provides a web/mobile application that allows therapists to document the services they provide in a streamlined way, and we take care of doing the medicaid billing on the back end, taking a percentage of the reimbursement as our fee.

There, aren't you glad you asked? ; )

Thursday, August 7, 2008

Office Space

Well, Research To Practice (our startup company) is now as real as a company can get: just this week we've moved into our own office (after working from our homes for the last 4 months). Of course, I say that a bit facetiously. Having an office does give off a certain feeling of authenticity, but there are a lot of great things about working from home as well. As I've pondered the move, I've thought about several issues that it was important to consider before taking the plunge, and I'd like to jot some of them down this morning while I have a breather:

Pro: Separation of Home and Work

Working from home, it is pretty easy to lose your balance in either of two directions. Ideally you have a block of time during your day that is set aside for work, but your environment affects how you utilize it. Some of my friends have said that working at home is hard for them because being at home fills them with distractions (dishes, laundry, etc) and they don't get as much work done as they intend to. I, too, have a small balance problem, though it leans the other direction: since the home is my workplace, I work anytime I'm there, even when I SHOULD be doing other things (dishes, laundry, etc). Having a separate environment can give you the separation you need to utilize your time efficiently.

Con: Operating Expenses

Probably the most obvious change, an office is going to cut into your budget for sure. There's going to be rent every month, which is a more and more daunting expense as you get closer to metropolitan areas. Also, the one-time move-in expenses will probably knock you off your feet. You need desks and chairs for everyone who will be working there, and that isn't cheap, plus all sorts of small items you hardly think about when you're working for someone else and they're taking care of it: toilet-paper, printing-paper, soap, pens, trash cans, etc. Now you have utilities to pay as well. Over-all, if the company's short on money it's going to be a tight squeeze.

Pro: Single location

When you're in an office, everybody is in one place (obviously). As a result, it's much easier to get a-hold of another team member when you need to: just holler. When working as a distributed team, people can be out of communication for an indefinite amount of time, and although usually not a CRITICAL problem it can easily fall into the category of "mildly annoying".

Con: You have to drive to that single location

My gas costs have been very low since I've been working at home. I only needed to drive when I was doing something other than work. Now, though, I'll be driving 30minutes every morning to get to work, and again in the evening to get home. That's time (5 hours weekly) and money (God knows how much, since I drive a minivan) out the window that I didn't have to spend before.

Pro: The experience seems more real

This is not a tangible truth, but it is accurate for me: getting this office has sharpened my awareness of our reality as a company. Up until now, it's felt almost like make-believe; like I'm writing software for fun and pretending it's going to be used for something important. Having this extra badge of authenticity, it's hard to imagine away the business side of things anymore. It makes me excited, honestly, because this is exactly the kind of thing I've wanted to do since I started working in the code-mines of other companies.

Con: The experience seems more real

No, that's not a typo. The fact is, the pressing realism brings it's negative feelings as well. Within the context of a real user-base, I can feel my anxiety over my work grow. Don't get me wrong, I don't lack confidence in my abilities, it's just that the experience is entirely new for me. I've never written a piece of software this big ALONE before. As we've been moving into our office space, the implications of that have been roaring louder in my mind's ears: this is a REAL business, and REAL people will be using our software, and they will have REAL bugs when they do, and every single one of them will be traceable directly to ME. Alas, there is no medicine for such concerns. I'm sure they are not unique to me, or even to those in my position, it's just that they are new.

Anyway, the deed is done. Research to Practice is now an entity of it's own, and it lives at 105 N. Oak St, Ashland, MO. 65010. Wish us luck!

Sunday, August 3, 2008

NewRelic.com review (RPM)

So our product is live and we're having real users act as our beta-testers. Things are going great! So great, in fact, that it was time to implement some safeguards to make sure that things KEEP going great (and that we don't crash and burn the first week in production). One of the things that's critical to preventing embarrassment is good performance monitoring, and I am convinced now that I'm using the best.

While researching ways to profile my rails application, I came across a few news articles referencing RPM (a product by newrelic called Rails Performance Monitoring). I liked the reviews I was reading of it, and then I noticed the best part: They're partnered with EngineYard (which is our super-good hosting provider). That means that included in my engineyard package is an account with NewRelic to keep an eye on my application's performance. I thought that was cool, but it wasn't until I got things up and running that I realized how great RPM really is. All I had to do was install their plugin and re-deploy my application. After clicking around a bit to create some data, I went to their website to see what kind of reports I had available. My reaction: WOW!

Logging into newrelic.com, I found that I could easily find out which controller actions were slowest, how much memory and CPU I'm consuming, what DB queries are taking the longest to run, which actions are used most frequently, which AR models are used most frequently, etc, etc, all through a very visually pleasing interface. Although I don't have to pay to use it (thanks to EngineYard), I sure would be willing to do so, and I don't say that about very many applications (not because I don't think that software should be paid for, but because I think most applications really aren't worth it).

I have a feeling this tool will be invaluable in the future, so THANKS newrelic, you guys are doing a great job!