Ask HN: Why do startups need so much money? - <AUTHOR>

Before I get downvoted for this, let me explain myself.  This is an honest question that has really been bothering me - especially lately, with all of the Yuri/YC hype.  When I think of a typical tech startup, I picture of a handful of brilliant fresh-out-of-college guys that are passionate about making things and solving problems [I know this may not describe the majority of startups these days, but it's all you hear about in the media so let's stick with it for the sake of this discussion.  Obviously the expenses are significantly higher when founders have families to support, mortgages to pay, etc.]
Anyway, I happen to be one of these guys (though a single founder), so I know exactly how much it really costs to get by on your own - here's some perspective.  I live in a cheap 5-bedroom apartment on a college campus (Champaign-Urbana IL) and drive a gas guzzling SUV (approx 11mpg).  Entertainment is negligible since I don't drink and rarely go to movies and such (that's all there is to do around here).  My combined expenses for rent, food, gas, and bills sits right around $600/mo.  I don't have a job, so for now, all of this is being paid for with the remainder of student loads and whatever I can scrape up.  I am fortunate enough to have supportive parents that are covering my insurance and phone bill (family packages) for the time being.  Even then, my total expenses should come in below $1000/mo.
So, back to these other young startup founders.  I think it's safe to assume that their circumstances are similar to my own, though I realize that cost of living is higher in the valley - especially rent.  I am only focusing on living expenses because they account for the vast majority of expenses for young startup founders.  Most YC startups say that almost all of their YC seed money goes toward rent, food and bills.  They rarely outsource work, do almost everything in-house, and usually wait several months or even a year before hiring other employees.  Server costs are minimal and offices non-existent.
Knowing that, I can't imagine the need for so much money.  Every day I read about startups that ran out of money and just couldn't keep going, but honestly - how much money do they really need?  Maybe I am naive, but young founders have the extraordinary advantage of minimal expenses and plenty of time and energy, so I don't see how this is possible.  Why do founders need hundreds of thousands or millions of dollars to "extend the runway"?  I'm pretty sure I could live on that kind of money for several years. <comment><USER2> The answer is that money = time. Or better, money = speed.

Money buys you an employee. Things get built faster.

Money buys you a design. Things look better, faster.

Money buys you more servers. The site is faster.

Money buys you tickets to X, where you can promote your site.

Money buys you traffic.

Money = speed.

If you can add a very talented person to your 1-person startup, your chances for success suddenly multiply. If you can build a kick-ass team, your chances for success are way up there.

The startups that "run out of money" don't really, usually, run out of actual money. It just means they couldn't build something successful and gave up on the idea, often because they had accumulated costs (employees, office, ...) that they couldn't pay for anymore.

That doesn't mean the alternative is to have everyone work for pretty much free. That's called open source. Different story :) (I'm probably a little off here with my logic, it's late)

<comment><USER3> i'll preface this by saying that i up-voted peter because many of the points were totally valid.

at the same time, i think money creates a distraction.

i've been bootstrapping for almost 3.5 years. throughout the process, i've built a team of four that all shares equity, and we've recruited more than 25 interns from UGA to help us through the semesters.

you know what my burn rate is? $50/month! i have one expense: hosting.

no one has taken any pay because they believe in the mission & they're motivated by the vision we have.

loren - i hear you my man. i think many of these YC companies will never learn what it means to be SCRAPPY. they won't understand how you can creatively finance things.

oh, last thing...i'm currently the live-in advisor at my old fraternity house...i know how to get by on nothing. just imagine what i'll do on something...

-adam

<comment><USER2> Don't you think money would buy you speed?

Also, your time may seem free now but it won't always feel like that.

</comment></comment></comment><comment><USER4> Depends on the scale you are talking about.

Can you create a one man startup and sustain yourself for $1000/mo? Sure.

Can you create YouTube, FaceBook, Google for the same? No, you really can't.

And if you are shooting for someone in between, can you compete against a similar company with 5-10 engineers when you only have one? Seems like a big disadvantage.

<comment><USER5> Without Customer Development Process (Steve Blank) you may not be building what the market needs. A solo startup might not be as productive as a 3-5 (or more) person team.

</comment></comment><comment><USER6> I think you have the causality reversed. The entire idea of investing in a company is that the company can take advantage of the investment to do better than it could without the investment. If you haven't got a way to spend the money productively, don't take it.

