Live data from Hacker News

Twenty five thousand dollars of funny money

rachelbythebay.com

111–120 of 175 posts

Re: Twenty five thousand dollars of funny money

#111
post #44

Earlier quoted context omitted.

Seriously, since everything I work in is denoted as "cents" from backend to frontend, I personally had never understood the need This matches my experience. Obviously actual strict typing has its benefits, but as far as developer ergonomics are concerned, IME you can get about 95% of the benefits just by following a convention of including unit names in identifier names. It's easy to see why this Ruby code might fail…

Easy! # not happening unless developer consumes a large number # of drugs distance_miles = 42 launch_rocket(distance_km: distance_miles*1.6) Aaaand we're off by 0.3924km. Enough to fit 4 football fields with a few meters left over. Oopsies Units are hard. Never under-estimate the ability of programmers to think they're converting but get it slightly wrong.

It's within a significant digit of the specified distance, though. A few football fields of error seems pretty good to me for 42 miles. What's the required accuracy and precision for this rocket launching system?

Re: Twenty five thousand dollars of funny money

#112

One of the first programming languages I learned was TI BASIC on the TI-89. It had an excellent units (refinement types) system: you could define an expression as a "unit" by prefixing a variable with an underscore, and it came with a bunch of built-in units. A unit expression could thereby automatically convert between types as needed, outputing the base unit. E.g. `5_dollars + 8_cents` would output `508_cents`. The…

Looks neat. Of course you can do this in c++.

Re: Twenty five thousand dollars of funny money

#113
post #88
post #41

Had exactly that bug in production, was using ruby on rails & active merchant, and some version change in ActiveMerchant switched from cents to dollars for one of the integrations. Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. Shortly thereafter I get an anxious customer call that we'd charged their debit card $2500.00 instead of $25.00 a…

> Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. This is why I'm pretty dogmatic about variable comparison in tests. This is dangerous and stuff like this has caused a lot bugs to slide though in my experience (and maybe ops): expect(account1.balance).to eq account2.balance This is safe and specifc: expect(account1.balance).to eq 2500 expe…

thanks. i do the same and consistently have to push back on reviewers (why don't they learn?) that the hardcoded number is there for a reason

Re: Twenty five thousand dollars of funny money

#114
Just to say it, for measurements that take a unit I am hardcore that you should include the unit in the variable time:

`timeSeconds`

`distanceMeters`

`amountDollars`

Have unit tests and everything, but also write your code so that when someone reads it they know as precisely as possible what's going on without other documentation.

Re: Twenty five thousand dollars of funny money

#115
post #88

Earlier quoted context omitted.

> Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. This is why I'm pretty dogmatic about variable comparison in tests. This is dangerous and stuff like this has caused a lot bugs to slide though in my experience (and maybe ops): expect(account1.balance).to eq account2.balance This is safe and specifc: expect(account1.balance).to eq 2500 expe…

I fend off the "magic numbers" people with a variable with a name that describes what the magic number is for. var expectedAccountBalance = 2500 expect(account1.balance).to eq expectedAccountBalance expect(account1.balance).to eq account2.balance

That's a good enough (initial) workaround if you're in an environment where you're in the minority (or alone) w/ your opinion and you still want to do the right thing personally.

I would advise you to try and convince your peers though and teach them the better way because I suspect that the people that you're fending off would not do what you did but rather just go w/ the one

    expect(account1.balance).to eq account2.balance
Now while parts of the code base do the right thing (in a slightly long winded way), the rest of the code base written by these other people is still using bad tests.

Re: Twenty five thousand dollars of funny money

#116
post #41

Had exactly that bug in production, was using ruby on rails & active merchant, and some version change in ActiveMerchant switched from cents to dollars for one of the integrations. Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. Shortly thereafter I get an anxious customer call that we'd charged their debit card $2500.00 instead of $25.00 a…

I also had this problem—with the same stack—but the issue was quite subtle. It was due to an upgrade of the Money gem that changed the way "cents" were handled.

In our case we had test coverage, including integration tests with VCR recordings to the payment gateway. But the problem was that the bug only affect Japanese Yen, and we did not cover every single currency.

Re: Twenty five thousand dollars of funny money

#117
post #41

Had exactly that bug in production, was using ruby on rails & active merchant, and some version change in ActiveMerchant switched from cents to dollars for one of the integrations. Our test harness didn't catch it (weird combination of reasons, too long ago for me to remember the details) & it rolled out. Shortly thereafter I get an anxious customer call that we'd charged their debit card $2500.00 instead of $25.00 a…

Reasonableness checks are nearly absent these days. Warning the user "that's a lot of money/a date far in the future/a large quantity.[1] Are you sure?" detracts, I suppose from the UX. Except it really doesn't.

1. "Reasonable" varies according to the particular situation (customer's order history, credit rating, the normal range of quantites for the product, etc.)

Re: Twenty five thousand dollars of funny money

#118
post #48

I'm gonna be honest, I had never understood the "strict type" argument until right now. Seriously, since everything I work in is denoted as "cents" from backend to frontend, I personally had never understood the need so I'm part of today's lucky 10,000th.

This bug could easily happen in a typed language though. function deduct(int cents) { ... } int dollars = ... deduct(dollars); You need something like (Apps) Hungarian notation [1] as a minimum - or even better, subtypes of primitives like in Go to represent units in a typesafe way. [1] https://en.m.wikipedia.org/wiki/Hungarian_notation

That’s a generic type, and that’s why they’re not enough. Here's a simple Python example:

    class Cents(int): pass

    def send_money(amount: Cents):
    
        print(f"Sending ${amount / 100}")
    
    
    send_money(42)
That’ll immediately fail validation without you needing to make sure you have tests which would catch every possible problem like that.

expected "Cents" [arg-type] Found 1 error in 1 file (checked 1 source file)

In a language which has strict typing, you wouldn’t even be able to compile it.

Re: Twenty five thousand dollars of funny money

#119
post #82

I'm confused how this was able to give out money before the new code was submitted to production. The author claims that both she and her coworker tested it before the code was submitted and they ended up with the extra $25k. Was this code only executed on the front end? Were there no checks in the backend to prevent employees from just pulling out whatever money they wanted?

The way that things work at this particular company is that you typically test changes in this codebase on your dev machine, but usually the dev machine talks to a prod database. The prod database is too large to practically have a second copy sitting around for testing. Also, if you tested on some pristine small test database you're going to end up missing bugs that would only manifest with actual prod data.

I get it but that just seems really dangerous. I hope they have a lot of guard rails and roll back support or something.

Re: Twenty five thousand dollars of funny money

#120
post #44

Earlier quoted context omitted.

Easy! # not happening unless developer consumes a large number # of drugs distance_miles = 42 launch_rocket(distance_km: distance_miles*1.6) Aaaand we're off by 0.3924km. Enough to fit 4 football fields with a few meters left over. Oopsies Units are hard. Never under-estimate the ability of programmers to think they're converting but get it slightly wrong.

It's within a significant digit of the specified distance, though. A few football fields of error seems pretty good to me for 42 miles. What's the required accuracy and precision for this rocket launching system?

Well if it’s a boom rocket for war, the expected precision these days is the size of a car if not smaller.

I think even dumb gravity bombs in ww2 were more precise than “a few football fields”

Post reply on HN