Chronicle: A bad idea i mentioned gets implemented
What was actually in the requirements and what the business customer thought was in the requirements were at odds. Apparently, a change was discussed, something was put in the requirements, and the business user signed off thinking her changes were implemented in it.
We're implementing a SOx related change, when the question of history comes up. History is part of the SOx requirement, the business user thinks it's in the requirements, and the developers know it isn't and that there is not enough time to put in history properly before the next release.
I mentioned in passing to one of the BAs that i sit next to, that it could be done with a TRIGGER shudder, but it would be a really Bad Idea. The hack is quick and dirty, TRIGGERs are evil, and this is a change log, not a history, which will be treated as a history at some point.
At the next meeting, the BA brought up the idea and it is decided to implement it. I fight with them over pulling in data from other TABLEs too, telling them that the FK should be enough, and duplicating data is bad. Someone gives me a TABLE structure, which adds new SOx COLUMNs, that is, not only do we capture what the change was, we capture who made the change, which, by definition, is the same as the master record's last updated or the next record in the change log. I register my comments, they are all ignored. The TABLE has the words "audit log" in it, and everyone refers to it as a history.
Now i have been asked to write a SQL statement to help the support team pull up the history. I mention that the original idea, seemingly agreed to, was that this hack would allow us to provide the change log on request, but it would not be automated. Further, this is a bug waiting to happen (especially if anything changes) and i strongly recommend against it. I am assured this will only be used by the production support team for now until a history is properly implemented.
I sent off the SQL to whomever. I remind myself (unsuccessfully, i'm sure) to keep my mouth shut.
Verbiage: Automatic payments want to switch phone service
I've been using MetroPCS for some time now, due to their $25/mo no contract, unlimited calling plan. It used to be $40, and that was good too, but at $25 it's hard to beat.
I like simple phones that are actually phones. Maybe i'm old-fashioned, but these semi-trucks that people whip out of their pockets with menus that look like they're from outer space don't seem to me to be an ideal phone. I also have a computer that is a phone, but i leave my mac at home.
MetroPCS is really annoying though. First it was the text spam. When i finally got bothered enough, i googled and found that it was the metro apps. Disabling some option took care of that. The second issue, which gets me every month, is automatic payment. I almost always forget to pay bills. I sit down once a month to pay my credit cards (which requires a bit of planning), but almost everything else is automatic. Two things are not, my water bill and my phone bill.
I live in an apartment building managed by Hartman and Tyner. I pay for electric bills to Detroit Edison through the local utilities comp. Heating and water is grouped together, and they split the bills in between the tenants. (They used to do that, i believe, they might have individual metering now.) It used to be that water was free, but they decided to have us pay 1/3 of the bill. That is handled by Yes Energy Management which adds a customer fee or two. Bills can be paid via the mail. or together with the rent at Rent Payment.
Rent Payment works if everything is in order. If anything is not, such as a credit card expiry made a card unusable, they won't tell you about it, and you find out when you get charged a $25 late fee (which increases every few days) and warning from the local office. Payment can be set to automatic, and they have gotten a little better about knowing when your lease starts and ends and required amount to pay.
The water bill is different. The amount shows up if i log in, but there is no way to pay it automatically. When i asked the local office why it wasn't, the response was that since the amount changes per month, it isn't possible. That seems bogus to me, as my electric bill changes every month and DTE has no such issues. So, i usually forget to pay it until i get a warning from the local office.
MetroPCS is the other problem. They text me when it is time to pay. At that point, by the time i get home and remember to do it, my phone has been suspended. Because it is suspended, i couldn't login to my account on their website, meaning i had to make a payment by typing in all the information. Only after the account was active could i get back into the account.
One month i actually setup everything, or so i thought. Apparently, the payments are still not automatic, but at least i can login to my account now. I went through the motions to make a payment, though i completed it (maybe even twice), but my phone is still not working.
I am sick of MetroPCS. I realized that i don't actually want the cheapest service. I want the cheapest convenient service. I'm ready to switch, anyone got any ideas?
Verbiage: Some random debugging session
A team member from Chenai asked me why a script which EXECUTEd a PACKAGE i wrote wasn't working. First thing i did was run it myself via SQL*Plus, which is did splendidly, i might add. :) First thing accomplished, it's not a problem in QA, it's the script.
Logged onto the app server and sure enough received the same error. Copied the file and started to change things. Having seen this file before, i was able to skip all the variables and right to the code. The code looked okay..maybe it should be tested on the db server itself to mimic what that script was doing.
Logging on to the server reminded me that the password had changed. No idea what it was changed to, but it wasn't required anymore, so i didn't care. That was a problem here. Luckily, there are those variables.
The variable and variable handling take up probably most of the script. The variables themselves are loaded from files, which may include other files. Ultimately, usernames and passwords are in a script under ~/etc...easy enough.
Trying the first set, then realized that was the db login itself. I made sure the db user could indeed EXEC that PACKAGE via SQL*Plus, and it could. But that wasn't the server login. Looking again, there was a server login, which failed. I checked and double-checked. Something was wrong.
That was it, no more assumptions, just check which server it was connecting to straight. Sure enough, it was set to the server we were migrating to, but is not for general use yet. The TNS name pointed to it as well. Duh! Is your computer plugged in?
When writing this, i hit [ctrl]-[e] 2 or 3 times to go to the end of the line. Between my mac at home and just being on a Linux box, switching back to windows shortcuts takes a second. After switch back from Google, i found my window empty, luckily, i had Lazarus installed.
Silliness: Commenting the wrong way
In middle of redacting a VIEW that deals with groups, members, and precedence, i fixed a bug, and explained a line in greater detail with (what i think is) the correct logic. (The actual COLUMN name has been shortened):
-- Match this record:
-- To match INDIVUDAL, check P_ as C_ will be NULL (INDIVUDALs have no children).
-- To match GROUP, check C_ for the children; parents can be ignored.
-- (Note: Checking the NULL child or irrelevant parent should not be a problem.)
AND PHC_1.C_ IN (PHC_2.P_, PHC_2.C_)
Some comments just seem wrong.
Having a free moment, i decided to search for something on eBay when the following message popped up on my screen:
Even without the non-working old-experience link, there is something wrong with using a modal window to tell me that i can't appreciate the experience.
If you ask me what version of FF i'm using, you're already a lost cause.
In Passing: Prepay before pumping
This morning i went to put gas in the car. I switched gas stations because i don't like answering three-million questions before being able to start the gas pumping. Sheesh, ask if if i want a receipt after it starts, why waste so much precious time (in the freezing weather)!
So, i went to a Valero station as they tend to be a little cheaper. They are not on the corner either, making them harder to get to; i'll see if i continue going there. A couple cents a gallon isn't something to get inconvenient over.
Anyway, on the pump there was a sign, "Please pre-pay before pumping".
In Passing: What that in celcius, -40?
Last week i overheard part of a conversation. Someone asked, "what's that in celsius, -40?"
And behold, i chuckled.
Verbiage: Cisco phone time to ring setting is global
I use Google Voice to ring my cell phone and office phone (amongst others). The problem is, the office phone picks up after two rings. It's a Cisco CP-7942G, an ip phone. The time to ring setting is global. Seriously?!
So, the office phone picks up first. This isn't usually a problem, because i am by the office phone during the hours i set Google Voice to use it. But yesterday, for example, was a Monday that i was not in the office, it still picked up first because i forgot to turn it off.
Game: Battle Monkeys (rules)
Been playing Battle Monkeys.
Learning what each icon does and proc-order is important, but i haven't seen it explained in detail in one place. So, i decided to place a start, here, so as to have it somewhere:
Each Item can be used once. When used, the icon disappears.
Names appearing on four-part screen before game starts are colored based on rank.
Players can have between 1 and 100 Health.
- If avatar receives health that would give it more than 100 Health, it is set to 100 Health.
- If avatar receives damage that would give it less than 1 Health, it is removed from the game.
Avatars take turns:
- By default, turns are taken in order, from left to right. (i.e. avatar with lowest ranking to highest ranking)
- Order of actions can change the order of turns, which becomes the new order for subsequent rounds.
If two avatars qualify for an action as a result of a rule, the avatar affected is chosen at random. (Perhaps it is in the same as turn order, that round.)
If an action applies to more than one turn, it is also applied to the current turn.
- Therefore, even though an action is shown as "+2", the board will show it as if it was 3.
Order of actions on a turn is:
- Push (Where applicable)
- Mace (If player is still in Mace from previous turn)
- Poison (If player is still in Poison from previous turn)
- Health, Full Health, Shield, Vanish, Extra Jump
- The rest (including new Mace and Poison)
Order is very important. For example:
- An avatar in Poison with 10 (or less) Health, has no recourse for more health.
- (If all other other avatars are in the same predicament, and go first, player can still win.)
- Being in Mace and landing on Mace, means Mace actions twice on that turn.
- An avatar in Poison that lands on a Vanish square, applies Vanish after the poison.
- So, the damage received from Poison will not affect Vanish.
- Poison on the next turn will affect Vanish.
All icons have a color:
Green Health to self
Red Damage to self
Blue No Health or Damage to self or others.
Yellow (potential) Damage to others
Push (event) - Avatar is moved off the current square.
- When more than one avatar lands on the same square, a die is rolled for each.
- The same number will not appear on more than one die.
- The avatar with the highest number applies Push to each of the other avatars.
- Push moves the avatar to an adjacent square. The avatar receives 10 damage.
- An avatar on an edge square may land off the board. That avatar receives 100 damage.
- If as a result of Push, an avatar lands on a square occupied by another avatar:
- In Single Player mode, the process runs again, for the new square.
- In Multiplayer mode, both avatars occupy the same square:
- The avatar that landed on the square first treats the square normally.
- The other avatar does not make use of the square, but can receive damage.
Health (heart, green) - Player receives 35 - 45 health
Lava (8 pointed star with outline, red) - Player receives points 35 - 45 damage
Extra Jump (up arrow with line through it, blue) - Player receives 4 (turns) to Extra Jump.
- During Extra jump, player can move 4 squares (instead of the usual 3.)
Vanish (8 lines in circle around dot, blue) - Player receives 2 (turns) to Vanish.
- Vanish ends prematurely if player takes any damage.
- If player stays in Vanish for 10 turns, player receives Ninja Achievement.
- During Vanish player becomes untargetable and avatar is not shown (mace and shield are)
Mace (mace, yellow) - Player receives 2 turns to Mace.
- Players in Mace target all targetable avatars within one square of player.
- Target receives 35 damage.
Shield - (double-lined shield, blue) - Player receives 2 turns to shield.
- Players in Shield (and not in Sleep) are protected from all damage except Smackdown and Push.
- Player in Shield can still receive Sleep.
- If player is also in Sleep, Shield is not active, but does consume a turn.
Sleep (Zzz, blue, targeted) - Target receives 1 (turn) to Sleep.
- Sleep end prematurely if target takes any damage.
- Target is avatar closest to player.
- During Sleep target does not consume any square's icons.
Debonus (encircled x, blue) - All avatars other than player are put in normal state. (Does not affect Health.)
Poison (skull with two injectors through it, yellow, targeted) - Target receives 2 (turns) to Poison.
- During poison, player receives 10 damage.
- Target is Avatar with highest health.
Meteor (circle with 3 circles inside of it, and 3 triangles outline of it, yellow, targeted)
- Target receives 30-35 (usual), 40 ("Big"), or 50 ("Epic") damage.
- If target has a shield, target takes no damage.
- Target is avatar that player received the most damage from.
- If no other avatars are targetable, player becomes target, even if in Vanish.
Lightning (lightning bolt, yellow, targeted) - Targets receive 30 damage.
- All targetable avatars (other than player) receive 30 damage.
Shotgun (rifle, yellow) - Avatars in the row or column of player receive 40 damage.
- Avatars with Shield or behind an avatar in Shield (relative to player), are exempt.
Shockwave (circle with 2 jagged outlines, yellow) - Avatars within 3 squares of player receive damage.
- Avatars within 1 square receive 40 damage, within 2 receive 30 damage, within 3 recieve 20 damage.
Special (star with outline, white) - Special changes by avatar type.
- Monkey - No special. (Icon is still consumed.)
- Chimp - Banana bombs.
- Avatars in every column other than player's column receive 45 damage.
- Avatar in Shield, or behind an avatar in Shield (relative to bottom of field) are exempt.
- Baboon - Smackdown (targeted) - Target receives 45 damage.
- Orangutang - Full Health
- Player's Health set to 100, even if game is Special: No Health.
- Player receives 3 (turns) to Shield.
- If player is in Poison, it is removed.
- Gorilla - Machine Gun (targeted) - Avatar receives 75 damage.
Berserker (clenched fist, blue) - Player receives 3 turns to Berserker.
- During Berserker all received damage from player, except Push, is doubled.
- Initial damage of each Poison is doubled. Subsequent damage is not.
- Special: Berserker triple damage causes triple damage instead of double.
Question: URL monitoring
I was asked by a not very technical friend, who was asked by another, to help them track where their son is going on the Internet. They are not technical at all, but they suspect their son may be visiting inappropriate websites, and if so, they want to talk to him, but first they want to capture the urls surreptitiously to see if their concerns are valid.
Well, truthfully, i do not know what to suggest. I searched and found OpenDNS which seems to have some services that allow URL monitoring (no timestamp thopugh). What would you suggest?
Mini rant: Stupid code (2)
More on the stupid code:
Some_Func, which is called at the end, INSERTs the new batch number to the log TABLE and includes an EXCEPTION block catching DUP_VAL_ON_INDEX and OTHERS.
IOW, this PROCEDURE makes a best guess at what the batch number will be, writes it to a bunch of files, and only then attempts to put it into the log. If putting it into the log encounters any errors, it logs that and exits without any record in the log of the job! The job currently takes about an hour or two to run. Seriously, what were they thinking?
The current situation can be remedied via a SEQUENCE. As long as noone breaks the rule that all ids be popped off it (which can be enforced by removing rights to the TABLE and forcing all writes to go through a stored PROCEDURE) everything will be fine until the SEQUENCE runs out of numbers.
Of course, this entire approach is just plain wrong. The correct way to log a run with a generated number which is used in the output, is to start by logging first. This garantees the number is recorded and lets others job easily use a further number. This is basic stuff.
To use a SEQUENCE (or even the MAX() hack), INSERT the number, and find out what it is, just use the RETURNING clause:
INSERT INTO Log(Id, Name) SELECT Log_SEQ.NEXTVAL, 'Moo' FROM Dual RETURNING Id INTO Batch;
Question: Cheapest health insurance
What is the the cheapest health insurance for an individual? The only thing it has to cover is the Obamacare tax.
Mini rant: Stupid code
Not only does this code have stupid constants, it has stupid code:
SELECT NVL(MAX(XXX_BATCH_JOB_R),0) INTO nBatchNo FROM XXX_BATCH_JOB_CONTROL WHERE XXX_BATCH_JOB_N = sBatchName;
IF nBatchNo = 0 THEN
nBatchNo := 0;
WHEN NO_DATA_FOUND THEN
nBatchNo := 0;
preBatchNo := nBatchNo;
nBatchNo := nBatchNo + 1;
8 similar references to these variables:
LPAD (NVL (preBatchNo,0),6,0) ||
LPAD (NVL (nBatchNo,0),6,0)
Some_Func(sBatchName, nBatchNo, v_updtPgm, nretcode);
There are no other references to these variables.
What is wrong with this code? Let me count the ways:
- The IF statement checks the 0 condition, even though 0 will work just fine.
- If it equals 0, it sets it to 0. Why?
- An EXCEPTION clause is used.
- The EXCEPTION is impossible, as MAX() is an aggregate function, and aggregate functions always return data
- The return is stored in one variable then immediately moved to another variable.
- The new new variable has a non-sensical name.
- The new variable breaks the Hungarian notation used elsewhere.
- The new variable is used eight times with formatting, and no where else. But the formatting is not done in the variable tiself.
- The new variable is always used with the old variable, for formatted output, yet they are kept separate.
- Both variables are NVL()ed over and over again, even though that was handled at the beginning.
There are other issues, such as the lack of a SEQUENCE to truly have unique numbers. But, those are trivial compared to the absolute stupidity of the block itself.
So, how should that code have been written?
SELECT NVL(MAX(XXX_BATCH_JOB_R), 0) INTO nBatchNo FROM XXX_BATCH_JOB_CONTROL WHERE XXX_BATCH_JOB_N = sBatchName;
preBatchNo := LPAD(preBatchNo, 6, 0) || LPAD(nBatchNo + 1, 6, 0)
Between the block and the NVL()s, i feel that the original coder was a blockhead that added no value at all.
Mini rant: Stupid constants
I am looking at a stored PROCEDURE as it takes too long to run. Besides the CURSORs, DECODE()s where NVL() should be used, and a UNION, there exists this stupidity up front:
csSpace CONSTANT CHAR(1) :='';
cnZero CONSTANT NUMBER(1) :=0;
How many things can you spot that is just plain wrong with that?
- It uses the misunderstanding of Hungarian notation.
- It uses Hungarian notation for a constant
- The constant is not an uppercase
- The contant says what its value is, as opposed to it itself is
- It uses CHAR(1) (In Oracle VARCHAR2 there is no benefit to CHAR over VARHAR2)
Why is it that good programmers exist only in forums and newgroups, but not in the real world?
Chronicle: Got a new job
I was looking for a job and an interview required references. I decided to put down an erstwhile supervisor and coworker, but only after aksing their permission. They both agreed, and i never heard back from that (first) place. (Not because of bad reviews, the head hunter explained they were excellent.)
A bit later, the supervisor called back with yet another supervisor, ready to hire me. He strongly recommended me to her, and she was willing to go with that. Asked if i wanted to be hired or contracted, i wanted to wait to answer, but they realized that as i only have a BA and not a BS, it would be better to contract and perhaps ask to be hired later. Fair enough.
I went for the interview which was toned down due to the recommendation, and the three supervisors (large project) seemed okay with me. Then the technical guy came in and asked me if i knew the things that the supervisor knew i did not know, and i answered accordingly. The idea was, since it's database related, i can learn it (quickly). I have a good track record learning the tools, and actually understanding what is going on.
Well, he nixed me. The supervisor was still going to hire me for an as-of-yet unknown position, after she got back from her two-week vacation. Indeed she did, and i started yesterday.
As she had no position for me, the other supervisor (the one i have worked for in the past) decided to pull me onto his project. The application was slow to begin with, expansion to Mexico made it even slower, and now with Europe on the map, it'll probably be redesigned, mostly because the database was not designed for it. Being that is my expertise, he wants me to do the redesign. Pretty kewl.
So, he (old supervisor) asked her (new supervisor) to move me to his project. Alas, she has finally found something for me to do. So, it's 50/50; working on two projects. The sense seems to be that she will hire anew, and i will switch to working for him 100%.
I was supposed to meet the two supervisors at 9am on Monday. I rented a car for the week, drove down the familiar road, and forgot one turn (different building). I called him after 9 asking for help, and he asked who was supposed to meet me. Well, that's kind of good. Noone "realizes" i am late on the first day. When i entered the building, he was waiting for me, he showed me to the other supervisor, drove me to get my badge, and showed me to my seat.
Getting the badge was simply enough Sit down and have her take a picture of me. She asked if i wanted to see it. As i didn't care, she went on to print the card.
I don't remember what it was, but my supervisor made some comment and i smirked. As soon as the lady saw that, she said something like, "ok, sit back down, we're taking your picture again, just keep smiling." She showed me the first picture too. I was less concerned about my facial expression, but my shirt and coat seemed a bit out of order. It's better on the second card, but i'm uneasy about that ridiculous smile.
Yesterday, i was asked to help someone with the website taking over a minute to load a particular page. When i asked to see the query, he said it was handled by toplink and he could turn on logging. While we saw which actions took time but the queries were still hidden. We were not getting anywhere.
When it was time for lunch, i explained our two options. One was to guess what the queries would be, see if they are slow and tune them, create an SP or VIEW, and have toplink call that instead. Or, find out where the appropriate loggin option is. I gave him my email address (work) and cell phone (personal, as i didn't have a work yet) to contact me when he wanted to continue, and i haven't heard from him since.
I got my phone, but am waiting for the computer to be replaced with the one i am supposed to be using. In the meanwhile, i cleaned the desk, drawers, keyboard, mice, and anything else with 409, and tidied up the wires with rubberbands. Other than that, there isn't much to do. When i get my computer, i'll have to customize it heavily, especially to get Windows 7 to be more like XP, which, for me, has increased functionality in the start menu and explorer. I'll probably install Libre Office so as to avoid the Office 2010 ribbons, which moved things sround so i can't find anything anymore. I'm so happy i switched to the mac at home.
I brought my Kindle to read during this expected downtime. I am a bit scared that i will lose it. Amazon will not track or deactivate ir (so i have read) and there really isn't a good way of identifying the device. With a cell phone you can at least call someone in the phone book asking them whose phone it is, but the Kindle has a first name. Even with a full name, it wouldn't say how to contact the owner. Perhaps i ought to put a sticky note on it. For now, i bascially leave it in my coat pocket.
Updating the Kindle here, though, is harder. Tryng to connect to the wifi results in an error, "Enterprise or peer-to-peer Wi-Fi networks are not supported." I guess i would just bring a USB cable here, But it really isn't that important.
Chronicle: Emailed Walmart about confusing item description
Walmart has a Slinky for $3.00. The description says: Clearance! Was $1.86. That seemed backwards.
So, i sent an email from their website:
Metal Slinky http://www.walmart.com/ip/Metal-Slinky/882938#Q%26A+Exchange
says the price is $3.00. The description says "Clearance! Was $1.86" Isn't that backwards? Because it went to clearance the price went up?
The response i received was
Can you please send us the link where you found the promotion.
To answer the question, i sent back
The site is Walmart.com: http://www.walmart.com/ip/Metal-Slinky/882938#Q%26A+Exchange
In red letters where it says Clearance! Was $1.86"
to which i received:
We sincerely apologize for the inconvenience but we are unable to do price match at this moment, please email us at firstname.lastname@example.org.
Did i miss something?
In response to a MakeUseOf post on apologies, i posted the following comment:
I use apologies, sorriness, and remorsefulness as three different things.
Apology is an explanation, as in Plato's The Apology. The sign in the image above that explains what happened is an apology. The usefulness of an apology is that the apologizer felt a need to give one, that is, he values the person he is apologizing to, and respects them enough to explain himself.
Sorriness is saying you feel bad that the other person was affected adversely, not that you would have done otherwise. The " This is much better" message is an example of it. The usefulness is to let the person know that you care.
Remorsefulness is (explaining that you are) feeling bad about what you did. The usefulness is to let the person know that you are humbling yourself by admitting guilt.
These three things are very important as not all situations call for all three. Indeed, sometimes using the wrong one can made a matter worse.
Apologizing is excellent when coming late (the first time), not doing things as expected, or any time the person on the receiving end feels belittled. When it is obvious that the apologizer does not care, does it quite often, or thinks apologies make everything better as if whatever-it-was never happened, the apology tends to infuriate the person.
Sorriness is to let people know you care. For example, when hearing something bad happened to someone else that you had nothing to do with "i'm sorry" means you care and means a lot to the receiver. Doing something you think is correct but adversely affects the other person, for example, a doctor taking blood or giving a shot that hurts might say "i'm sorry but this will hurt". In other words, i do not regret the action, but i feel bad that it will hurt you.
Remorsefulness is expected when people have their values slighted. A convict may be given a more lenient sentence if he shows remorse, a child may be forgiven if he really does feel bad that he broke the friend's toy, a relationship can be salvaged this way as well. Remorsefulness is the hardest of the bunch because the person must humble himself, a quality not often found in society.
The method of remorse is really based on the relationship the two parties have. The idea is not the words but the conveyance of actual humility. As this is based on many factors including the people involved, the amount of time taken between the offensive action and the expression of remorse, and the gravity of the offense, no real guidelines can be explained. Some can be via email, some cannot, though perhaps it can be a first step.
Looking for Galen's De Temperamentis in English (2)
Moving slowly along in trying to read Galen's De temperamentis in English, i came across Distributed Proofreaders which aims to proofread texts for Project Gutenberg. They have groups of people, some willing to type in projects before the proofread, though those projects are slow and not always accepted.
I was pointed to a page on proofing old texts which addresses some of the issues i thought were typographical errors. There are still those, but knowing the conventions of the time helps quite a bit.
The Kickstarter ideas seems to be a no go, though it seems is doable on Amazon's Mechanical Turk (sandboxed job). There is difficulty in the conventions used, and that many are not too acquainted with Latin. Typing it in as is seems okay, except the accented letters which are not on everyone keyboard. The Mac makes it easier with Characters (cmd-ctrl-space) which allows to save favorites and is easy to work with, but still it would encumber a fast typist. Learning the rules seems complicated and hard to check if done correctly, but perhaps using the base letter (English alphabet) plus a semicolon would work, much like the "q;" as a "que mark".
I was about ready to go there when i was pointed to the Distributed Proofreads possibility, which is where i am stalled. If that doesn't work out it is possible i may yet turn back to Amazon Turk.
Verbiage: I love Amazon reviews
I love Amazon because of the product reviews. Even when Slashdot was promoting the Amazon boycott over the 1-click patent, i mentioned (can't find my comment, /. seems to stop comment history in 2007 :( ) that B&N was terrible in that they only have positive comments on their website. A negative comment i left on B&N was deleted shortly thereafter. Amazon, however, keeps even the bad reviews.
Here's a couple that caught my attention recently. While looking for a bath overflow cover, this comment has a better idea. This product does indeed grow mold, look at the customer images on the left side of the main picture.
I was looking at comments on using a Kindle in the tub, where it was mentioned (seems to be a common idea) to put it in a ziplock bag to protect it from the moisture (which gets into the debate whether the buttons or swipe is better to turn pages).
I learn a lot from Amazon comments, the 1-stars often tell you what people are complaining about, and the 5-stars many times counter the complaints and have useful comparisons. The 2s, 3s, and 4s, similarly are helpful. I think Amazon's comments are what make Amazon such a great retailer. Well, not the only thing, but, even if i purchase something elsewhere i will go to trusty Amazon to find out the real deal.
Link of the day: How Hollywood Can Capitalize On Piracy
How Hollywood Can Capitalize On Piracy. Nicely written article, with a bit of history and research.