For as cheap as a startup _can_ be, it's the odd startup that honestly _can't_ make use of a bit of funding to do better. You really can't get any more value out of having an employee? If that's the case, then stop seeking investment. You don't really have a startup at that point, you just have a business that isn't seeking growth. (The definition of "startup" is certainly in the eye of the beholder and I wouldn't limit it to "those seeking home runs", but surely the idea entails _some_ sort of concept of succeeding and growing to some extent.)

</comment><comment><USER7> Someone posted a detailed answer on Quora but I can't find it right now, essentially hiring people. While you can feed you founders ramens, employees need to be paid market rate. $1 million dollars gets you 6 people for a year.

Sure you can try to do everything yourself, but you'll be destroyed by a competitor that can scale up by hiring more staff.

<comment><AUTHOR> By 6 people, do you mean 6 developers? If so - the market rate, at $166,667 annual per developer, is extraordinarily higher than I thought. That seems a bit pricey for a developer working at a scrappy startup.

<comment><USER8> You have to factor in other costs on top of the employee wage:Taxes, Insurance (liability/health,etc), Retirement/401k, Office Space (Rent & Utilities optional if running virtual)

I'm sure there are other costs some optional, some not. Depending on how lean you want to run you can have a very low overhead.

It also depends on what level of developer you are hiring.

</comment></comment></comment><comment><USER9> #1 Rule of a business if your not making a profit now, you won't make any later. About 99% of the time effort is equal to profit, (as an example not directed at op) don't like cold calling? To bad go do it.

</comment><comment><USER10> money is a common "key" to many doors and solution for many problems. not every problem and not every door, of course, but if you can throw some cash on some annoying problem to get rid of it, it may be better solution than solving it with your time

see also [http://teddziuba.com/2010/12/the-3-basic-tools-of-systems- en...](http://teddziuba.com/2010/12/the-3-basic-tools-of-systems- engineering.html) \- this extends to many other fields

still, having no money is not an excuse to be lazy

</comment><comment><USER11> I had this same question, thanks for asking it.

<comment><AUTHOR> Please upvote so we can maybe get some decent answers here.</comment></comment>


Spotify – security team response time - <AUTHOR> http://algorithm.dk/posts/reflected-xss-spotify-best-security-response-time <comment><USER2> From OP: "Spotify came to my attention because of that specific page as I'm currently looking to build a security portfolio."

This is almost as foolish as it is illegal.

Finding web security issues is much more complicated legally than finding security issues in desktop/server software. I can download and install Apache and test it on my local box and discover things like the Range Header DoS. There are no legal issues for me to worry about.

I can't download and install "LinkedIn" and test it for web issues. I have to test against their site running on their computers. Immediately in the US the Computer Fraud and Abuse Act comes into play (though the OP lives in Denmark). "Hmmm, let me 'test' random website X for something that could cause a DoS" is insane.

Even if a company has a formal "we are OK and authorize people to test our site for security issues" policy that is still extremely dangerous from a legal perspective. Maybe you are only authorized if you follow their specific disclosure policies. Maybe you are only authorized to do non-destructive testing. Every company is going to have some tipping point where, if you testing impacts X or caused Y downtime, that's enough damage where they will seek your prosecution.

Building a "security portfolio" against websites is a stupid idea with some potentially huge negative consequences. If anyone insists on doing this, at least go looking for issues in projects that you can download and audit locally.

<comment><USER3> Have to disagree with a few points here.

"Hmmm, let me 'test' random website X for something that could cause a DoS"

The author was testing reflected XSS which is inherently client side, there should be no case of concern for DoS here.

"Building a "security portfolio" against websites is a stupid idea with some potentially huge negative consequences."

The author mentions Apple, Linkedin, Amazon and AT&T all of which have some type of vulnerability notification program. (See [https://bugcrowd.com/list- of-bug-bounty-programs/](https://bugcrowd.com/list-of-bug-bounty-programs/) for a great list of programs) I would have to say that as long as the researcher was performing within the scope of the respective program, there should be no worry. I think it's the exact opposite of a stupid idea. Building out a portfolio within the scopes of the programs is a great way to build some security reputation.

<comment><USER2> I understand what you are saying, but I disagree with the risk/reward.

Yes, the author was testing with a reflected XSS attack string, and yes "there should be no case of concern for DoS". But that's exactly my point. You have no idea what effect that will have.

I personally have caused an inadvertent DoS attack with an XSS probe while doing a security audit for a large SaaS company. (The attack made the code throw and exception and some of my escaping characters caused havoc with their error logger, sending it into a infinite loop trying to log data, pegging the CPU and growing memory until the disk thrashed.)

You don't know what you actions will cause because the server/app is a black box. And if you want to audit that, you should have a formal agreement with the company that they know what you are doing and its OK. A generic, flimsy, non-personal "everyone can try and 'hack' us and it's OK" policy published somewhere is just too little protection, especially given how the CFAA is applied in courts today.

<comment><AUTHOR> Then what is the purpose of bug bounties in your perspective?

<comment><USER2> I think bug bounties can make the risk/reward ratio palatable, by either lowering risk or increasing the reward.

If a company offers monetary awards for web vulnerabilities in their site, that's a good sign. It shows they recognize the monetary value on what you are doing and made the decision to reward you. It shows the extent of their commitment to the bounty program that they have allocated budget and have accepted the added accounting challenges to provide money for issues. It also means that have thought through exactly what they are expecting and what they are willing to pay.

In my eyes, someone offering marketing swag or "putting your name on a web page" doesn't think your work is as valuable. Thus they are more likely to be angry and seek legal remedies should your testing cause them harm in some way, because in their eyes the value of your security testing or your findings doesn't out weight the damage.

In short, all of this is an indicator of how much thought was put into the company's policy on finding and reporting security issues, and how mature their reaction will be to things they have not thought of or bad things happen. The less mature, the more likely they are to decide your testing was "unauthorized" and to seek legal remedies.

Compare Spotify's policy [1] with Google's Policy[2]. Which one has put more thought and planning into running a program like this? Obviously people's risk/reward appetites differ...

Please note that I am taking the risks of bug bounties/"its ok to audit us" policies that apply public websites. The Stripe/Matasano challenges are specially created systems and are always a great thing to do.

[1]- [https://www.spotify.com/dk/about-us/contact/report- security-...](https://www.spotify.com/dk/about-us/contact/report-security- issues/) [2]- [http://www.google.com/about/appsecurity/reward- program/](http://www.google.com/about/appsecurity/reward-program/)

</comment></comment></comment></comment></comment><comment><USER4> The initial response was very quick, but honestly: Fixing such a simple XSS hole on a web application shouldn't take 7 days. In the age of automated testing and continuos deployment, escaping that parameter is trivial.

Granted. If you have a systemic issue and you need to fix your framework to always escape unless told otherwise, that will take longer, but it won't prevent you from quick-fixing just the reported issue.

<comment><USER5> I had to do a double-take when I read the "7 days" part, because I wasn't sure why that should be a pleasant surprise.

If it were their desktop client, that kind of turnaround would be understandable. For their website? I don't see why they couldn't have deployed a hotfix immediately.

On the other hand, perhaps they had a quota of more serious security issues and were preoccupied with addressing those.

<comment><USER6> It's likely that it was fixed sooner than that. I would bet they gave it 7 days before he could talk about it, so they could audit the rest of their site.

</comment></comment></comment><comment><USER7> _edit_ : oops. Didn't know it was actually a Sweden based company. (minus 1000000000 chars below).

Regarding the 7 days patch, that does look long. Not sure why. It'd be interesting to find out.

By the way, I like your resume. Visually impressive; a pleasant to read. It'd be interesting to see that being a shirt.

<comment><USER8> Actually Spotify is mostly Sweden-based but they seem to be ramping up on NY as well.

<comment><USER7> Oh! Thanks for the correction! I am surprised. They used to recruit a lot of U.S. based engineers last year as I was looking for job.

<comment><USER9> Yes, Spotify is a Swedish companies, but we have several engineering offices in the US and in Europe. The current openings are listed on spotify.com/jobs

</comment></comment></comment></comment><comment><USER10> Did they reward you in any way, or simply recognize your name on this list?

</comment><comment><USER11> Response time is useless if it still takes 7 days to deploy a patch for a simple XSS issue.

<comment><USER12> Totally agree with that. The important time is the one between the disclosure and the fix, not the one between the disclosure and the first response. It could be a bot :)

<comment><USER9> Trust me, Nenad is not a bot :)

We work hard on becoming better and faster at tackling these and other issues. We try to learn from incidents and mistakes in order to be faster next time.

Thanks for the feedback.</comment></comment></comment>


We called it RAID because it kills bugs dead - <AUTHOR> https://devblogs.microsoft.com/oldnewthing/20200317-00/?p=103566 <comment><USER2> I left MSFT and went to Viair (with folks from the MSN Mobile and Outlook Express team), and we didn't have a bug tracking system... so we had someone send us a few screenshots of RAID and built a VisualJ clone one weekend. Fun side project, didn't really want to be in the business of bug tracking, was slightly before the web app era... We called our bug tracking system "BlackFlag" because it was a competing brand of bug spray. (And obviously we used the logo from the punk band...)

<comment><USER3> Fun fact, one of Sweden's most influential music- and culture journalists was being interviewed on national television about a weird documentary wearing a pink "Pink Flag" t-shirt with a modified Black Flag logo. Beyond meta.

<comment><USER4> Is that a clever way of referring to Black Flag at the same time as Wire's Pink Flag?

<comment><USER3> That's how I interpret it. I actually asked him on Twitter an hour ago - I'll keep you posted :)

</comment></comment></comment></comment><comment><USER5> The bug puns were everywhere!

When I started working at Industrial Light and Magic in 1998, there was no bug tracker in regular use. I ended up building a bug tracker in Python called "Roundup" (inspired by a program by Alan Trombla, who came up with the name). To create the thinnest veneer of plausible deniability in case the bug spray lawyers came after us, the icon was a little spinning GIF animation of a cowboy on a horse, lasso curled in the air.

I only stayed at ILM for two years, but Roundup remained still in use as the ILM software department's main issue tracking system long after I left, at least 6 years later. It was one of the early issue tracking systems that made it easy to subscribe to any issue, so you'd get e-mail notifications whenever the issue was updated.

The issue identifiers were numbers prefixed with a code to indicate the affected software project, like "REN003" for a bug in the rendering system. Three digits, of course, because I could hardly imagine that a single project could ever have more than a thousand bugs!

I remember that along with statuses like "in progress" and "done", we had a status I've never seen anywhere else: "cbb". As in "done, but could be better." What optimistic software engineers we were back then!

<comment><USER6> CBB reminds me of the pieces of hardware I've labeled as "maybe bad".

Only to run across 2 years later, and find myself wondering "who was this 'future me' that I envisioned might be interested in an ethernet card that exhibits flaky behavior under high load when bonded?"

<comment> Anthony-G Been there and learned that lesson! Let's waste _future me_ 's time by having them figure out in what way the hardware might be bad.

</comment></comment></comment><comment><USER7> Fun fact: Apple's internal bug tracking tool, Radar, traces its origins to a pen-and-paper tracking system from the very early days.

In a similar fashion to RAID from the article, it's use expanded way beyond the original use case and is now used by nearly every team at Apple, from hardware, to test, to marketing, retail, and everything in between.

It's often the butt of a lot of jokes as most people hate its dated and confusing UI :).

edit: Though to be fair, the team maintaining it has made massive strides recently to completely revamp the UX which is no small feat given such a wide range of business critical use cases.

<comment><USER8> As far as I can tell, most teams think Radar is the best bug tracking tool ever. Externally, it's extremely frustrating to interact with, even more so through Feedback Assistant.

<comment><USER7> Actually you bring up a good point - the reactions are perhaps more bimodal than anything. If you're on one of the teams it was designed for, it is indeed near perfect. If not, it's far from it.

<comment><USER9> The UI was old and crufty and it was a pain in many ways to work with. But I really miss it because it's still better than any other issue tracking system I've ever used.

<comment><USER10> Can you elaborate on what made/makes it better?

</comment></comment></comment></comment></comment><comment><USER11> >>> they might have been too scared to write it. When looking back on the origin of RAID, one of the original developers confessed, "It really wasn't made to last that long. Sorry!"

This speaks to me - too many times we think we need clever architecture and well thought out methodologies and ... the most useful tools are a mix of inspiration and timing and luck.

Had the developers stopped to plan they would have built something with over 16 bits of primary key - and also made a hundred other "improvements" that would have destroyed all the value MS got out of it.

There is a point in this - it I am not sure I know what it is.

<comment><USER12> > Had the developers stopped to plan they would have built something with over > 16 bits of primary key

While true, this was in the 16-bit, Windows 1.x era. Also the ~640kb of RAM era (disks also werent that big either, DOS (v3.x) around that time only supported 32 MB partitions). Not sure which version of DOS Windows 1.0 ran on, I didnt use windows until v3.11 for Workgroups. A 32-bit primary key would likely have been seen as wasteful (not that I'm excusing it) and impractical, because you could likely never practically store more than 64k records on a PC of the day (and even if you could, you wouldnt have an disk left to do anything else).

<comment><USER13> He didn't say which platform it ran on. Was Microsoft still using Xenix internally at the time?

<comment><USER14> Yes, for a time Xenix was used for some proportion of internal development, IIRC for DOS.

I think I read that on here somewhere. I unfortunately don't have a citation. Need to get a time machine to take me to whatever point in the future I sort out my bookmarks ._.

</comment></comment></comment></comment><comment><USER15> Google's counterpart is called Buganizer. I've seen bugs in it dating back a decade or more. I don't know what, if anything, was in place before Buganizer. They might be exposing some version of it externally as well now: [https://issuetracker.google.com/](https://issuetracker.google.com/), although the UI bears little resemblance with the internal version I used years ago, so it's probably a separate product.

What Raymond's article does not mention (or at least I don't think he does, I have only skimmed the article) is that at MS each team had _its own_ bug database. As a result, even filing a bug in another product was an ordeal, let alone fixing bugs across products. What this friction means in practice is nobody would bother unless they really couldn't live without a fix. I think you can easily see the results of that in Microsoft products today.

At Google, _everyone_ uses the same bug DB. If a BigTable bug affects something in Ads, you can create a bug for BigTable and reference it in a bug under Ads, which is, IMO, the way it should be. Moreover, you don't need to get bug database permissions for BigTable, because you already have them.

<comment><USER16> I remember when I first started at Microsoft, I found some bug in some product and thought "I should file a bug with them"

Turns out there was no easy way to do that. I ended up emailing some person from the team I found in the GAL (I think that's what they called it?) and they weren't helpful or appreciative.

Never did that again.

<comment><USER15> I don't know how it is now, but you've just described every single well- meaning starry eyed fresh Microsoft employee in the 00s and likely before. The fact that management did not see how fucked up this was is a condemnation of the Microsoft company culture of that period. Again, don't know how it is now. I turned in my blued badge well over a decade ago.

</comment></comment></comment><comment><USER17> I'll take any opportunity to mention John Browne's "The Bug Count Also Rises"[1], which contains the line "The RAID is huge with bugs", referring to Microsoft's bug tracker. It was previously submitted to HN[2].

[1]: [http://www.workpump.com/bugcount/bugcount.html](http://www.workpump.com/bugcount/bugcount.html) [2]: [https://news.ycombinator.com/item?id=2740452](https://news.ycombinator.com/item?id=2740452)

<comment><USER18> What a poetic (and a little depressing-in-a-good-way) comment. I remember various times of my career being a glorified bug tracker. It's a bad mode to get trapped in with no forward progress.

[https://news.ycombinator.com/item?id=2740626](https://news.ycombinator.com/item?id=2740626)

</comment></comment><comment><USER19> Oh lord, product studio. Back in 2013 the preferred method of filing workitems for a given "wave" was to load this spreadsheet, do weiiird formatting, and indentation, type up all the workitems you foresee for the next sprint and then press a magic "send to product studio" button." God help you if you messed up some of the nesting or wanted to reorder anything - honestly I would just wipe it clean and start from scratch.

Ironically my team just finished a product called RAID that was designed to kill bugs in product studio and move them to DevOps. There are still pockets of teams that use Product Studio within Microsoft - the sufficiency gap is real - but they're the overwhelming minority now.

<comment><USER20> I had absolutely zero problems with product studio when I used it from 2008-2011. It was a very 1990s style MDI application, somewhat representing the peak of win32 ux design, short and to the point, and as long as the servers were happy it "just worked".

</comment></comment><comment><USER18> > Mind you, that doesn't mean that things have been stable, because the name > of the service changed from Visual Studio Online to Visual Studio Team > Services, and then again to Azure DevOps Services.

That's the most Microsofty sentence ever. It summarizes their allegiance to ever changing marketing goals over simplicity and consistency. Even for something like a bug tracker.

<comment><USER21> Before it was called Visual Studio Online it was called Team Foundation Server.

To make things even more confusing, there is now another product called Visual Studio Online, which is a completely different thing (it's a cloud IDE) [https://visualstudio.microsoft.com/services/visual-studio- on...](https://visualstudio.microsoft.com/services/visual-studio-online/).

</comment></comment><comment><USER22> The one thing all long-lived systems have in common: nobody ever intended them to be long-lived systems.

<comment><USER23> The quick and dirty Perl deployment system I built at reddit lasted nine years. Five years after I left.

I definitely never intend it to last that long.

<comment><USER22> My father wrote a dBase application _forty years ago_ that, to his amazement, is still in use in some places today.

Inertia is a hell of a force.

<comment><USER24> It probably has more digits for the primary key than the MS bug tracker originally mentioned. Sigh.

</comment></comment></comment></comment><comment><USER25> As an independent dev team working with Microsoft Games in 2002-2003, we used RAID to ship Rise of Nations. It was great! Rockin' fast compared with any web tool now and batch operations were near instant. Sadly it was utterly insecure for remote use and it went away after that game.

<comment><USER26> I loved Rise of Nations! Mind sharing which bits you worked on?

<comment><USER25> Single player campaigns

</comment></comment></comment><comment><USER27> I started at Microsoft in 1991, and remember RAID fondly. My favorite part back then (probably running on Windows for Workgroups): when you minimized the program back to its desktop icon, the icon animated for a few seconds, showing a can of bug spray firing on a small flying bug, which dropped to the ground.

<comment><USER28> For green-field projects (new projects/apps), you always had bug #1: "[Insert project codename] doesn't work. Severity: 1. Priority: 1."

Always interesting to read some of the bug reports; some of which could meander off-topic in interesting ways.

</comment></comment><comment><USER29> Sometimes I think bug tracking doesn't get enough attention. It's gotten a lot better these days but compared to source control, bug tracking seems to remain the red-headed step-child.

Bugs can be just as important as source code - if a line of code is changed and all the comment says is "bug 1234", then hopefully bug 1234 has context about the scenario that was broken, a history of a conversation between QA and development, and signoff from QA with whatever was verified.

Sure, this might fall into "write a good commit message", but obviously that doesn't always happen, and having the historic knowledge of the bug tracking database at your fingertips is important.

<comment><USER30> Fossil ([https://www.fossil-scm.org](https://www.fossil-scm.org) ) has an interesting approach to this problem - integrate bug and work item tracking, project wikis, and source control, but make them _all_ distributed, so that there is not a single master copy of the bug database or the docs wiki.

It attempts to solve both the cultural challenge (bugbase written by a different company/team from the source control, imposing 2 different styles on you) and the technical one (bugbase and source control don't talk to each other, and so bugs and checkins are not linked).

<comment><USER31> If only Fossil weren't so opinionated... I love the idea of bundling everything in the repo, and not averse to SQLite database as the storage format. But there's no way to edit history, even for commits that don't exist anywhere other than your own local repo - because the author considers rebase an anti-pattern.

</comment></comment></comment><comment><USER32> The late Joe Armstrong described the similarly minimal Erlang issue tracking system in this excellent post about MVPs

[https://joearms.github.io/published/2014-06-25-minimal- viabl...](https://joearms.github.io/published/2014-06-25-minimal-viable- program.html)

</comment><comment><USER33> Borland's bug tracking tool for Delphi was also called RAID.

It used the disconnected data set and resync technology that was part of Delphi itself, which was handy for remote working before always-on internet.

<comment><USER34> I wonder if Borland's RAID was inspired on Microsoft's, or just the same pun.

</comment></comment><comment><USER35> > Office cloned the source and built their own custom version

I found this bit amusing considering that (IIRC) the Office team also had their own C compiler :-P

</comment><comment><USER36> It's often the simple things, not meant to last long, but work well that live the longest.

</comment><comment><USER37> Who wants to celebrate the 18th anniversary of the oldest open Jira ticket with me? [https://jira.atlassian.com/browse/JRASERVER-161](https://jira.atlassian.com/browse/JRASERVER-161)

</comment><comment><USER38> And if you have disks in RAID a bug in it kills your data instead. ;-)

<comment><USER39> I was startled that they used the name RAID given the Berkeley RAID paper... but on checking the dates, they would have needed a time machine to realize that this term was about to become heavily overloaded.

</comment></comment><comment><USER40> Isn't RAID a way of storing all of the zero bits on one drive, and all the one bits on the other drive?

That makes replacement of a bad drive much easier.

</comment><comment><USER41> It's a weird, nice feeling watching your software in use well beyond it's planned - or more frequently, assumed - obsolescence.

<comment><USER12> What ammuses me is looking at some of the hard-coded "end of time" dates at previous employers. Instead of using null as an unbounded upper bound (because nulls are hard /s), there are hard coded "end dates". One was 2032-12-31, another 2037-12-31 and usually 9999-12-31. Obviously, these all have problems, especially when used in finance. 2037 makes sense, because 2037 is the year that 32bit linux overflows. 9999 also makes sense. At least none of us will be around, so it's some future generation(s) problem. The 2032 one made no sense to me, and I was never able to get a justification.

<comment><USER42> Now that it's 2020, I've been looking for a new year to think of as "the future". 2040 seems too obvious and maybe too far away to really imagine, what just add 20 years? Boring. I think I'll take 2032.

<comment> Paul-ish 2049, for the year the blade runner sequel is set in.

</comment></comment></comment></comment><comment><USER43> I'm sure RAID was much more usable than some of the ITIL-inspired monstrosities some of us have to deal with.

</comment><comment><USER44> > Unfortunately, the archive project renumbers the work items. Fortunately, > the original work item is remembered in the title, so you can do a search > for originalid:3141 to find the old work item known as number 3141.

I wonder what happened if a bug was carried over for 2 or more databases.

<comment><USER9> Presumably the archive projects are read-only and therefore once a bug goes into the archive project it never moves again.

</comment></comment><comment><USER45> I remember using RAID when I worked at Microsoft from 1993-1996

</comment><comment><USER46> Product Studio, RAID's replacement was great. I really didn't like the transition to TFS.

</comment><comment><USER47> > The database was written back in the days of 16-bit computing, so naturally > it had a limit of 32,767 bugs

I know it's a nitpick; but no, that is not natural to me at all. You can't have a negative bug or would store it in list with negative indices. So using signed makes no sense to me.

Sometimes I get really confused why signed shows up in places it doesn't belong.

<comment><USER48> > Sometimes I get really confused why signed shows up in places it doesn't > belong.

Because in the absence of convenient sum types, you end up using a simple type with sentinel/special values so often that anything where the main value is logically non-negative (or strictly positive) but you don't have a clear reason to never need special values is done with a signed type where negative (and possibly zero) values are reserved or assigned to special uses.

</comment></comment><comment><USER49> I loved RAID. Lightning fast, so fast that speed was its own quality.

<comment><USER49> Of all my comments, this is oddest thing to downvote! Is RAID bad now?

<comment><USER50> seek not to comprehend the downvoters, for it is written: it is simpler to predict each gust of wind in a storm, than to explain even a single downvote

or something

<comment><USER49> Thanks marvy, this made me smile.

<comment><USER50> :)

</comment></comment></comment></comment></comment><comment><USER51> it killed them dead by means of tracking and keeping them in an inventory...

</comment><comment><USER52> im a CMVC man myself

</comment><comment><USER24> Is it just me, or does this seem terrible? Lack of a stable business key & limiting key size to 4.5 digits just seems terribly lacking in any competent database practice.

I was building ISAM database applications for small business in the early nineties, and we used 6 digit keys.. and an index to access records by.

I'm sure Raymond Chen is a nice guy, but this just makes me think of a retard stabbing his cheek when trying to eat with a fork. (Dirty Rotten Scoundrels movie.)

<comment><USER53> Yikes, please don't post like that last bit here. I get that you probably meant it lightheartedly, but it does not come across well.

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

</comment></comment><comment><USER54> No you did not.</comment>


An Arizona superintendent on safely reopening schools: 'It's a fantasy' - <AUTHOR> https://www.washingtonpost.com/nation/2020/08/01/schools-reopening-coronavirus-arizona-superintendent/ <comment><USER4> And yet, Sweden never closed their schools - and as far as I'm aware didn't have increased incidence in teachers relative to the rest of the population. This article is about a teacher who got sick _despite not having students there_ , and who seems to have been in _increased_ contact with other adults relative to pre-COVID times. (Since she shared a classroom with two others while doing remote learning, which is presumably not normally the case) At least to me, that doesn't seem directly applicable to "can we bring back students safely".

</comment><comment><USER5> Much as with _Princess Bride_ , every line is quotable.

Unlike the film, most definitely not light comedy.

There are no good choices, no easy decisions, no Pareto-optimal solutions.

<comment> crooked-v There was an obvious optimal solution at the start of all of this, which is the same thing many other countries did: have a national lockdown for 1-2 months or so with everyone paid to stay home so that total number of new cases drops very low, then remove the lockdown and use comprehensive contact tracing and testing to quickly respond to new outbreaks.

Instead the federal executive branch acted in a worse than useless manner by being actively counterproductive, while various state governors refused to do anything because acting sensibly contradicted their political beliefs.

<comment><USER4> > while various state governors refused to do anything because acting sensibly > contradicted their political beliefs.

Aaand yet all the worst outbreaks early on were in the bluest parts of blue- or-purple states, and were under the control of Democrat mayors and governors. Who are also the ones with real authority, incidentally.

Now, the red parts of the map aren't exactly doing well right now either - <USER2> let's not pretend that only the Republicans fucked up on this one.

> have a national lockdown for 1-2 months or so with everyone paid to stay > home so that total number of new cases drops very low, then remove the > lockdown and use comprehensive contact tracing and testing to quickly > respond to new outbreaks.

I honestly think that Trump _could not have done this_. If he had tried - which would have taken a _large_ expansion of executive power - at a time that this would have helped, I wouldn't be surprised if he was impeached. You might remember what happened when Trump banned (a lot of) travel from China - <USER3> wasn't people saying that this was insufficient, it was people saying that it was _racist and unconstitutional_. Do you _really_ think that a response a thousand times as intense would have gotten a positive response?

<comment><USER6> Why do you come here to peddle that BS? What is the point?

Here is a clear example of the federal government siding against state's lockdown mandates

[https://www.vox.com/covid-19-coronavirus-us-response- trump/2...](https://www.vox.com/covid-19-coronavirus-us-response- trump/2020/5/23/21268394/justice-department-lockdown-coronaviruslos-angeles- illinois)

" The Justice Department is pressuring state and local officials over lockdown orders The DOJ is questioning the legal authority of top officials in California and Illinois to extend stay-at-home orders."

<comment><USER4> Well, when someone seems to be claiming that "everything would be fine if Trump wasn't a fuckup", I try to push back with "even if Trump wasn't a fuckup, there's enough other breakage in the way to prevent things from going perfectly". Trump messed up - that's kind of what he does. But with current US politics, there genuinely may not have been any set of actions Trump could have taken that would have both limited US cases to the levels Taiwan or South Korea encountered and not be impeached for it. (Because it would have meant doing things like "somehow convincing NYC to implement a no-seriously-you- stay-home order" and "implement a travel ban from _everywhere_ ", both of which would become a partisan issue and thus gridlocked)

A vox article about how the feds fucked up has no bearing on a counterfactual where the feds treated COVID like an existential threat back in February or early March. In that situation, you'd instead have an article saying that this was a major infringement on the rights of Americans, or that it disproportionately impacted a minority group. Which would have been true! But everything is a trade-off.

And as we can all see, it's not like the American Left has any real commitment to fighting COVID. Just look at how fast "stay the fuck home" turned into "protests are fine".

EDIT: you said "Why do you come here to peddle that BS?". I responded as if you thought my "I'm not sure anything Trump could have done would have turned out well" statement was BS, but you might have meant something else. Let me know!

<comment><USER6> To your edit: yes that's what I meant

You keep bringing politics into this - I think it's ridiculous that you consider impeachment a threat while Republicans control the Senate

The federal government has taken unscientific actions during a pandemic risking people's lives

<comment><USER4> And I continue to _not deny that the federal government has continually failed_. Instead, I've been saying that they're not the only ones to have failed, and that they're not always the ones with the most control. (Federalism is still a thing)

Further, impeachment only requires the House - conviction takes the Senate. And honestly, if Trump was enacting martial law, or anything similar, I don't think it would be too hard to get a few Republican senators to flip.

Really though, I brought up "what could he do without being impeached again" as a decent metric for "how much could he do before some cities and states told him to fuck off and stopped enforcing things". Incidentally, this would have almost certainly have gotten him reelected. Can you imagine the optics of "the states that followed Trump's lockdown orders were fine, while the ones that told him to fuck off have hundreds of thousands of dead"? (But this still wouldn't satisfy the hypothetical of "as good as Taiwan/SK", despite being better for the country and better for Trump personally)

</comment></comment></comment></comment></comment></comment></comment><comment><USER7> Bill Gates disagrees.

[https://www.foxbusiness.com/lifestyle/bill-gates-says- school...](https://www.foxbusiness.com/lifestyle/bill-gates-says-schools- should-reopen-despite-covid-19)

<comment><USER4> But Bill Gates is only a good person to listen to when he agrees with the current political zeitgeist - otherwise he's a billionaire monopolist who should thus be ignored.

Honestly, I'd love to hear what circumstances people would _accept_ opening schools in. Would "COVID is 10x less deadly than chicken pox for children under 15" be enough, if there was some way to protect teachers? What about "less deadly than driving to school for a year"?

<comment> crooked-v How about 'after successfully reducing new infections to almost zero', like many other countries? There are many solutions here other than 'shrug and give up' as the current federal government and many state governments have done.

<comment><USER4> And if that's the minimum you're willing to accept, that's fine! I'd also be ok with evidence showing kids don't die at more than 1 per million and also don't spread the disease to others. (This implicitly values a year of in- person education at a millionth of the life of a child. Arguably this is far too low, considering that we pay thousands of dollars for a year of education and almost every statistical measure of the value of life is under $10 million. If the difference in education is worth more than $100, that would put the acceptable deaths at at least 1 per 100,000)

If you're looking for case studies... Well, Sweden is the one everyone seems to be eyeing.</comment></comment></comment></comment>


Ask HN:Alternative to archiving email on Gmail - <AUTHOR>

I've got my email setup in such a way that all my email gets sent to an everyday email account, as well as a "backup/archive" Gmail account where nothing gets deleted.
Gmail's search has been the one thing that's kept my email archive useful vs. a stack of mail files in a folder.
My question is, what email archive/backup setups to HN'ers have? <comment><USER2> I use gmail accounts so all my mail gets sent there first. Then I use POP3 to retrieve new messages as they arrive. I save the important downloaded messages in kmail on my desktop computer and I delete the rest locally. If I ever accidentally delete an important email locally I just login to the gmail web interface and retrieve a new copy.

It's a good system because it archives all my email on the gmail server first, saves copies of the important messages locally, and eliminates more than 99% of my SPAM so I never have to deal with it.

</comment><comment><USER3> I'm interested in this too. The setup I'm running at the moment isn't optimal, and I've got a client that would like to have all of their email archived for compliance / contractual purposes, but can't use Postini or other third parties.

I've been playing with the idea of setting up a back-to-back email server rig, which should do the trick, but it's really inelegant.

</comment><comment><USER4> IMAP or POP3 download into a desktop client, with rules to filter messages into local folders.

Do it in Thunderbird or another client that saves message folders in a decent format (IIRC, Thunderbird uses mbox, which is quite a common text format).</comment>


How to Not Suck at Running a Kickstarter Campaign - <AUTHOR> https://medium.com/@jadojodo/how-to-not-suck-at-running-a-kickstarter-campaign-ee91319d776b#.el9dozcx9 <comment><USER2> >"I've never run a Kickstarter campaign, nor have I been involved with one in any capacity."

stopped reading right there</comment>


Git repository summary on your terminal - <AUTHOR> https://github.com/o2sh/onefetch <comment><USER2> Patterns of commit activity might be shown using unicode sparklines and/or a color scale (foreground and/or background).

"C++ (41.75 %)" seems a lot of ink and space for "C++ 42%".

</comment><comment><USER3> Reminds me of Ohloh (now OpenHub) but for your own projects and on command line.

<comment><USER4> Funny fact: actually there is _OpenHub_ [0] app for Android, that is just GitHub client.

BTW, I just curios, is it possible install & use _onefetch_ using _Termux_ [1] on Android?

[0] [https://apt.izzysoft.de/fdroid/index/apk/com.thirtydegreesra...](https://apt.izzysoft.de/fdroid/index/apk/com.thirtydegreesray.openhub?repo=main)

[1] [https://apt.izzysoft.de/fdroid/index/apk/com.termux?repo=mai...](https://apt.izzysoft.de/fdroid/index/apk/com.termux?repo=main)

</comment></comment><comment><USER2> Imagine one wished to collect interesting repo measures and visualizations. Any suggestions on fruitful places to scavenge?

"<This tool> has a nice one." "I frequently find myself checking a repo for <this measure>, and wish it was automated." "<Here's> a pretty way to present <measure>."

<comment><USER5> "gource" is pretty cool. It generates an animated history of all commits, visualized as authors pushing into files.

<comment><USER2> It[1] has a surprising large number of videos...[2]

Hmm, the documentation supports their creation.[3] "Encourage your community to create videos" as a way to raise awareness of a code analytics tool... I'd not thought of that.

[1] [https://gource.io/](https://gource.io/) [2] [https://www.youtube.com/results?search_query=gource&sp=CAI%2...](https://www.youtube.com/results?search_query=gource&sp=CAI%253D) [3] [https://github.com/acaudwell/Gource/wiki/Videos](https://github.com/acaudwell/Gource/wiki/Videos)

</comment></comment></comment><comment><USER4> I just touch it - and it _panicked_ :-/[0]

[0] [https://github.com/o2sh/onefetch/issues/120](https://github.com/o2sh/onefetch/issues/120)

</comment><comment><USER6> Nice! In the 2nd screenshot, how is it showing the image? Is that a terminal that can render images, or some clever conversion to ascii art [there's some ascii art related code in the onefetch repo].

<comment><USER7> It uses `kitty` terminal's built in support for images. [0][1]

[0] [https://sw.kovidgoyal.net/kitty/graphics- protocol.html](https://sw.kovidgoyal.net/kitty/graphics-protocol.html) [1] [https://github.com/o2sh/onefetch/blob/master/src/image_backe...](https://github.com/o2sh/onefetch/blob/master/src/image_backends/kitty.rs)

Note: iTerm2 also has its own image display protocol and for something more generic there is Sixel or w3mimgdisplay (from w3m).

</comment></comment><comment><USER8> I know this won't be an accurate representation, but sometimes I want to know how many hours I've spent on a repository.

I used git hours for this [0], but it's not well maintained anymore (has some problem on newer node version). I'm curious whether anyone else need this functionality.

[0] [https://github.com/kimmobrunfeldt/git- hours](https://github.com/kimmobrunfeldt/git-hours)

</comment><comment><USER9> An option to ignore some of the directories of the repository would be a nice addition (ex: ignoring ./vendor/ in golang repository).

Otherwise, nice tool, thanks for creating and sharing it.

</comment><comment><USER10> What's with the color palette at the bottom? Can I turn off the graphic?

Overall this is almost certainly becoming a staple of my toolbox.

<comment><USER11> Interestingly enough the color palette doesn't appear for me :)

<comment><USER10> Wunderbar.

<comment><USER11> Hahaha. Sorry, that wasn't meant to be a brag. I just know that I haven't turned anything off, so maybe it's a behaviour of a particular commit?

I installed via Cargo, version 1.6.5.

</comment></comment></comment></comment><comment><USER12> Is there a mac binary or homebrew formula?

<comment><USER11> `cargo install onefetch` should work

</comment></comment><comment><USER13> I thought this committed all my terminal commands to a git repo. It doesn't but now I want something like that.

<comment><USER14> Do you mean bash/zsh profiles or recent command history?

<comment><USER13> Command history

<comment><USER15> script -f filename ?</comment></comment></comment></comment>


Do snails have eyes? Seventeenth century doctor Sir Thomas Browne investigates - <AUTHOR> http://www.theguardian.com/science/the-h-word/2015/may/13/do-snails-have-eyes-seventeenth-century-mythbuster-and-science-communicator-sir-thomas-browne-investigates

<comment><USER2> Taking the question a bit literally: [http://www.molluscs.at/gastropoda/index.html?/gastropoda/mor...](http://www.molluscs.at/gastropoda/index.html?/gastropoda/morphology/eyes.html)</comment>


Raw data from a 40-year-old study raises new questions about fats (2017) - <AUTHOR> https://www.scientificamerican.com/article/records-found-in-dusty-basement-undermine-decades-of-dietary-advice/ <comment><USER2> Note that this is mostly about saturated fat sources versus polyunsaturated fats. These polyunsaturated fats were all high in omega 6, which is widely regarded as less heart healthy than omega 3 oils or monounsaturated fats such as olive oil, avocado oil, or high oleic sunflower oil. Equivocating the results here as plant fats versus animal fats misses most of the nuance.

<comment><USER3> In a sense, though, I think this is exactly the point of the article: when this study was run, we didn't know about omega-N fatty acid profiles of fats. So things that seemed "obvious" didn't pan out in RCTs like this one.

Today, most of the RCTs about things like omega-3 fatty acids show no effect. Why?

My guess at the root cause is a bit of scientific reductionism mixed with overgeneralization. Omega-3 fatty acids are a great example, and often it looks like this:

1\. Shockingly healthy population X has a diet rich in foods A, B, and C. What do A, B, and C have in common? Perhaps it's some micronutrient in abundance (like omega-3 in high-fat fish-eating cultures). Logically, the cause might be that micronutrient!

2\. Early observational studies that happen to pass publication thresholds show promising connections. People who eat salmon -- high in Omega-3 -- are healthier! They have lower triglycerides, or cholesterol, or whatever.

3\. RCTs show no positive effect from supplementing omega-3 fatty acids.

What happens between 2 and 3? Observational studies can't really isolate the effect of a single micronutrient, because there are a ton of interactions happening. Probably one of those other interactions is also necessary, but we don't know what it is -- much like how "plant fats" vs "animal fats" misses a ton of nuance.

I'm not really sure what we can do about this, though, except stop getting excited in phase 2?

<comment><USER4> Supplementing is not the same as avoiding. As you say, the interactions are complex. Maybe it isn't that supplements of omega3 are beneficial, since omega3 and omega6 compete, but avoiding omega6 while having sufficient omega3 gives the benefit. Any RCT support the negative properties of omega6?

</comment></comment></comment><comment><USER5> See the recent "FAT: A Documentary" (Amazon Prime has it) or the book "The Big Fat Surprise" by Nina Teicholz for many more details. I found these entertaining and compelling.

> The Frantz children always felt fortunate that their father brought his work > home, his beliefs about the dangers of saturated fat shaping what the family > ate. "Other kids would have ice cream; we had ice milk," recalled Ivan > Frantz. Bob said they were "reared on margarine," foreswearing butter's > saturated fat.

I think this is key. This debate isn't about corporate shills, but honest disagreement between sincere, hard working scientists. It shows how hard nutrition science in particular can be.

</comment><comment><USER6> So the population was mental hospitals and nursing homes?

They certainly isolated away exercise as a variable.

</comment><comment><USER7> Likely cause is the good old bias against publishing null or negative results.</comment>


The Higgins Boat: Wood, Steel, and Purpose - <AUTHOR> http://smallwarsjournal.com/jrnl/art/the-higgins-boat-wood-steel-and-purpose <comment><USER2> The Normandy landings were not in the Bay of Biscay.

<comment><USER3> It's funny because Operation Ironside - the operation to trick the Germans was intended to get the Germans to believe that the landings would be in the Bay of Biscay.

</comment></comment><comment><USER4> WW2, the original Worse Is Better:

M4 Sherman

PT Boats

Liberty ships

Almost everything the Soviets built

<comment><USER5> > Almost everything the Soviets built

The T-34. The epitome of sound, sensible, pragmatic engineering.

<comment><USER6> In the early part of the war the T-34 outclassed everything the Germans had. More were lost to mechanical failure than enemy action. As the war went on, the Soviets continued to simplify it until it became classic example of Soviet design we know about today (like the AK-47).

The extreme weather conditions and lack of availability of spare parts in the USSR lead to some awesome engineering:

Soviet aircraft can operate from the world's shittiest airfields: [https://youtu.be/uWUG1FuALaw](https://youtu.be/uWUG1FuALaw)

MiG-29 has extra intakes on top so it doesn't suck in junk from said airfields: [https://youtu.be/MpPSPQq7oas](https://youtu.be/MpPSPQq7oas)

Russian trucks: [https://youtu.be/5BRu-XGKdgU](https://youtu.be/5BRu-XGKdgU)</comment></comment></comment>


Moves for iPhone - Let your iPhone tell you how much you move - <AUTHOR> https://moves-app.com/

<comment><USER2> I've been using this for 42 days and it's pretty clever - it's mischaracterised less than a handful of events in that time.

Step counting is terribly wrong though - it has me at 100-150spm for walking when the Garmin footpod is reporting 55-60spm. The GPS tracking can also be wildly inaccurate but that's the iPhone, not Moves, at fault there.

Needs a proper export function too.

On the whole, B+, "Would take this app on a dirty weekend but not marry it."</comment>


New social network for gadget lovers now in beta - <AUTHOR> http://gadgetinity.com <comment><AUTHOR> Post gadgets you have, wish or just get interested with. Give your feedback on them. We'll find most interesting reviews and news for your tastes. If you wishlisted gadget, you'll get personal offers. Register now to become early adopters!</comment>


Python Image Vision library/framework - <AUTHOR> Which image vision library/framework do you think is best for the python programming language for object recognition(i.e recognizing people's body). Thinking of using opencv, is it good enough?. <comment><USER2> It depends on what you want to do. Opencv is amazing but it doesn't have easy to do high level stuff. It gives you the tools to implement computer vision systems, but you have to put the pieces together.

opencv does not come with models to detect objects and body parts out of the box(except for face detection), so you would have to find tutorials and learn how to do that recognition in opencv.

Building high accuracy detection systems is not trivial, so I would first look into apis from strong companies to see what is available. Start by googling "body part recognition API" and "object recognition API"

Some great detection apis are Google cloud vision, Amazon Rekognition, Clarafai, and there are a few others.

<comment><USER3> I agree - although I think there are three options:

1\. Deep learning - therefore any deep learning framework 2\. "Classical AI" \- use OpenCV for most of it 3\. APIs as you mentioned above</comment></comment>


Ask HN: Is there any good reason to use Google Checkout? - <AUTHOR>

I will be selling my software online soon. Is there any reason why I should support Google Checkout?<p>I would love to just use Google's solution, but I'm not sure there's a reason since PayPal has such a large market share. <comment><USER2> I have A/B tested this. GC + Paypal outperforms either individually for my site.

</comment><comment><USER3> We have a significant % of customers who use google checkout. Not sure the breakdown of Paypal vs Google checkout. Some people (myself included) prefer the simplicity of using their same Gmail account that they're probably already logged into vs Paypal. The more options the more better, if the integration doesn't give you too much trouble. The more ways to say "you don't have to give me your credit card info" the happier the customer.

</comment><comment><USER4> If most of your customers use a CC/DC, then support both.

The things that PayPal can do, but GC cannot are: payment from an existing balance, eCheck funded payments, micropayments.

The only advantage to using one or the other, is it would focus your payments towards getting up to the next tier in reducing your merchant fee percentage.</comment>


The Elements of Python Style - <AUTHOR> https://github.com/amontalenti/elements-of-python-style <comment><USER2> This guy got a bunch of things wrong:

> encode = lambda x: x.encode("utf-8", "ignore")

Why not rather call it s (short for str)?

> With tuple unpacking, using _ as a throwaway label is also OK.

Use __ (double underscore) instead so it won't clash with the gettext convention:

        from django.utils.translation import ugettext as _

> always use _args and_ _kwargs for variable argument lists

No, no, no, no, no! Why not clarify what are those accepted arguments?

What the following code is doing?

        def shuffle(*args):
            # do something

It shuffles SOMETHING.

And this?

        def shuffle(*cards):
            # do something

It shuffles CARDS. Big difference IMO.

> Use parens (...) for fluent APIs

I don't like that.

> Use implicit continuations in function calls

PEP8 suggest: "The preferred place to break around a binary operator is after the operator, not before it."

Following this logic, this should be:

        return set((key.lower(), val.lower()) for
                    key, val in mapping.iteritems())

(for at the end of the first line)

> Rarely create your own exception types

> ... and when you must, don't make too many.

Sorry but that's plain stupid.

> if item vs if item is not None

Yes, you should absolutely care. Not all the times, but sometimes a "NULL" value is different than a filled, but empty value. See zero. It's falsy, but totally acceptable input...

<comment><AUTHOR> I'm "this guy" who "got a bunch of things wrong" :)

Style guides are opinionated, and not everyone will agree. I intentionally made the style guide part of a Github repository so I could consider feedback from the community, and I've already incoporated plenty. As I mention below in the thread, I think you have a good point about "args" vs "cards" for your shuffle example.

Re: "The preferred place to break around a binary operator is after the operator, not before it", I think you mis-read this PEP8 suggestion. A binary operator is something like "and" or "+", not the "for" keyword inside a listcomp.

Re: your other disagreements, they amount to style choices of their own. When a style guide picks between two ways of doing things, there will inevitably be detractors, and I am OK with that.

<comment><USER2> If you don't use "if item" properly, it's bad code, not just style choice.

</comment></comment></comment><comment><USER3> > Use reST for docstrings

I would suggest also using the Napoleon [1] extension now included with recent versions of Sphinx. It allows you to use Google or Numpy-style reST formatting to describe parameters and types without all the javadoc-ish noise from :param:, :type:, and others.

[1] [https://sphinxcontrib- napoleon.readthedocs.org/en/latest/](https://sphinxcontrib- napoleon.readthedocs.org/en/latest/)

<comment><AUTHOR> Thanks -- we are actually discussing this possible change in a Pull Request here: [https://github.com/amontalenti/elements-of-python- style/pull...](https://github.com/amontalenti/elements-of-python-style/pull/4)

</comment></comment><comment><USER4> > If the strict 79-character line length rule in flake8 bothers you, feel free > to ignore or adjust that rule.

Thanks for remarking this. Too many people use flake8/pep8/pylint in commit hooks.

From the BDFL himself:

> "I personally hate with a vengeance tools named after style guide PEPs that > claim to enforce the guidelines from those PEPs."

> "[stylechecker] tools' rigidity and simplicity reflects badly on the [style > guide] PEPs, which try hard not to be rigid or simplistic"

> GvR

[https://twitter.com/raymondh/status/683793667996303360](https://twitter.com/raymondh/status/683793667996303360)

[https://twitter.com/raymondh/status/683809696902332416](https://twitter.com/raymondh/status/683809696902332416)

</comment><comment><USER5> My big problem when reading Python code are "from" and "as" in imports.

To illustrate: I read a function doing a few calls in file, and I want to understand what happens in one of the calls (a name without any dot prefix). So I do forward search for the name in the current file (a bit silly when thinking of it, but forward slash is so close to my index finger; and in web browser the search is forward by default), and it only finds it in imports in the beginning of the file after "from". At this point I lose the context of the function I was originally reading, because I have seen other chunks of code which I try to understand a bit. Also I lose the position of the original function in the file. If I want to dive deeper to the calls, I look up the module in question.

If the name would be use with full namespace prefix, like

      import datetime
      datetime.datetime.utcnow()

^ I could immediately see which module it's coming from and go there. Straight up! I wouldn't need finger acrobatics, and it would be readable in e.g. github code viewer.

If you are really bothered by the length of the dot-prefixed names, why not do

      now = datetime.datetime.utcnow()
      print(now())

^ That's all clear, and most likely you will fit to 79 chars per line.

Namespaces are a good idea, and explicit over implicit, right? I understand that there are some conventions (like _ for gettext), but I see importing names without dot prefixes as killing readability.

<comment><USER6> Minor nitpick: I think you mean

       now = datetime.datetime.utcnow # no parentheses

More generally, I think the strongest argument for using "from" is when you're dealing with redundant "foo.foo.bar" names. Would you really be confused at seeing "datetime.utcnow()" instead of "datetime.datetime.utcnow()"?

</comment></comment><comment><USER7> Good piece.

A (minor) nitpick.

On section titled '''Prefer "pure" functions and generators''' two "dedupe" functions are shown. They are stated to be the same but aren't. The first function returns the number of duplicated elements excluded (an int). The second function returns a set of excluding duplicated elements. It's true (in the first function) that the original list "items" will be modified to exclude the duplicated elements but an additional unshown step is needed in the second to determine the number... i.e len(items) - len(set(items)).

<comment><AUTHOR> I agree. I opened PR #19 to address this:

[https://github.com/amontalenti/elements-of-python- style/pull...](https://github.com/amontalenti/elements-of-python- style/pull/19)

Would love to hear what you think of the changes.

</comment></comment><comment><USER8> I've always been curious about docstring style. I've usually gone with numpy- style docstrings:

[https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMEN...](https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt)

They tend to be easier to read than reST, and happen to be used by the packages I use most (numpy, scipy). They are also easily worked into sphynx/napoleon.

2 questions:

1.) Why use reST instead?

2.) Why isn't there a python-wide standard or best practices as is found for Scala/Java/others?

<comment><USER9> From [1], the "Docstring Standard" section of your link, "Our docstring standard uses re-structured text (reST) syntax". It seems like they use reST?

1 - [https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMEN...](https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring- standard)

<comment><USER10> That's referring to the syntax in the docstring format they developed is only supported by reST, render by Sphinx's integration with reST. For exmaple,

        .. image:: filename

You don't get that in Markdown.

</comment></comment></comment><comment><USER11> > The biggest offender here is the bare except: pass clause. Never use these. > Suppressing exceptions is simply dangerous.

This doesn't apply if you're using exceptions as control flow, which is idiomatic and recommended Python behavior.

Let's say you want to make sure some file doesn't exist before you start doing something. Specifically, you want to wipe it out if it exists, and you don't care if it doesn't exist. You do:

        if os.path.exists(temp_file):
            os.remove(temp_file)

This isn't idiomatic Python behavior. Instead, you want to use exceptions:

        try:
            os.remove(temp_file)
        except OSError:
            pass

Mind you, an actual bare "except:" (without specifying an exception type) is still bad, because that'll catch things you don't want being caught, like a SystemExit or KeyboardInterrupt, but it's perfectly acceptable to silently pass in this case.

<comment><USER12> Even better (with Python 3.5 or newer):

        from contextlib import suppress

        with suppress(OSError):
            os.remove(temp_file)

More generally, context managers are the right way to refactor repeated try/except/finally clauses.

<comment><USER11> Well, I have yet another reason to migrate from 2 to 3 now.

</comment></comment></comment><comment><USER13> > _With tuple unpacking, using _ as a throwaway label is also OK._

I see this sometimes, but the problem is that this breaks internationalization using gettext, commonly imported under the name _:

       from gettext import gettext as _

(For those who've never seen it, "_" is then used as a function which wraps strings, like _("Book"); translation tools can then _parse the source code_ , deduce that "Book" is a term which needs translating, and at runtime the "_" function can return the translated term instead of the original string when a different language is needed. The name "_" for this functionality predates Python and is a common feature across most programming language using the gettext method of internationalization. It is therefore unfortunate that some Python users have taken "_" to be a kind of throwaway variable.)

<comment><USER14> I thought it was mostly imported as __ (double underscore).

<comment><USER13> No, I've never seen that. The normal single-underscore name is used in the Python documentation:

[https://docs.python.org/3.6/library/gettext.html](https://docs.python.org/3.6/library/gettext.html)

<comment><USER14> You're right, I was probably thinking of some other library/framework/language.

</comment></comment></comment></comment><comment><USER15> I agree with a lot of the criticisms. In addition,

1\. The prefixed underscore affects exports if you're providing an API in a package - see the standard library for lots of examples of prepended underscores.

2\. Don't use lambdas where a regular function definition works.

3\. Only use _args and_ *kwargs where these args are completely generic, otherwise be specific as to the semantics.

4\. Complex list comps should be rewritten to append to lists.

5\. Multiline condition statements should use indentation other than 4 spaces (2 or 8, for example).

6\. Don't use `if foo` when you mean `if foo is not None`.

Good luck with your style guide, I wish more people would make good style important to them.

</comment><comment><USER16> Most of it is pretty obvious. However, what I am still fighting myself on with Python is a project layout/module structure.

In languages with C++-like OOP model (Java, PHP) it's most of the time reasonable to settle on "1 file, 1 class" and to use directory structure the same way you use namespaces. Actually, in some such languages it's enforced.

For PHP it still leaves a problem with where you shoud put/expect to find anything beside classes, but it's fine, more or less. I hope some day we'll decide even more generally what works best, but for now it's decided per project/framework and it's mostly bearable.

For Ruby it's mostly the same as for PHP, even though the language is a bit more flexible. But it's still normal to use class as the main entity, so pretty much the same guidelines/problems apply.

For Python… I cannot decide yet, and what's worse, looking at the code on, say, Github, it doesn't seem like it's less of a problem for many others. Because some of "solutions" are seriously horrible. No project structure whatsoever, tens of classes in the same file. Classes, functions and even app- specific code (like GUI, CLI or HTTP-routing) all in the same file. Multi- thousand LOC files are considered completely normal. Ridiculous amount of code in __init__.py, that completely re-arranges submodule structure or even defines a bunch of new code. Hell, I've seen projects (more than 1) almost entirely written in the __init__.py! Please don't say you think it's normal.

I would say that things remind of "project-structure" in C, but (it's scary to suddenly realize that) it would actually be a compliment for Python, because even though large files are considered normal as well, with modern practices of writing C-code and all that "C-lang OOP" model stuff it's mostly clear where you should put something. With Python I'm never sure. The only way to find something is to use grep.

With things like that in Python, it's even no use to speak of a "project structure" in the more general sense, aside from what's enforced by the frameworks like Django.

So, any suggestions?

<comment><USER17> In PHP you create classes for everything because there is no other encapsulating scope. In that circumstance, with the class loader hook the language gives you, one class per file is a clear win.

In Python, with module-level scope, it makes sense to group like-functionality in the same module (aka _file_ ). Maybe it only seems "wrong" to you because it's different than other languages you're more familiar with?

<comment><USER16> Yes, it makes sense "to group like-functionality in the same module", but that seems to be the very problem. Because I already describes what it leads to, and compared with state of things in languages with more rigid code structure I cannot say it satisfies me.

And, just to clarify, I consider myself quite familiar with Python, because it's probably my first language I'm still using a lot, even though the language itself changed a lot during this time. That's about 10 years. And I am _still_ never sure where I'm supposed to put anything.

When 1 file contains everything there is to say about `time` — it will contain a lot, because there really is a lot to say about time. It's much easier to move around the codebase, when there are many files with clear semantic scope. Say, there's a module Time with a file (and a class) Timezone in it. Then, even though the class Timezone may be 4000 lines long — it doesn't bother me. If I assume that there's no crazy person working on that project, that would write something about product energy value in the class named "Timezone" — there's pretty much zero cognitive load of keeping that file in my text editor. Because I know, that even though 4000 LOC is quite a lot — there's nothing else in that file. There's no "before" and "after" that class. If I am not finding something here — it isn't here.

And the best thing is, that the directory structure can be quite nested, but feel pretty flat. The directory tree is completely semantic, there's no 1 directory with 200 files in that, there's clear meaning in that: src/Time/Timezone, src/Time/Datetime, src/Food/Components/Protein, src/Food/Components/Fat. I can execute `tree -f` in the console, and I already know a lot about what I can expect to find in the codebase. Discoverability is important.

It is also easier to review commits in CVS with a project structure like that. I can look only at files changed and I know, that somebody changed something in Timezone class, not just something "time-related".

With python it's a great deal harder to follow project structure like that. If everything can be grouped by file based just on "related-ness" principle — files can grow huge and I have to apply constant, significant effort to notice that something can become a sub-module, not just a file with bunch of functionality. And looking at the file with the same 4000 LOC becomes way harder: I don't know what else there is in that class, judging only by filename, assumption of developers being more or less sane and even the piece of code I'm looking at right now. There can be many things "related to time" before or after that piece of code. 4000 suddenly seems much larger than before, and the cognitive load now is quite significant.

That's why I'm looking for some "project-structure style guide" for Python. There needs to be some set of simple rules to follow, so that python project would not become the mess it always becomes. If we think it's reasonable to have a style-guide about "backslash vs parens in multi-line expressions" it's unreasonable to assume that project structure will grow just fine all by itself. Well, it contradicts my observations.

<comment><USER17> Python gives you packages for domains as large as "time". You would create a directory (for the uninitiated: with an empty __init__.py file in it) and now that directory is a package. The files within it are modules. There would be a time package with a timezone module within. That module would have the Timezone class.

The language has a feature -- a second level of scope -- that does need to be managed if used. You're right about that and it's a legitimate concern I suppose if it affects your throughput.

I suppose to me it's a win because my Python code has fewer classes than say my php code because I'm able to make use of module scope to provide encapsulation for things that don't need to be a class.

</comment></comment></comment></comment><comment><USER18> I can't take a guide seriously when things like this are sprinkled all over it:

        return [x
             for x in items
             if x.endswith(".py")]

        if (response and
            "data" in response and
            response["data"]):
            return response["data"]

Just use 2 lines instead of using valuable horizontal lines, and make the code harder to read.

ex:

        pyfiles = [x for x in items if x.endswith(".py")]
        return pyfiles

<comment><AUTHOR> It's a fair point, but the style guide is meant to be illustrative.

The former example is indented the way longer lines might very well be e.g. if your filter clause were a 2-part bool, you might not be able to fit it in a one-liner. The indentation also clarifies the difference between it and the imperative example above it.

The latter example is a rewrite of code written with 2 nested if statements, so the indentation serves to show that now the two nested statements were incorporated into the bool evaluation. If I made it a one-liner, someone might make the argument that the nested version is "more readable", but as written all you can say is that the single-if version is "less nested", which is the point I was trying to get across.

</comment></comment><comment><USER19> At first read this is a pretty reasonable doc for some things to consider. I also recommend watching the linked "PEP8" YouTube presentation from PyCON: [https://www.youtube.com/watch?v=wf- BqAjZb8M](https://www.youtube.com/watch?v=wf-BqAjZb8M)

From past projects, I got way more adherance-to-the-letter type patches versus "make this code pythonic and elegant" type patches, and the latter IMHO is more of the point of where things should go.

It's a bit of a long/slow talk, so if you find yourself getting bored, switch it up to 2x speed on youtube and I think many of you will like it.

My personal PEP8 ignore list was:

-pep8 -r --ignore=E501,E221,W291,W391,E302,E251,E203,W293,E231,E303,E201,E225,E261,E241 lib/ bin/

Which is quite a lot of it :)

Codebases are easier to understand when everybody's consistent within the codebase, but things need to be idiomatic well beyond PEP8 and it's easy to have a forrest vs trees scenario.

</comment><comment><USER20> >But another good example is rewriting an if/else chain as a dictionary lookup or repetitive code as a tuple of operations followed by a for loop.

I'm familiar with the dictionary lookup method but not the tuple. Perhaps it's obvious but could someone please give an example?

</comment><comment><USER21> All great tips, except I still feel could write docstings in markdown.

Is there a way to use Sphinx but with markdown?

</comment><comment><USER22> The grammar capos of python are back.

Can we get rid of the stupid indent vs tab stuff and have errors visible on screen without black magic?

Oh and maybe why not braces to really control variable lifetime?

        from __future__ import braces
        SyntaxError: not a chance

Ah ah what a joke.

Just remember that use strict exists in Perl and in python you have

        dyslexia=0
        if True:
            dylesxcia=1

will raise no error.

The strawman fallacie of python purity of style</comment>


The future of free - mkr-hn http://www.bitcreature.com/editorials/change-the-game/

<comment> mkr-hn The title here is very different from the title on the article, but it seems like a better fit for the content.</comment>


String.intern() - <AUTHOR> https://shipilev.net/jvm-anatomy-park/10-string-intern/ <comment><USER2> Every time I see String.intern() my mind leaps to the problem of new Java programmers who are misled into this:

        String a = "hello";
        String b = "world";
        assert a != b;
        b = "hello";
        assert a == b;
        // OH NICE I'LL USE == FOR STRING COMPARISONS NOW

It works cause source-code literals are intern'ed down into identical objects by the compiler, but that's a special case that won't apply to strings created at runtime.

<comment><USER3> _new Java programmers_

Or perhaps _interns_? ;-P

In fact, I've wondered about the origins of the term "intern" since I first heard of it; the technique was already known to me and likely others as "tokenising" before that, however, since compilers would often have to compare identifiers and doing this to them made it much faster.

<comment><USER4> It's from Lisp, and where did Lisp take it from in the sixties, I don't know. But I'll bet that this particular Java method comes straight from Lisp, as there were some Lisp folks involved in making Java (in particular, Guy Steele worked on both Common Lisp ANSI standard and Java language specification).

<comment><USER5> And was one of the Scheme creators.

</comment></comment></comment></comment><comment><USER6> This is really an unscientific claim but I ran a hand crafted/hacked benchmark just to get a feeling for the numbers. For 5 to 35 character Strings, == is 20 to 40 times faster than String.equals().

Given that s1.equals(s2) if and only if s1.intern() == s2.intern() (assuming you haven't filled the string table), then this looks like an opportunity for a significant optimization.

Before doing this, I had hoped that String.equals might check if both were "interned" and shortcut the character by character comparison if this was the case by just comparing references. But interpreting the results of my rough benchmark would suggest this isn't what is happening which would agree with the source provided for the String.equals method.

Java String comparison is absolutely ubiquitous so I would have expected that an optimization like this might have been considered?

Having said that, the supplied rt.jar source also suggests that the String.hashCode() computation isn't cached/memoized. This strikes me as odd given that Strings are immutatable and Strings are one of the most common key type for Maps.

<comment><USER7> This is from Oracle JDK sources:

        public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            ...

So if both strings are interned, this shortcut will work. I guess, your benchmarks were wrong. Microbenchmarks in Java are hard to implement correctly.

hashCode is cached as well in field `hash` and lazily computed:

        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;

                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }

Everything there is optimized till the last cycle, I'm sure about that.

<comment><USER6> I hadn't spotted that in the hasCode() implementation. Thanks, that makes sense.

Regarding .equals(), indeed that shortcut exists but it didn't help my benchmark because it spent nearly all it's time comparing Strings which were not equal.

I switched the benchmark to compare all equal (interned) Strings and even then there .equals() is about half the speed of the reference equality check. I guess because of the method call overhead?

Yes I would have been sure that everything to do with Strings would have been optimized to the last cycle hence my surprise. I'm not sure about the state of Java intrinsics with the Oracle JDK but I would have thought that most of the String methods would be handled by intrinsics and be very heavily optimized.

Edit: correction - indeed microbenchmarking is tricky and I had a bug. If the (interned) Strings are equal then .equals() and reference comparison run at roughly the same speed.

<comment><USER7> I don't think that JVM will do magic and execute something different from actual sources, even for String. On the other hand, optimizing those bytecodes to compile to perfect machine code or playing with code to produce bytecode which will be correctly optimized by JIT is more reasonable approach, not only java.lang.String would benefit from those optimizations, but any other developer with similar code.

Method call overhead is real and calling equals method is slower compared to reference comparison, but eventually JIT might decide to inline this method call, so there'll be no overhead after that. Anyway it's unlikely, that those difference will be noticeable in real code, IMO.

</comment></comment></comment></comment><comment><USER8> Total aside from main topic, I love shipilev's posts.

If there are other core JVM developers that have similar blogs, I'd love to hear about them here.

</comment><comment><USER9> We built an inmemory map and we were using String.intern for both keys and values. We could see that we were saving lots of memory but we had the problems described in the article. We then built our own 'String.intern' by using yet another static HashMap. It worked. It was the simplest alternative and it just did the job. Thanks alekskey for the nice article.

</comment><comment><USER10> I'd never seen the @Benchmark annotation before so I looked it up.

The blog author is also one of JMH's authors.

[http://openjdk.java.net/projects/code- tools/jmh/](http://openjdk.java.net/projects/code-tools/jmh/)

</comment><comment><USER11> Have been doing Java for 14 years so far, never ever needed the .intern(). I can imagine it's use-case, but anyway does seem pretty rare case.

<comment><USER12> Deserializing tons of records all having one of a few values for a particular field is an easy and probably fairly common use case.

</comment></comment><comment><USER13> Is "Anatomy Park" a Rick and Morty reference? [http://rickandmorty.wikia.com/wiki/Anatomy_Park_(episode)](http://rickandmorty.wikia.com/wiki/Anatomy_Park_\(episode\))

</comment><comment><USER14> Please consider adding "JVM Anatomy Park" to the title.

</comment><comment><USER15> The code creates unique strings to "interns" which most likely isn't what would happen in a real world application (unless you know... code without thought), you'd inter strings with low variance usually. Not saying that it won't be slower but the memory usage might be lower.

<comment><USER16> Yeah, blindly interning strings isn't a good idea, but it can be useful for certain use cases. For example, keys of maps where you know the keys won't vary much. It can reduce memory usage, and improve lookup performance (since doing a lookup requires a string comparison).

</comment></comment><comment><USER17> This, and the few other articles up, are a great series. Having done Java development now for 30% of my life these are some amazing pointers.

I'd love to buy a hard copy of these if they ever get up to a few dozen articles. Would be good to give to middle-experience devs (like myself) in the future.

<comment><USER18> Some good content along the same vein with 16 years worth of articles: [http://www.javaspecialists.eu/](http://www.javaspecialists.eu/)

</comment></comment><comment><USER19> "The performance is at the mercy of the native HashTable implementation, which may lag behind what is available in high-performance Java world, especially under concurrent access."

What native HashTable is used? Shouldn't the JVM be using an optimized one?

<comment><USER20> I think by "native" they mean "implemented-in-c++-by-the-JVM", which potentially vary; not java.util.HashTable, which should be pretty standard across JVM implementations.

<comment><USER21> Yes, although Hashtable is legacy from JDK 1.0. New code should use HashMap or ConcurrentHashMap.

<comment><USER22> Please be careful with blanket statements like this. HashMap, Hashtable and ConcurrentHashMap behave differently in certain (subtle?) ways. ConcurrentHashMap doesn't like NULL but is thread-safe. Hashtable is synchronized, slow and thread-safe, but doesn't mind NULL. HashMap is not thread safe and doesn't mind NULL.

Edit: pardon the dupes, on unreliable mobile link :-(

<comment><USER23> > Hashtable is synchronized, slow and thread-safe, but doesn't mind NULL.

The issue with Hashtable or rather all legacy collection classes is that the API is rarely useful without additional synchronization. So you might as well use a HashMap wrapped by Collections.synchronizedMap or use a ConcurrentHashMap with a placeholder object instead of null.

</comment></comment></comment></comment></comment><comment><USER24> String.intern() would suck much less if strings had an "IS_INTERNED" flag which would prevent hashtable lookups for already interned strings. Really sad given the insane overhead Java strings have.

<comment><USER25> No, it would suck more, because currently you have an option to avoid string.intern() altogether (and that is what you should do), and pay nothing for that in runtime. Another boolean flag may cost extra 4-8 bytes on the heap for each String object, whether you use String.intern() or not.

</comment></comment><comment><USER26> > in OpenJDK, String.intern() is native, and it actually calls into JVM, to > intern the String in the native JVM String pool.

How much of this also applies when using the standard Oracle JDK?

</comment><comment><USER27> It would be interesting to know where it's used, was it used in the JDK for example?

</comment><comment><USER28> Also see:

XInternAtom (XWindow function)

RegisterClass (Windows)

</comment><comment><USER29> The instrumentation here is impressive. The amount of data inspection done with just a few simple commands is a bit overwhelming. Frankly, I rarely hope to find myself looking at this level of metrics.

There's a lot down there I like to take for granted. But more likely I try to use methods like string.Intern() exactly never.

Use code you know and understand. Frankly, use code you can trust. And wtf would trust a method string.Inter() to do... exactly, what?

If you are writing a function to _do something_ the name of the function must be the thing being done. What the heck is a 'static internalize'? The explicit HashMap was a few lines of code, and it's the most basic and obvious, and surprisingly performant approach. So definitely I agree you must use your own HashMap and not a static internalizer.</comment>