Three logicians walk into a bar. The bartender goes, three beers?
The first logician says: I don't know.
The second logician says: I don't know.
The third logician says: yes.
Three logicians walk into a bar. The bartender goes, three beers?
The first logician says: I don't know.
The second logician says: I don't know.
The third logician says: yes.
So in my spare time, I've had a project thrust upon me that needs a site built. As a PHP guy, I figured, sure. I'll help. So they gave me FTP credentials to have a look. Of course, this "framework" is some of the shittiest code I've ever seen. Those of you who have had the displeasure of having to work with legacy PHP code will appreciate the following:
$ grep -r 'error_reporting(0)' | wc -l
26
Can someone please brexit my life for me right now? I'm not even being paid for this. :(
So at work, we have certain things that users can process. I can't go into what sort of things without giving away the industry I work in. Let's say these things are stories, and they are divided into chapters, and each chapter has one or more paragraphs. Basically, our client has customers, the customer gives out licenses to their customers. The licensees have several people assigned to them, we'll call those storytellers. The storytellers supply the end users with stories.
We built a feature for our client to prepare her own template stories. She can allocate those to some or all of her customers, and their licensees' storytellers can then make a copy and then edit the story, or simply use it as-is. I personally think this is a great feature, considering the business our client is in. Anyway, yesterday our client called. She said, "Hey toon, those three stories we've been writing, I've tried to couple them to WritaCorp but it seems to be taking a long time." Sure enough, turns out it takes three and a half minutes. For a single story to get coupled to a single customer, their biggest one, with about 60 licenses.
So I took the debug log that the operation dumped, and saw that it took not one, not two, not three, not four, not five, not six, but seven fucking thousand (7,000) database queries. I spent some time alleviating the problem and turned those 7,000 into 3,600 in about half an hour, shaving about a minute off the running time. The decoupling, the reverse operation, took about 4,500 queries and I got that down to about a dozen.
Why o toon, you might ask, are so many database queries needed: after all you still have 3,600 left? Well, perhaps considering how this coupling was implemented may illuminate things.
In the olden days, there used to just be stories, with chapters and pararaphs. Then templates arrived, adding a column to the story table that equals 1 if and only if it's a template. Also to the stories were added a license ID column, and a customer ID column. So you can have a story template for just one license, or a story template that's available to all licensees of the customer. So far so reasonably decently.
Subsequently, a co-employee who is no longer with the company, was tasked with giving our client the ability to make template stories that she can then couple to customers, or some/all of their licenses. A set of screens was added that gives our client the means to do this. What happens when you couple a story template to a customer is, it gets duplicated and added to each license. So in the case of WritaCorp, 60 copies were made, each with a set of chapters, and each of those with a set of paragraphs, all of which were inserted into the database separately. This is why I was able to easily halve the number of queries: I simply combined thousands of INSERT queries into a single one.
"Foreign key constraints? We don't need no stinkin' foreign key constraints. We'll just insert one row, get the inserted ID back, then insert all the rows in the other table. If they have "children" then we'll obviously have to do the same for them!" Of course, even without foreign key constraints there may be several better ways to go about this, but this, apparently, is how this sort of thing is done.
Wait, you shout! What happens if the client changes something in the story template? All those duplicates will need to change along with it! Well, my ex-coworker thought of that in advance. He added a "set ID" column to the story template table, but there is no such thing as a "set" table in our application. What this column does, is group all of those template stories together. That way, you can find the templates that belong together! So if the client changes the title of a chapter, why you just get all of the chapters of all of the other templates with the same set ID, but just the ones with the same position, and then update those (one by one, of course). Rearranging chapters becomes a great exercise in creative bookkeeping, and of course there are other WTFs that arise from this implementation.
Now, I thoroughly dislike this sort of thing, because I hate what I like to call "bookkeeping code". With an extra hour of thinking, probably making the thought process span about 65 minutes, my ex-coworker should have come up with a much better solution. See, the whole premise behind this bookkeeping code my coworker wrote, is of course that you're somehow guaranteed to start out with a consistent state, you do something (without using transactions or anything like that), ergo you're sure to end up with the state still being consistent afterwards.
Now recall that I said the coupling took three and a half minutes. Our server (a PHP 4 box, for a whole other extra bonus WTF) is set to timeout any scripts at four minutes. So if someone decided to refresh the page because editing a story took too long, or the script timed out after only 6,000 out of 7,000 queries finished, you're stuck with an inconsistent database state. Nobody realizes this at the time of course, and our client, thinking we built something that works, merrily keeps editing, only making the database state more inconsistent, after which this sort of situation turns into what I believe Donald Knuth, in many of his seminal works, terms a "clusterfuck".
I don't even know how to unmangle this mess without spending several days on rethinking and rewriting whole parts of our application.
The hidden premise here seems to be that you need to be good at Windows to be a good developer, or so I thought at first.
Thinking about it more made me realize that what you guys all seem to be agreeing on is not that the dude is a bad developer for not knowing how to change the extension, but for not being able to find out, and coping with that by writing a shitty hack instead.
If there's anything I've learned in my short career, it's that what makes a good developer is being able to solve problems you've never seen before, because of a thoroughly developery mindset.
So I'm finding that one page of a site I'm working on, hangs. It only happens locally, not online (thank goodness). I'm working with PHP4 so I can't get XDebug and stuff, this is legacy code so no logging or anything. So what do I do? I put an exit('test'); statement in and move it around. Finally, I come to the point where I find out that this doesn't hang:
exit('test'); if (extension_loaded('curl')) { // do stuff } else { // do other stuff }
And this does:
if (extension_loaded('curl')) { exit('test'); // do stuff } else { // do other stuff }
My conclusion: HOLY SHIT the extension_loaded function hangs my site! So I spend about half an hour googling, before realizing the problem is inside the else clause. Can I hand my programming license please? :(
... you can apply permission and make sure contractors are actually doing their working and committing their incremental changes somewhere safe instead of the local repo on their C drive.
Situation my company encountered: they employed a developer who was very sloppy, in that he would push code to production without checking it, and not use VSS properly. As I've mentioned in another comment, we're switching to Git at the moment. One reason against switching from VSS, is the "bliss" of file locking and check-in, check-out mentality of having everything at a central hub so at least the boss knows what the guy is doing!
My argument against this was, well, Git won't be much different because the guy will just go from not checking in or checking out, to not committing and pushing, which of course is exactly what happened. They still had production sites that didn't match source control, they were still mile high in regressions and spaghetti code, and they discover that honestly, with VSS it was just the same except at least they could see which files he had checked out, but they discovered that unfortunately they had no magic mirror that looked into his workstation.
You see, he'd just do what I do when I need to work with VSS: flip the read-only bit, do some work, then do a project diff, and check in/out the changes you need to commit all at once. Except he'd skip the checking in/out part.
But in the end they solved the problem!
So what was the solution? What source control software trick saved the day? What productivity management tool did the trick? They canned the guy, that's what.
If your contractors can't be fucked to work with you, hire someone else and state in their contract that they are obligated to manage your code responsibly. This sort of thing should not be enforced by software, but by people.
I find it interesting that you say both "Git may take a while to get used to" and "it's a breeze to use". That's like saying a complicated piece of construction equipment is easy to use because the guy with years of experience is having no problems.
Good analogy, but you're taking my words out of context so it looks like I'm contradicting myself. What I actually said was:
[quote=toon, post:133, topic:3005]Git may take a while to get used to, but if you learn a few commands and get used to a couple of GUI's then it's a breeze to use.[/quote]
That's not a contradiction from where I'm standing.
Take a forklift: I used to drive one for a living. Forklifts definitely take a while to get used to. They handle differently from most other kinds of vehicle you might drive, such as cars or trucks. You need to know a fair bit about the forklift in question to be able to maintain one. There are even things you need to be aware of, to be able to drive one without seriously risking property damage or human injury. So yeah, I'd say you shouldn't be driving a forklift around other people unless you know what you're doing, and that takes a definite amount of effort.
But would I argue that forklifts are not easy to use? No, I wouldn't. In fact, I'd say at least 95% of all adults under 65 could do it if they were so inclined. Of course, I'd also argue that pallet jacks are much easier to use than a forklift. Basically anyone who can walk upright can use those. But if I need to move a tank of water over dozens of yards of pavement through the rain to the next warehouse, why I can do it with both, but I know which tool I'd consider better suited for the job, and it's not the more easily usable one.
Look, this is a forum where people go, "this person should have his keyboard license revoked". Developing software is a craft, there are ways to do it properly and improperly, and some of the best tools you can have in any craft, take time to get used to, and then all of that time pays itself back tenfold. DBMS'es, web servers, debuggers, IDE's, text editors, even web browsers, it's all the same in that respect, they all come with manuals, and I don't see why VCS should be any exception.
Trying to install Bugzilla on a server that only runs the 9 year old Perl version of 5.8.8, which is a whole WTF in and of itself. Anyway, when installing the required modules this happens:
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Etcetera etcetera. Good thing I was paying attention so I could hit Ctrl-C, after which the installation went on its merry way.
I hate you, Bugzilla. I hate you, Perl.
So I'm about to start a project in my spare time for charity; literally for starving children in Africa.
Anyway, about ten actual seconds in, I see this:
$nrs_lookup = array( 1 => "01", 2 => "02", 3 => "03", 4 => "04", 5 => "05", 6 => "06", 7 => "07", 8 => "08", 9 => "09", 10 => "10",
11 => "11", 12 => "12", 13 => "13", 14 => "14", 15 => "15", 16 => "16", 17 => "17", 18 => "18", 19 => "19", 20 => "20",
21 => "21", 22 => "22", 23 => "23", 24 => "24", 25 => "25", 26 => "26", 27 => "27", 28 => "28", 29 => "29", 30 => "30",
31 => "31", 32 => "32", 33 => "33", 34 => "34", 35 => "35", 36 => "26", 37 => "37", 38 => "38", 39 => "39", 40 => "40" );
disgunbegud.gif
A few months ago, I posted this topic: Bookkeeping code or: how I learned to stop worrying and love data duplication.
TL;DR of previous topic: we have an application that among other things, manages "stories" (actually they're not stories, don't want to give away too much), which can have many chapters, which can have many paragraphs. These stories can be linked to clients and their licensees. An ex-coworker thought it would be a good idea to interpret "licenses share stories", as "each license gets a deep copy of the story", resulting in lots of bookkeeping code and thousands of database queries.
I'd already pulled a few tricks out of my top hat and this alleviated the problem, but still, when the client would try to change a chapter title, it would take five minutes. This was basically my fault: I'd written a method that would take one story, delete all the data in the copies, and then repopulate the copied stories. It would get called each time a story got saved. This is the only way I knew how to be sure that the whole bookkeeping code thing didn't cause any bugs. This problem would, of course, only get worse with time unless something was done, and I was just about out of tricks. So I talked to my boss about it, and although he knew a bit about what was causing these screens to be so unresponsive, it turned out that he didn't really realize how bad the problem actually was. So I decided to clue him in, and flat-out recommend that I just yank out the whole godawful mess. And he agreed.
So last week I spent about a day and a half rewriting this stuff. Now we have an extra database table, and also we have 80,000-100,000 fewer records overall, that no longer need all that bookkeeping code to manage them. Many, many known and unknown bugs got squashed. Screens went from thousands of database queries, to like two or three. Git tells me I took 1,151 LOC out and wrote 333 new ones, not including any whitespace changes.
I'll be deploying tomorrow. I did a good thing last week.
@TimeBandit yeah, I did in fact remove them first thing, I was getting white screens with no clue why. Quickly set error_reporting
to E_ERROR | E_WARNING
though. Choose your battles and such...
@bb36e I found 25 instances, excluding legitimate uses such as doc comments and stuff. I also decided to exclude Smarty, because I happen to know that those guys use the @ operator deliberately as a way of writing code that's dirty, but optimized for speed. For instance, if in benchmarking, they find that checking if a file exists and then getting the mtime, is slower than just getting the mtime with an @
, then they'll go for the @
.
So in my spare time, I've had a project thrust upon me that needs a site built. As a PHP guy, I figured, sure. I'll help. So they gave me FTP credentials to have a look. Of course, this "framework" is some of the shittiest code I've ever seen. Those of you who have had the displeasure of having to work with legacy PHP code will appreciate the following:
$ grep -r 'error_reporting(0)' | wc -l
26
Can someone please brexit my life for me right now? I'm not even being paid for this. :(
No problem. I think there's some miscommunication here, as you mentioned a pre-commit hook, which I took to mean that this hook would execute locally. I think that the hook that both of us have in mind, is called post-receive in Git.
I don't see why it's anyone's business what I do in my own local repo. Stuff like that goes in the remote in a receive hook, not in a local pre-commit hook. I want to be able to make shitty test branches or be able to make lots of commits that I may throw away or combine and/or split with rebase -i
.
I'll push things that are ready to be pushed and I think it makes perfect sense that I am not allowed to push whatever I want. But until then I want to be able to do my job without getting nagged by management's mandatory micromanagement tools. I don't want to have someone write a program that keeps checking if I'm making a mistake, before I've made it in any real sense.
Man, I hope the OP doesn't complain about your unfunny OT comment.
Dammit, @blakeyrat! Why, I oughta...
Trying to install Bugzilla on a server that only runs the 9 year old Perl version of 5.8.8, which is a whole WTF in and of itself. Anyway, when installing the required modules this happens:
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Please tell me where I can find your apache src
[../apache_x.x/src] ../apache_x.x/src
Can't stat `../apache_x.x/src'
Etcetera etcetera. Good thing I was paying attention so I could hit Ctrl-C, after which the installation went on its merry way.
I hate you, Bugzilla. I hate you, Perl.
There is technically definitely such a thing as captcha breaking software. What you do is, you are a shady person with a bunch of shady websites that a bunch of people comment on, and you write bots that write comments on captcha protected websites. And you then proceed to simply serve the captchas your bots encounter to the humans on your own sites as if they are your own captchas.
Me neither.
This is a fine joke for poking fun at stereotypes. If you want to go into the reality, then it breaks down. It's all well and good for @Buddy to be all PC about gender, but they should probably either lighten up or make decent arguments, I guess that's my point.
Agreed. 96-99% probably fit one gender fine.