Coronavirus: China's Hubei reports 14,840 new cases, 242 additional deaths - <AUTHOR> https://www.cnbc.com/2020/02/13/coronavirus-latest-updates-china-hubei.html <comment><USER2> I think we were all suspecting this, consider the graph at:

[https://www.worldometers.info/coronavirus/coronavirus- cases/](https://www.worldometers.info/coronavirus/coronavirus-cases/)

Observe the "Daily New Cases" graph, that looks like a sawtooth. It's very easy to mentally fit a straight line on the left edge, and another straight line on the right edge.

Now pretend the actual detected cases simply continued on the original straight line, then at ~Feb 11 it would reach about 6k per day, instead of falling down to 2k per day.

So the missing triangle has a base of about 7 days, and a height of about (6k - 2k) = 4k per day.

The missing people under the area is thus base * height / 2 = 7 days * 4k per day / 2 = 14k people...

The reason we all knew the crooked graph had to be false was because if you consider the time distributions from infected to infectious, from infectious to encountering a new person etc... then these distributions convolve, so you never get these simple instantaneous hard bends.

The new numbers tell us that the original trajectory is continuing roughly unabated!

So was this deception to buy time? build hope? it doesn't make any sense. Unless Xi is so desperate as to become an inside trader and manipulate the worldwide markets?

<comment><USER3> I was also tracking this graph and had built my own projection based on it.

After a day or so of thinking about it and seeing my projection match what was being reported, I concluded China chose this function because it shows a concern but does not cause great alarm. A predictable upward linear growth. Unsettling, but not terrifying.

I had considered how to get actual accurate death data, and figured it was impossible. However, there was some new, somewhat reporting from cremation facilities in Wuhan that, if true, paint a very dire picture.

[https://www.epochtimes.com/gb/20/2/5/n11845444.htm](https://www.epochtimes.com/gb/20/2/5/n11845444.htm)

I doubt this is about markets now, this is as it has always been, about "stability." The emergence of a true threat to stability that can not be controlled by the worlds most successful authoritarian state is so unexpected that I suspect the Xi and the politburo have been caught completely off guard and unable to change strategies to contain the threat.

If they had been truthful about the deaths from the beginning, demonstrations might have occurred that would have made things worse for everyone.

I think that we are going to see continued sharp rises in reports of deaths now that WHO officials are on-site and it becomes more difficult to hide the scale of what is most likely a global catastrophe.

<comment><USER2> >After a day or so of thinking about it and seeing my projection match what was being reported, I concluded China chose this function because it shows a concern but does not cause great alarm. A predictable upward linear growth. Unsettling, but not terrifying.

Initially the expansion was clearly exponential as evidenced by the clean straight line in the log-linear plots.

Under high mixing conditions (like a high N-dimensional cube) this is to be expected for the initial breakout.

Then quarantine and lock-down measures came, and experts expected the second derivative of the cumulative infections to reach a constant, which subsequently happened.

I witnessed a lot of people not understanding 1) why a simple quadratic? 2) why is a quadratic any better??

When there social distance measures are in effect, the virus can only diffuse on territory, and not "teleport" by public transport etc.

This means that it can only spread in 2 dimensions.

Consider the oversimplification of an epicenter, with a disklike area of infection, then a constant radial ground speed through diffusion, would mean the infected area would increase quadratically with radius. And the radius would increase proportionally to time (effective ground speed, since 2 months from now people will not be able to suddenly sneeze 2 times as far...).

So the cumulative number of infections would hence increase quadratically with time.

If we knew the eventual infection percentage (which Gabriel Leung estimated as potentially being 60%?), then we could calculate the effective radial ground speed:

If P is the number of people per area A then rho = P / A is the population density.

If only a susceptible fraction S can get infected and assuming a circular disk, with A = pi R ^ 2 = pi v ^ 2 t^ 2

Then we can calculate the cumulative number of infected people N as N = rho * A * S = rho * S * pi * v ^ 2 * t ^ 2

so the daily new cases would be

dN / dt = rho * S * pi * v ^ 2 * ( 2 * t )

and its slope X would be:

X = d ^ 2 N / dt ^ 2 = rho * S * pi * v ^2 * 2

(units: confirmations per day, per day or confirmations per day ^ 2)

solving for ground speed:

v = sqrt( X / ( rho * S * pi * 2 ) )

Sadly I can not read Chinese for your link, can you fluently read Chinese or did you use something like google translate?</comment></comment></comment>


Germany Closes Book on World War I With Final Reparations Payment - <AUTHOR> http://www.spiegel.de/international/germany/0,1518,720156,00.html <comment><USER3> Wow, that's interesting. I didn't know they resumed payment after WW2 - <USER2> always assumed that it was over when Hitler refused to continue paying.

My history teacher (in Germany) didn't mention anything about continued payments, either.

I don't know how to feel about this, but given that our own government created a huge debt after the 1974 oil crisis and again after the unification, I couldn't blame our debt on the reparation payments.

<comment><USER4> It's even more interesting: payments were officially suspended in 1953 until Germany would be reunited - which nobody expected to happen in the foreseeable future. The bonds were near worthless curiosities until things happened quite suddenly in 1989...

</comment></comment><comment><USER5> And just 4 years short of the centennial of the beginning of the war!

</comment><comment><USER6> Personally I find this sort of stuff interesting but why is it on Hackers News?

<comment><USER7> I think in the submission policies there is a point "if it would interest a geek, it is ok to post it" (not literal :) I think it is interesting, too!</comment></comment>


Ask HN: Philantropic Organizations looking for ML/AI help - <AUTHOR> Looking to volunteer some of my time and skills. <comment><USER2> You could see if you are a good fit for the organizations that DataKind[1] represents.

[1] [http://www.datakind.org/](http://www.datakind.org/)

<comment><AUTHOR> Thanks! will take a look

</comment></comment><comment><USER3> What methods are you good at?</comment>


The "Post-Mom" Economy - <AUTHOR> http://bostonreview.net/gender-sexuality/sarah-sharma-going-work-mommys-basement <comment><USER2> Actual title is "Going to Work in Mommy's Basement".

Wanders from Roosh V to Damore to "gendered technologies", without really making a point. Saved you a click.</comment>


Steve Ballmer calls Apple's Mac growth a "rounding error" - <AUTHOR> http://www.appleinsider.com/articles/09/07/31/steve_ballmer_calls_apples_mac_growth_a_rounding_error.html <comment><USER2> This wasn't a smart thing to say. Apple's growth is real. While it may not be a threat to Microsoft's profits, calling it a rounding error just seems out of touch with reality.

If anything, Microsoft should play up two things. First, that they believe their products offer a superior value, choice, and flexibility when compared with Apple's as their "laptop hunters" commercials portray. That counts for a lot. Second, that Apple's health shows that competition is alive and well in the computing market which will drive all parties to produce the best products they can.

Saying that Apple's growth isn't real simply comes off as out of touch with reality. It makes it seem like you don't know the market well enough to see the obvious and, if that's true, how can you steer your company to success? Similarly, if Apple were to simply dismiss Microsoft's "laptop hunter" commercials as not connecting with people, they'd similarly be out of touch.

Both offerings have strengths and weaknesses. Pretending that isn't true might win you points with fanboys, but makes you seem out of touch to the 90% who aren't die-hards on either side and try to buy what's best for them.

The key is getting across the point that your product has continued value, not that someone else's product doesn't have value. Windows is powering more computers than ever today as the market expands. Windows provides a low-cost (compared to Apple) operating system that maintains a high level of compatibility that businesses demand. Similarly Apple should stress that they offer an elegant, integrated experience with greater interoperability than ever.

Fanning flame wars as an executive just seems immature.

<comment><USER3> Ultimate in hubris: IBM regarding Wintel [Edit: PC] offering as a "toy" circa 1984. This seems to be in that same spirit.

Apple's Standard Oil model of business (fanatical control of every aspect of its products) has given it certain major engineering advantages but has limited its desktop share to that of a strong high-end niche - great for connoisseurs and for those on the cutting edge, less appealing to those who need to solve immediate business problems with cost-effective solutions.

It was a seismic shift ala first-time-ever mass computing that blind-sided IBM and caused it to lose hegemony in the enterprise market. That could happen today as well (though not from the Mac itself, which will remain a high-end niche product), and I would suspect that Microsoft is not nearly as sanguine in the back room about the threats to its dominance as it lets on. Agreed it is not wise to put on an arrogant face about it.

<comment><USER4> Hm? Windows was first released in November of '85, and the first release that achieved significant popularity was released in '87. Do you mean to say IBM regarded the Apple Macintosh as a toy?

<comment><USER3> I really messed that one up.

IBM senior management regarded the desktop PC manufactured by its own Boca Raton division as a toy.

What IBM missed (with all its big-systems hubris) was the competitive threat that arose when it gave Intel and Microsoft a vehicle by which to seize the future of mass computing when they got to supply the key inner parts for the PC.

"Wintel" was intended as a shorthand reference to the Intel/Microsoft teaming but it was obviously a poorly chosen term to refer to the early 1980s era, when Windows didn't even exist.

</comment></comment></comment></comment><comment><USER5> Is it really about market share? The cool one is the one who innovates, the one who changes market landscapes. Apple does that. Microsoft doesn't. Microsoft shouldn't worry about gaining the rest 10% of the OS share. They should worry about why they aren't innovative.

<comment><USER6> _Is it really about market share?_

Yes. Getting market share means you've a product that lots of people want _and_ you've figured out a way to get it to them.

Just because Microsoft does not fit in your narrow definition of innovation does not mean that they are not innovative.

 _The cool one is the one who innovates_

Yes, but the cool one is not usually the most successful business. If anything, Apple's learned that over its history. For the longest time it innovated great cool things that Microsoft would copy and sell it better while after the innovation phase, Apple would crumble. Since the iPod things have been looking up but geez, Apple has a longtime to go before it can compare itself to Microsoft.

Talking about innovation, don't even get me going about Apple's treatment of developers versus Microsoft's. Hint: innovation is a lot more than building cool technology in your secret lab.

<comment><USER7> "but geez, Apple has a longtime to go before it can compare itself to Microsoft."

According to Google Finance, in the last available quarterly results for each company Microsoft had about $13B revenue with $3B net income, Apple had about $8.3B revenue with $1.3B net income. And Apple has been growing faster (Microsoft's income went down year over year last quarter, for the first time in their history I believe). So, yes, I think you can compare them. Microsoft is still bigger with more profits, but with Apple growing faster you can make a case it is the better stock to own.

</comment></comment></comment><comment><USER8> [Disclaimer: I work at Microsoft but on cloud stuff not on anything Mac vs Windows related. This is not officially endorsed by Microsoft, just my personal opinion, etc, etc]

One small clarification.The 'rounding error' he was talking about was the _change_ in share. I know this since I was a few feet away doing manning a booth for my team :)

[http://www.microsoft.com/msft/speech/FY09/BallmerFAM2009.msp...](http://www.microsoft.com/msft/speech/FY09/BallmerFAM2009.mspx) has the entire speech. Grep the page for the quote - it appears deep in and is just a couple of lines.

<comment><USER9> This is not a "small" clarification. The headline is completely misleading - thank you for calling this out.

</comment></comment><comment><USER10> Yet again, Ballmer is either mad about something or saying something inflammatory. Why not just save yourself the frustration of arguing and ignore him altogether?

<comment><USER11> For some reason, Ballmer's statements remind me of Sarah Palin's statements

<comment><USER12> To be fair, he speaks in english sentences ((with the occasional chant), not Palin's constant _word salad_

<comment><USER7> Not word salad, but brilliant free verse poetry.

<http://mashable.com/2009/07/29/shatner-palin-conan/>

</comment></comment></comment></comment><comment><USER13> I think it is easy to think this way if you don't operate in many circles. Around MS and with Ballmer's associates, I am sure that there are very few Apple products around. But go into any Starbucks in NYC and you'll probably see more Mac's than PC's.

<comment><USER14> Exactly. Ballmer obviously hasn't been on a college campus in the past few years. I personally saw the percentage of Mac laptops go from ~5% to ~40% from 2005 to 2008 in my classes. The ratio goes even higher if you go to any scientific/technical conference.

<comment><USER15> You say that like it is his job to speak the truth and accurately describe the world.

</comment></comment></comment><comment><USER16> Microsoft paint Apple as expensive, elitist and irrelevant. Apple paint Microsoft as unfashionable, unoriginal, and unreliable.

This has been going on for years, this isn't news. Who cares?

</comment><comment><USER17> Microsoft missed revenue estimates by a billion dollars in the fourth quarter. I guess that's a rounding error for them too.

<comment><USER6> Anyone know how historically significant that billion dollar figure is? Meaning, how is that relative to other tech companies missing their estimates in the recession?

<comment><USER18> Significant in regards to what?

At this point the recession is a fairly known quantity and should be factored in to estimates - its not a very solid excuse any more.

Google and Apple topped estimates for the quarter I believe

<comment><USER6> _Google and Apple topped estimates for the quarter I believe_

Cool. That's exactly what I wanted to know.

</comment></comment></comment></comment><comment><USER19> Summary: The infidels are falling at the gates of our operating system.

</comment><comment><USER20> Microsoft needs a strong Apple so that they don't get buggered by those pesky anti-monopoly fees

</comment><comment><USER21> Since January 2000 when he became CEO of M$, the stock went from $60 to $20 the first year, then flatlined for the next decade.

Ballmer is the only problem in M$, the worst CEO ever, and I will be very happy the day he steps down.

<comment><USER21> Btw, AAPL went from $80 to $160 in just a quarter.

I guess Ballmer is banging his head against a monitor showing a Win7 screensaver for missing that opportunity to double his wealth.</comment></comment>


How we Spent the Kickstarter Money, where we are now, and what's next for Ghost - <AUTHOR> http://blog.ghost.org/year-2/

<comment><USER2> As a developer, the costs towards developing ghost seems high: 3 employees and $70,907.89 on subcontracting. Is my mindset wrong?

I like ghost.org, it's clean and fast. OTOH it's not complicated or revolutionary, is it? I followed ghost for a while and was not impressed by the pace of development. New features took ages.

Anyone know why the development is so (seemingly) slow? Bureaucracy? Slow decision making?

</comment><comment><USER3> In an age where everybody talks about cloud infrastructure, I find it a very interesting decision to spend $30k on servers up front.

Apart from reducing operating costs, I never thought about servers as assets. Essentially, using things like AWS for operations makes the money go away as soon as it's spent. That's a very real risk if you're striving for a sustainable business that doesn't run on ads and you don't yet know where this is going.

<comment><USER2> Yeah, and I'm not disagreeing with you, cloud can be _really expensive_. But with cloud they could have started small and cheap, and scaled up when needed.

</comment></comment><comment><USER4> Wow, 10% of funding money towards the domain. Am I being a prude for thinking that's a lot?

<comment><USER2> Paraphrasing someone: _In business there 's no "cheap" or "expensive". It either pays off or it doesn't._

Will this domain increase sales enough to make back the 33k? I don't know, but I wouldn't bet on it :)

</comment></comment><comment><USER5> Could someone comment on why the monthly hosting is $3,042.68? Is that the cost of running their servers?</comment>


AI generates ultra-realistic fashion models from head to toe - <AUTHOR> https://thenextweb.com/artificial-intelligence/2019/05/01/this-ai-generates-ultra-realistic-fashion-models-from-head-to-toe/ <comment><USER2> This is cool but I am not sure how they are going to make these models wear new line of clothes without which this is pretty much useless. Am I missing something here?

<comment><USER3> As with most AI stuff done today, this is mostly academic, and not really intended to produce a commercially viable product.

</comment></comment><comment><USER4> Link to release (no paper or implementation details): [https://datagrid.co.jp/all/release/386/](https://datagrid.co.jp/all/release/386/)

I find GAN gifs like the one in the release oddly mesmerizing. I watched it for a bit looking for funny anatomy (differently shaped hands, unusual feet).

They can generate the body, is it simple enough now to superimpose apparel on to the generated fashion models?</comment>


Apple Doesn't Want My Filthy Disabled Money - <AUTHOR> http://deborah.dreamwidth.org/63403.html <comment><USER2> If you are rude or demanding you will be treated accordingly, and this post has a very demanding tone. Maybe I'm cold but I don't think being disabled is a pass to treat other people in a condescending or rude manner. It sounds like a frustrating ordeal and I am sympathetic but can't help but think the other side of this story may be different.

You only need a credit check if you are getting a phone on a contract. Perhaps the carrier you want a contract with has some policy about credit checks or driver's licenses. Did you try going through the carrier directly?

It sounds like you've given up or are at least very soured at this point (I don't blame you) but it might be worth cooling down and trying again via the carrier. Here in Canada you can get a credit check done with an existing credit card number and your SIN (social insurance #). Politely suggesting, to Apple or a carrier, that a credit card and SSN should be enough for a credit check could be worth a shot.

</comment><comment><USER3> Alternate Headline: Disabled woman outraged that things aren't just handed to her because she is disabled, actually has to do stuff.

For the record, I'm Canadian and I have never once had to proffer ID to purchase an iOS device, and I've owned an iPhone, iPod touch and iPad. Sounds like a requirement of whatever carrier you are trying to get the phone from because you don't have much of a credit history or an existing relationship with a carrier. Not exactly Apple's fault.

I'll give her the accessibility thing, but when is that ever the case? I mean with the exception of possibly wheelchairs and items that are designed for disabled people, what company has reps that can properly explain all the accessibility features in a given product? Accessibility in iOS and OS X is documented much better online.

How about this: just buy the damn thing from Best Buy, try out the accessibility features, and if you feel they aren't adequate, return it within 30 days. You'll learn everything you need to know, and you'll give some kid an open box iPod touch to purchase at a discount. Everyone wins.

> I understand that Apple is trying to position the iPhone as the phone that's > great for people with disabilities (which to Apple means "blind people").

Custom vibrations are for blind people? Screen flashes/LED flashes for alerts? Mono audio? Custom gestures and TouchAssist? I don't know why she found it necessary to throw in that little condescending comment at the end.

Apple bakes in thousands of dollars (literally, what it costs to add these features in to Windows 7 or XP) of accessibility features into iOS and OS X, for people with all sorts of disabilities. It's really insulting to characterize that as just some token features for the blind.

</comment><comment><USER4> _Discover on my frustrated way out the store that "expert in accessibility" apparently meant "took the accessibility training"._

What more do you expect from a retail store? They're going to have someone who went through a training course on the devices they sell.

They're not going to have someone on staff who has studied and published manuscripts on device accessibility, just like they're not going to have a baseband firmware engineer there on staff to tell customers what airplane mode means.

</comment><comment><USER5> I call BS. I just went through the process of ordering an iPhone from the Apple store. No drivers license required, only an SSN, and that is SOP for any credit check. If you order an unlocked phone and pay full freight you don't even need an SSN.

<comment><USER3> Clearly. As anyone who has ever purchased any iOS device besides an iPhone locked to a carrier knows, Apple couldn't care less about your drivers license number. That's something the carrier you picked wants so that they can run a credit check.

</comment></comment><comment><USER6> One thing that seems to be missing from this page, the "trying to buy an android phone" page, and the about me page, is what the actual disability of the author is. I'd be interested in knowing what they can't do - it's worth taking it into account when designing your own UIs.

It's very hard for someone who doesn't suffer from a disability to imagine how someone with a disability will interface with their product. Screen readers/accessibility for the blind is relatively easy - write some software that reads the screen and presents what it sees in an auditory menu. Imagining how other disabilities affect the user, and then working around that, is hard. Given the extensive range of disabilities in the world, it's impossible to take into account everything. A device has to be designed with the most common disabilities in mind.

</comment><comment><USER7> Whiny, rude, disrespectful, also not smart enough to proffer alternative ID. Her problem isn't disability, its stupidity.

<comment><USER8> > Whiny, rude, disrespectful, also _did not choose_ to proffer alternative ID.

Her problem may be rudeness. But rudeness is not stupidity. Confusing the two is either stupid or rude (depending on the reason for the confusion).

</comment></comment><comment><USER9> Every time someone or some system lazily says "driver's license", substitute "state-issued photo ID" in your head. You can get one from your local DMV office for a few dollars and a little time. It and its number will work fine in any context (other than actually driving) in which a driver's license may be called for.

<comment><USER10> In that case why specifically say "driver's license"? And when she complained that she did not have one surely it would have been easy for the person on the phone to correct her and state that any valid ID would be fine rather than insist on a driver's license, I'm sure it's not the first time this has come up.

In the UK people will usually say "Passport or Drivers License" (or if your in a bar just 'ID?') since almost everybody will have at least one of the two.

Pherhaps this is because less people in the US have a passport?

<comment><USER3> > In that case why specifically say "driver's license"?

Because more people are confused by government ID thinking it means passport, military ID or something like that, than are confused by thinking Drivers License means only a drivers license and nothing else. They may also try to offer items that don't count, such as a photo-ID health card.

<comment><USER10> My point here was more that once she mentioned that she did not have a drivers license , I would have assumed a good customer service person might suggest some specific alternatives at that point to avoid confusion. I'm assuming a passport or military ID would have been adequate.

It just seems to me surprising to declare someone as stupid for assuming that 'drivers license' literaly meant 'drivers license' as opposed to 'drivers license or equivilent' especially when the customer service person did not help them understand, lots of people end up with various forms of ID from passports to membership cards, it doesn't seem that surprising that someone might not know exactly which forms are equivilent by memory.

Reminds me of confusion in the early 90s with some software requirements specifying "IBM PC" when really meaning "IBM Compatible PC".

<comment><USER9> > _I'm assuming a passport or military ID would have been adequate._

I really can't emphasize enough the degree to which the US revolves around state-issued photo IDs, whether in the form of a driver's license or a simple ID card. This assumption is baked into everything.

Take a look at this page: [http://www.travel.state.gov/passport/ppi/stats/stats_890.htm...](http://www.travel.state.gov/passport/ppi/stats/stats_890.html)

In 2000, there were fewer than 50 million valid US passports. That's less than 18% of the population at the time, and a chunk of those passports were probably not truly valid -- US passports are good for 10 years, and nobody bothers to tell the State Department when somebody dies.

10 years earlier, in 1990, there were only about 11 million passports, less than 4% of the US population at the time.

This is because nobody needed one. Few Americans leave the US to go anywhere other than Canada or Mexico. Until 2009, land-based travel to Canada and Mexico did _not_ require a passport, and until 2007, air travel to Canada and Mexico didn't, either.

This isn't Europe, you can't drive across multiple international borders on a day trip. It's possible to traverse over 4,400km in a straight line (on land) without leaving the 48 contiguous US states, and over 6,600km in a straight line (on land) going from northwestern Canada to southern Mexico, with only the US in between.

In contrast, by the time it became common for Americans to need an ID card at all, drivers licenses were also becoming common. Win-win.</comment></comment></comment></comment></comment>


Show HN: 15-question programming quiz with answers - <AUTHOR> https://quiz.triplebyte.com/ <comment><USER2> This is very python specific. While I got a 15/15 and can easily answer these, the reason for that lies with the fact that I am very fluent in Python, had I not been I would have not gotten at least 6-8 of these wrong.

This isn't a generalist quiz, nor is it a good baseline for interviewing candidates for the hiring process, this wouldn't tell me anything about the application of their skillset.

<comment> squeaky-clean I took a quiz at the Facebook booth at PyCon this past weekend. It was Python specific, but had a few annoying gotchas. There was one question in there twice, but with 2 different values for the input (which is what tipped me off that it was a trick).

It basically relied on this fact...

        x = 256
        x is 256  # True

        y = 257
        y is 257  # False

Which for one, you shouldn't use `is` to compare integers in Python. I wish I could have just written that as my answer.

Secondly, you need to be aware the CPython uses an integer cache which causes the answers to be different. You'll actually get different answers based on whether you run it as a file, enter it line-by-line into the interpreter, or use a different implementation such as PyPy.

[https://stackoverflow.com/questions/15171695/whats-with- the-...](https://stackoverflow.com/questions/15171695/whats-with-the-integer- cache-inside-python)

There wasn't any point to the quiz, so it's okay that they put in silly questions like that. But it's clearly there just to try and trick you, and not quiz you on anything relevant. Most of the other questions were tricks of the sort, or or Python 3 specific gotcha's.

<comment><USER3> As a Python beginner I'm completely flabbergasted... How can this be? And why can't I use "is" to compare integers? This is insane. The quoted stackoverflow is not very readable to me...

By the way y == 257 does work.

<comment><USER4> "is" is for asking whether two objects are the same exact object in memory. "==" is for asking whether two objects are logically equal, ie, that they represent the same value. As an example:

        >>> x = [1,2,3]
        >>> y = [1,2,3]
        >>> x == y
        True        # two lists with the same values; equal
        >>> x is y
        False       # two different lists; doesn't matter that they contain the same values
        >>> z = x
        >>> z is x
        True        # same list object in memory

Because here you want to know if the two integers are logically equal, not if they're necessarily the same object in memory, you want "==" and not "is". Due to an optimisation, "is" might work for small integers, depending on implementation, but the takeaway is not to use "is" for value comparisons; that's what "==" is for.

<comment><USER5> To expand on this, python creates some values as singletons to save memory/speed things up because they are used so often. The most well known examples are True/False/None. That's why you can always do None is None, because all None are the same None in memory. Python takes this a step further by creating lower integer singletons. So any integer from 0-256 (not sure about negatives) will always be the same number in memory. Above 256 python will start actually allocating memory for integers, so two of the same number won't be at the same memory address, and there for won't be comparable by 'is'.

<comment><USER6> _0-256 not sure about negatives_

-5 to 256 (inclusive) [[https://github.com/python/cpython/blob/master/Objects/longob...](https://github.com/python/cpython/blob/master/Objects/longobject.c#L18)]

</comment></comment></comment></comment></comment></comment><comment><USER7> Not entirely applicable to this particular quiz (most of the questions were relatively simple until the final few), but the interview questions like the ones that Hired and Triplebyte focus on honestly make me feel like an imposter.

I've been a software developer for over 4 years but I don't have a formal CS education. I've gone through CLRS along with MIT's open-courseware--but I rarely use any of that _directly_ in the workplace and so have forgotten a lot of it. And I think I'm a pretty good software developer, yet in the past when I've tried to get into Hired or Triplebyte, I always leave feeling like I don't belong in this profession because I can't tell you the big-O complexity of DFS off the top of my head, much less write the algorithm on a scratch pad.

I've been doing technical interviews for a few weeks now (I was recently laid off) and I'm honestly just a little tired of the brain teasers and non- applicable algo questions--and more often than not, the interviewers flexing their "knowledge" muscles.

Case in point: I'm in final stages with multiple companies for a Rails position, yet only _one_ of those had even mentioned Rails in the technical interviews--the others decided to quiz my CS knowledge and one of them even quizzed my FP knowledge (for a Ruby position…). I don't understand it.

<comment><AUTHOR> Hello Ezekg,

I am sorry that our process makes you feel bad :( The simple truth is that there are a lot of different ways to be a skilled programmer. One ways is being really good at CS (and to people who want skills in CS, talking about DFS is a reasonable low-bar question). However, another way is writing great, well-structured rails code. We work with people all the time who don't have CS backgrounds (we help them get jobs at companies that don't care about CS). The intent of our process is to measure both CS and practical skills (we actually break it down on more axes, but you get the idea).

This does mean that if you go through our process, you will be asked CS questions. But you'll also be asked to code. And not knowing the CS questions is not an obstacle to passing.

<comment><USER8> Do you truly believe that being really good at CS will magically make you a skilled programmer?

Are they not different skill sets? One is a practical skill, the other an academic one.

I've met "programmers" who had depth of theoretical knowledge but couldn't code their way out of a paper bag.

I've watched online lectures where Doctors of Computer Science lecture about OO but clearly have no understanding of what works and what doesn't.

I will concede that being good at CS will give programmers an advantage in solving problems in a subset of domains.

I suspect I could add the word small to advantage and subset and that statement would still be true.

<comment><USER9> > Are they not different skill sets? One is a practical skill, the other an > academic one.

I'd like to see you design and program a P2P networked program without any CS knowledge, like Kazaa or Bit Torrent, that actually works as well as they do.

> I've met "programmers" who had depth of theoretical knowledge but couldn't > code their way out of a paper bag.

That's true for lots of fields, but it's not hard to see that that doesn't mean theoretical knowledge isn't useful.

<comment><USER10> It's a lot, lot easier to read papers on the algorithms needed by, and understand the specific requirements of, a particular project than it is to learn the entirety of software development outside algorithms ad hoc.

Honestly, even though I do know a fair bit about the Bit Torrent algorithms, I _wouldn 't trust that knowledge_ since it's most likely out of date or incomplete. It's deserving of research for anyone, even people who 'know it already'.

That's why I don't understand these narrow algorithmic tests - very, very seldom is a priori knowledge about DFS vs BFS going to be something that makes or breaks a project.

It would be akin to testing civil engineers on the memorization of precise ratios of the ingredients of concrete in current usage, instead of on the broad applicability of particular materials to particular purposes.

<comment><USER11> Yeah, I'd love to know how they test civil engineers in interviews.

</comment></comment></comment></comment></comment></comment><comment><USER12> This was an interesting quiz, but perhaps not the way the authors intended. The second half was straightforward first-year computer science, but the first half challenged me to speculate about the syntax of a novel scripting language.

<comment><USER13> Agreed. I've been a professional developer for nearly 20 years. I've shipped kernel C, windows C++, java,python, ruby, clojure to production, but the last time I wrote python was nearly a decade ago. Since then, I've been firmly in the Clojure community, with no intention of leaving.

I know I'm a good programmer, and I got nearly every python-specific question wrong. I understand closures and call-by-reference tyvm, but I don't remember or care about the quirks of python.

Triplebyte in particular seems to not care about the difference between "good at programming" and "good at programming in python". The skillset needed for C, python, clojure and JS are wildly different. They do a disservice to their users by pretending otherwise.

<comment><AUTHOR> For what it's worth, we run our interviews in the language of the engineer's choosing (including clojure), and get people jobs at Clojure and Haskel and C++ companies. We went with Python for this (toy) quiz because it's the most common language we see among applicants. I tried to add comments to explain anything python specific, and make the question about the underlying logic. But it seems it's still easier for Python folks.

<comment><USER14> Sorry, not buying it.

I caught 3 "Whoops sorry you missed a weird bug in a specific programming language that you weren't explicitly being tested on". Sure, if I was doing a Python3 quiz, I'd expect those. But this wasn't what the quiz claimed to be.

Turns out, the "fill in the blank" code was easy, got all of them. Along with all the 1st year theory questions.

<comment><USER15> I agree. Coming in with a LOT of experience in JS and a good damn chunk in c++, but none in python... this is really bad test.

You ask dev about aspects of the language that are essentially memorization:

Does matrix.append(x) in python append by reference or by value? Both are equally likely without knowing anything about the language.

the question is also pretty easy to answer correct IF I know that, but I have no reason to know that. You're not testing skill in any sense of the word. You're purely testing familiarity with this specific language (and worse, this language's standard library)

That's bad.

<comment><USER4> > Does matrix.append(x) in python append by reference or by value? Both are > equally likely without knowing anything about the language.

I don't think they're equally likely. The question would have the same answer in Javascript, Ruby, Lisp, Perl 6, Java, and many other languages. You can see from the code samples that Python is a high level, dynamic, imperative language, so I think it's fair to assume you would expect that behaviour from it. There's a bit of guessing, but you can make an educated guess.

<comment><USER15> Way late, but your response sort of proves the point. You're having to argue about what I can infer about the language.

What JS/Ruby/Lisp/Perl/Java do is irrelevant. Hey, C/Go/D/C++ would all be more likely to append by value, but neither of us care a whit because it's asking about Python, which I know nothing about.

So (and this is really hard) try to forget that you've got experience with the language, and approach it as a random pseudo language: this question has no clear answer, because it depends on the memorized implementation details of the standard library of a language...

That's bad.

\---

Finally: JS doesn't have matrix as a base type (boolean/number/string/null/undefined/symbol is it, baby), so for this same question, I'd strongly argue that you're simply wrong about bucketing JS with those other languages. Again, for JS the question would revolve around the implementation details of the matrix object and its prototype. Trust me, I can write a useful matrix implementation that appends by value in JS.

<comment><USER4> > What JS/Ruby/Lisp/Perl/Java do is irrelevant. Hey, C/Go/D/C++ would all be > more likely to append by value, but neither of us care a whit because it's > asking about Python, which I know nothing about.

I guess my point was that you should be able to infer that Python would be more likely to behave like JS/Ruby/Lisp/Perl/Java than C/Go/D/C++. If you know or can tell by looking at it that it's much more in the first camp then the second, then you should be able to guess. You're probably right that I overstated how easy that is to tell just from the syntax if you don't know anything at all about Python, but it's also pretty short of memorizing implementation details.

> Finally: JS doesn't have matrix as a base type > (boolean/number/string/null/undefined/symbol is it, baby), so for this same > question, I'd strongly argue that you're simply wrong about bucketing JS > with those other languages. Again, for JS the question would revolve around > the implementation details of the matrix object and its prototype.

The 'matrix' in the question wasn't a special matrix type, it was just a list of lists. Word-for-word translated into Javascript it would look like:

        let matrix = []
        let row = [0, 0]
        for (let i = 0; i < 2; ++i) matrix.push(row)
        matrix[1][1] = 1

<comment><USER15> But that LITERALLY is memorizing implementation details.

Here are the rules for JS, which I happen to know, because I use it often:

1\. Javascript is always pass by value, but when a variable refers to an object (including arrays), the "value" is a reference to the object.

2\. Changing the value of a variable never changes the underlying primitive or object, it just points the variable to a new primitive or object.

3\. Changing a property of an object referenced by a variable does change the underlying object.

Those are not trivial "just infer it" details. That's highly language specific, and absolutely unrelated to the skills the test claims to be evaluating.

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER16> The wording on question 9 (the regex one) is a little unclear: both b[l]. _e and ([^b]_ b[^b]*){3} will match blabber but not babel. Presumably the intended meaning is that the entire string must be matched, but the question does not make this explicit.

<comment><AUTHOR> Just added anchors to the expressions. Thanks for pointing this out!

</comment></comment><comment><USER17> Cute quiz. Question 9 is incorrect, however – or at least poorly worded. It asks about regex matches and only considers the last one to match, while the second one also matches, albeit incompletely. The last regex is the only one that matches the _entire_ input string, but that's not usually how regexes work – e.g. in Perl or Ruby. This verbiage seems to be specific to Python, which uses `re.match(str)` to mean "match the entire string" as compared to `re.search(str)` which means "search for any matching substring". Arguably a decent distinction, but very Python-specific.

[Update: this is now fixed in the quiz.]

<comment><USER18> The given regular expression does not match `blabber`, it matches `blabbe` (minus the `r`).

I got that one wrong as well. The question should have been "which regular expression FULLY MATCHES X and not Y"

<comment><USER19> Nope:

In [3]: re.search("b[l].*e", "blabber")

Out[3]: <_sre.SRE_Match at 0x7f2db79ed030>

"Matches" means "matches". If they wanted "fully matches", they should have specified "^$". That's why anchors exist.

<comment><USER18> Yes, I agree. I just explained where it went wrong and that "Match" can mean multiple things. It matches `blabber`, but the match result is `blabbe`.

</comment></comment></comment></comment><comment><USER20> Got a few easy ones that were about language implementation details wrong because I've never done Python. Only realised it was Python and not some kind of beautiful pseudocode when I kept getting answers wrong

</comment><comment><AUTHOR> We've been using a quiz as part of our hiring process (at Triplebyte) for the last two years. However, a lot of people do our quiz for fun. So we decided to create a version optimized for this (and hopefully a little education). The problems come from the most common mistakes / misunderstandings we see when giving interviews, and ramp up in difficulty. We put a lot of effort into writing interesting answers.

Let me know what you think!

<comment><USER21> If you're going to pick one language for the quiz (python) it seems a little unfair to non-python developers to focus the questions on idiosyncrasies of python. Whereas if all questions were of the more general algorithm variety (like you see toward the end), non-python developers could infer the answer without any esoteric python knowledge.

<comment><AUTHOR> We talked a bunch about this. Python and JS are the two most common languages we see on our site, and Python has slightly more compact syntax, which works well in the questions. The idea, however, was not to require any python- specific knowledge. Which question do you think is looking at syntax?

<comment><USER22> Hey, not the GP, but just glancing through the quiz - Question 3 focuses on the fact that Python passes things by reference to functions. This is definitely specific to the two languages you guys use (as is your prerogative), but if you're expanding this for others, you should definitely explain that these focus on the JS and Python languages.

<comment><AUTHOR> Good point. I _think_ that objects are passed by reference in a high enough % of language in common use (PHP and C++ are the two exceptions I can think of) that this is a fair question. But if enough people think it's bad, we'll remove it.

<comment><USER23> You got me on that too. A high enough % of the languages pass stuff by value (C/C++), copy on assignment (C++, D, I'm sure there are more), or do not have the concept of references or changes to start with (Prolog, Haskell).

Anyway, if you want to bias it into Python, go for it. It's a fun quiz.

<comment><USER24> Copy on assignment was what got me, and I didn't feel terribly bad for missing it. No harm done though, seeing as nothing was riding on the quiz.

</comment></comment></comment></comment></comment></comment></comment><comment><USER25> "True programming generalists are rare. This quiz covers basic programming, web development, algorithms and low-level systems. The questions start easy, but get harder fast. Only 3% of programmers can get all the way through. Can you?"

This test doesn't cover any of that, makes me worry if they think it does.

it's more :-

do you understand python syntax?

do you understand a few algorithms?

do you understand a few security issues?

not sure how you'd go from this test to working out if a person is a programming generalist. In fact I'd be worried that someone passing this test would be fresh graduated from college where they used python.

</comment><comment><USER26> imo, this is the right way to do interviewing. I'm currently interviewing with several companies, and one thing that stresses me out is the expectation that

1\. candidate must discover algorithm to solve unseen problem

2\. candidate must code up algorithm discovered in #1

3\. candidate's code must work

4\. steps 1,2,3 must happen under 1 hour

I think this is a bit too much, and completely misrepresents the current working state of professional programmers.

If I am asked to do #1, I usually do a literature survey - I read papers before rolling my own algo from scratch. 99% of the time, there's a good enough algo already out there.

If #2 - ok.

If #3 - not ok. Typically you need a debugger & 1-2 passes before you get it right.

If #4 - definitely not ok. Step 1 itself can take you forever, and you don't even know if its correct. Then you've got #2,#3...adding time constraint to this mix is crazy.

So yeah, this quiz has two highlights: showing a block of code & asking to fill in the blanks - much better, highly recommended. Also, looking at a block of code & figuring out what it does - definitely part of programmer's everyday work. I hope more companies adapt this technique.

<comment><USER27> A live example, from Uptake (Chicago): [https://twitter.com/ch1gg1ns/status/867043938779222016](https://twitter.com/ch1gg1ns/status/867043938779222016)

<comment><USER28> i thought those were just for free tacos?

<comment><USER27> Hard to tell if you're joking or serious. (Either way: "Why not both?") Here is the official tweet:

[https://twitter.com/Uptake/status/867105586336456705](https://twitter.com/Uptake/status/867105586336456705)

</comment></comment></comment></comment><comment><USER29> I'm sorry but I just can't take a quiz/website/company seriously that assesses programmer ability, and yet they put the freaking answer key in Local Storage. Seriously, quizState? I got a 100%. ;)

{"questions":[{"name":"max_function","answerIndex":2,"question":"Fill in the missing line of code:","code": ...

<comment><AUTHOR> This quiz is just supposed to be fun :) We opted for speed over security, on the idea that anyone who cared enough to pull out the answers deserves a 100!

<comment><USER29> Gotcha. Just know it could give a bad first impression about the security of other assessments and competence of the team. While I find these questions to be quite flawed for the stated purpose, I really do wish you and others in this space luck!

</comment></comment></comment><comment><USER30> This quiz is not a programming quiz but a Python quiz.

</comment><comment><USER31> If you only fail the regex, unicode, and hash security question you ought to get a badge of innocence you can print and cut out

</comment><comment><USER32> 15/15\. Some questions felt like they were trying to trap me. Or maybe I'm just tired, I've had a long day of work.

Congratulations on making this! It's less fun for me than algorithm puzzles, but I can see it working well for hiring purposes. I'd love to see some software company use it and report the results.

</comment><comment><USER13> The quiz wouldn't pass security review, FWIW. The answers are shipped with the javascript, and validation is done client side, so they're just an 'inspect element' away.

<comment><USER33> I'd cap scores at 5/15 for applicants who automate their responses.

I especially enjoyed the post-response explanation of the time and memory bounds of iterative deepening.

It would be a shame to miss the opportunity to test one's skills on such a well put together experience.

<comment><USER13> In a quiz with multiple security questions, I'd give bonus points to an applicant who found security problems.

<comment><USER33> Good point.

</comment></comment></comment></comment><comment><USER34> On the last two questions, I'm curious why the ability to memorise which algorithm to use is a useful skill for a professional software engineer, let alone a useful interview question. Isn't the best answer "I would look up the best algorithm by ..."?

<comment><AUTHOR> If you understand the graph traversal algorithms in question, there's nothing to memorize. You can just think through the problems. Is it important to understand graph traversal algos? I don't think it is for everyone. But a lot of people who like CS find it interesting. And if you work on, say, a web crawler or a game AI, then you'll need them.

<comment><USER34> The last two questions are little more than "what is the name of the algorithm I should use to solve this problem?".

This doesn't test understanding in any way. How is it useful to determine whether someone can work on the examples you give, let alone the average software engineering job?

<comment><AUTHOR> The goal of this quiz is to be a little challenging and fun and maybe educational. It's not to judge whether someone can do a software engineering job!

The answers to the graph problems are indeed fairly straight forward. But asking about why one might use a BST in place of a sorted list prompts interesting discussion. And going into Dijkstra's vs A* and iterative deepening depth first search is (I think) pretty interesting!

</comment></comment></comment></comment><comment><USER35> Concerning 12: timing attacks are not a relevant threat for hash function computations. See [https://github.com/codahale/bcrypt- ruby/pull/43#issuecomment...](https://github.com/codahale/bcrypt- ruby/pull/43#issuecomment-15797932). Supported by our own tptacek here [https://twitter.com/tqbf/status/866115075110825984](https://twitter.com/tqbf/status/866115075110825984)

<comment><USER36> Whoah. Careful! Timing attacks aren't relevant _to password hashes_ , because the user doesn't control the hash, only the input to the hash, whose output is unpredictable. But cases like the TripleByte quiz, in which a user is directly submitting a hash to check (typically: an HMAC on a message) are totally relevant; in fact, they're the most common kind of legitimate timing attack.

<comment><USER35> Yes, sorry, my comment is sloppily phrased. I should have been specific. And then I may have realized I was wrong, because it wasn't about password hashes.

(It seems that tweet and the link were fresh in my memory: I automatically interpreted the question as being about password hashes, although the code actually does not imply that at all. And the linked thread is clear about the difference between password hashes and other hashes, but it seems the 'simple' message was more available to me than the deeper truth)

</comment></comment></comment><comment><USER37> Question for ammon : What's the time frame for expanding to remote jobs?

Question for other HN readers : How much did you score on the quiz? I scored 10/15 and it shows that I'm better than 50% of engineers i.e I'm somewhere right in the middle. Not very encouraging, but if I brushed up on the graph algorithms, I could have done better.

<comment><AUTHOR> The truth is that there's just a lot less demand for remote engineers, and among companies that do hire remote, it's usually for very specialized roles. (There are obviously exceptions.) Looking at our stats, about 5% of the companies we work with are interested in remote engineers. We're not going to expand to remote jobs until we have that number up to a point where we can provide a good experince. I don't have a time-frame, but not in the next 3 months (over the next 3 months we're focused on expanding to other cities)

<comment><USER38> Follow up question : In your faq, you mentioned that you do not interview candidates who need visa sponsorship. Any plans to change that part?

<comment><AUTHOR> Unfortunately probably not :( I would love to, but the jobs are just not there. H1Bs are just too hard to get.

What I do hope to do is expand out of the US, and get around the issue that way.

</comment></comment></comment></comment><comment><USER39> Seems extremely language-semantics specific.

</comment><comment><USER40> In the 3rd question, if you give the wrong answer, it says Java is pass-by- reference as well, though IIRC it is always pass-by-value. Also JS passes primitives by val as well if I'm not mistaken.

<comment><AUTHOR> Well, objects in Java are only accessible via references. So the result is behavior identical to Python and JS (primitives are passed by value, objects are passed by reference)

</comment></comment><comment><USER41> > claims this is a generalist programming quiz

> first half focuses entirely on weird Python quirks.

Wew.

On the plus side, I still somehow managed to get 9 out of 15 right, which apparently puts me above 50% of all programmers.

</comment><comment><USER42> Mildly annoyed at myself for getting question 8 wrong: the true answer was what I thought that code would be doing, but the bytes didn't look like valid UTF-8. I had a brainfart and thought that continuation characters were always valid ASCII, so a string containing only characters >= 0x80 wouldn't be valid.

The (much saner) reality is that continuation characters are never valid ASCII.

10 I admit I got through elimination: three answers were obviously wrong, one could have gone either way.

</comment><comment><USER43> I'm not very familiar with Python but I liked this quiz. I got two wrong (13/15), once for a stupid mistake and once for not knowing the algorithms well enough. In a couple cases I didn't know the right answer, but was able to determine that all other answers were wrong, which worked.

Overall, I think this is a good level of knowledge that isn't too nitpicky but has enough meat to really test if someone knows something.

</comment><comment><USER44> This was fun. It's been a while since I took a multiple-choice test, and it called to mind the Cluss Test <[https://www.recompile.se/~teddy/cluss- test>](https://www.recompile.se/~teddy/cluss-test>). This test was fairly cluss-resistant, as I don't recall making any inferences from the test's format or language rather than its content.

</comment><comment><USER45> 14/15 - I missed the one where Python doesn't copy the row before appending it to the matrix.

</comment><comment><USER46> This is a quiz about python gotchas.

</comment><comment><USER47> I first found out about Ammon and Triplebyte through this YC video interview. I thought it was interesting, so I'll share:

[https://www.youtube.com/watch?v=haxZDcTWdOo](https://www.youtube.com/watch?v=haxZDcTWdOo)

</comment><comment><USER48> Too many language specific aspects.

</comment><comment><USER49> Reminded me why I dislike Python...

</comment><comment><USER50> Where do the percentiles come from that are displayed at the end of the quiz? Are these based on a previous test sample group or are they being updated as more people take the quiz?

</comment><comment><USER51> Is there a JS equivalent of something like this out there?

<comment><AUTHOR> If people like this, we'll be creating more version (in different languages, and drilling into different areas)

<comment><USER52> Judging by other people's comments, this would be a good quiz if it was written in their favorite language.

The quiz doesn't seem too hard to port (ha, I've heard "it won't be hard to write" before). I think that a good approach might be to let the user see the code in multiple languages via tabs or an interactive select element, like the MSDN docs do.

</comment></comment></comment><comment><USER53> What's the deal with the warp searching question? There are both depth and breadth first algorithms that can handle cycles. Bit annoying since the example I had in mind was Djikstra's but it turned out that was classified as a BFS instead of DFS like I thought it was. Finding the shortest path from A to D in 4 steps for example seemed more "depth" to me, but maybe the algorithm as a whole doesn't neatly fit into either.

<comment><USER54> I think you're misunderstanding the point of the question. BFS is guaranteed to find you a shortest path in terms of "# of hops" in an unweighted graph. DFS is not.

</comment></comment><comment><USER55> Is this intended to be taken with access to references and a python interpreter, or closed book?

<comment><AUTHOR> Either way. It's just supposed to be fun / interesting

</comment></comment><comment><USER56> I only got 50 percentile which I thought wasn't bad for not knowing python

</comment><comment><USER57> I would have done better had I known how python does parameter passing...

</comment><comment><USER58> I took the Triplebyte quiz on Facebook and after finishing, they didn't even bother giving the score. It was very outputting, and felt like a trap, asking for an email address instead of giving the score. I won't ever be doing business with them.

<comment><AUTHOR> Ah, you're talking about going through our regular process and looking for a job? In that case, we try to make it clear that what you're doing is applying for a job (and we require an account creation at the beginning of the process).

This quiz posted here is something we created because some people (like you?) are applying to our process just to answer the questions. So we created this version (which does not require an account creation or ask for an email) and totally gives you a score and shows what we think the answers are.

<comment><USER59> I took the 35 question quiz. At the end it told me I passed and I shoul wait for feedback on how to move next but after a day I got an email informing me I failed.

</comment></comment></comment><comment><USER60> I like the idea, but my first reaction was that this is a test of how well you know Python's quirks (like the problems with not deep-copying things).

But then I realised that that's not true. For example, call-by-value and call- by-reference are pretty pervasive across languages: many of those examples would've worked the same in Java, say. It's not familiarity with Python, but rather familiarity with a certain kind of language (which admittedly constitutes the majority of those used in industry ATM) that the test demands, at a time when even Java is getting nice FP-like abstractions and the JavaScript community is cooking up all sorts of ways to bring the benefits of that kind of thinking to their own work (from React/Redux all the way to Ramda and the like).

If you're more used to languages that "get out of the way" by eliding what could very well be termed "implementation details" (e.g. is there any reason[0] to use call-by-reference in the absence of global mutable state given a "sufficiently smart optimizing compiler"?), I'd predict (n = 1) that you'll be more likely to make mistakes.

I would've done far better on this quiz back when I was playing with matplotlib as an eighth- or ninth-grader: apart from the token _map_ implementation, the quiz really favors knowledge of counterintuitive behavior common in "mainstream" imperative languages over an understanding of "composability" that users of modern functional languages are used to. (And no, that doesn't only mean Haskell or "ultra-Haskells" like Idris, but also languages like OCaml, F#, and so on.)

It would be much nicer if the quiz could be less about the candidate coaxing her preferred meaning out of a language implementation and more about testing the meanings a candidate knows how to implement with the help of the language.

[0]: For instance, the standard reaction to things like

        sum (map (\x -> x ** 2) (map (\y -> sin (y * pi / 10)) [0..9]))

is that a single for-loop is better than this for "real-world purposes". That is very false: the Haskell _vector_ package is usually capable of efficiently fusing the code above into exactly what one would've written by hand.

[https://www.schoolofhaskell.com/user/commercial/content/vect...](https://www.schoolofhaskell.com/user/commercial/content/vector)

At the risk of going all peak-HN, these things are more a problem with implicit, nonuniform behavior which well-designed languages solve with abstractions like the Copy trait in Rust or even C++ move semantics.

</comment><comment><USER61> Failed two questions in the first part because I don't understand Python tree syntax and don't know what does it pass by reference and what by value.

Would be great if authors translated it to at least a couple of other languages.

</comment><comment><USER62> Thanks a lot for that short quizz !

</comment><comment><USER63> its a python quiz.

</comment><comment><USER64> Someone please change the title to "15-question python programming quiz". Or python and js? I stopped at the 2nd python "trick" question.

Also, remove the "generalist" reference. Generalist those questions aren't.

<comment><USER65> A bit harsh to make a generalist judgement if you quit after two questions. I don't know any python and still did pretty well.

<comment><USER64> It was their 'generalist' statement that made me quit.

</comment></comment></comment><comment><USER66> Expected to dislike it, but ended up liking it quite a bit.

</comment><comment><USER67> I admire triplebyte's effort and the content they produce. Their narrative is really data-driven common sense: some engineers fit to some companies but not to others. Especially enjoyed: [http://blog.triplebyte.com/who-y-combinator- companies-want](http://blog.triplebyte.com/who-y-combinator-companies-want)

I am a programmer and I run [http://www.coderfit.com](http://www.coderfit.com), a tiny recruiting agency in Zurich / Switzerland (reach out to me via e-mail address in my HN-handle if you look for a tech job in Zurich). Recruiting is really, really hard and I am happy to see platforms like [http://interviewing.io](http://interviewing.io) and [http://triplebyte](http://triplebyte) popping up that give programmers without classic CS background a chance.</comment>


Announcing pkgsrcCon 2015 in Berlin - <AUTHOR> http://blog.netbsd.org/tnf/entry/announcing_pkgsrccon_2015_in_berlin

<comment><USER2> For those who don't know pkgsrc yet: It is a portable framework for building over 14,000 open source software packages. Besides NetBSD pkgsrc is the native package manager on SmartOS and Minix. It is portable across 22 different operating systems including Linux and Mac OS X.

This event will be a weekend of fun around making open-source software work across platforms. I look forward to meeting other pkgsrc enthusiasts there!</comment>


Anti-if: The Missing Patterns - <AUTHOR> http://code.joejag.com/2016/anti-if-the-missing-patterns.html <comment><USER2> I'm disappointed that of all the patterns presented, most of them actually increase the complexity to some extent, and none of them are the use of a lookup table/array. IMHO that is the "real anti-if pattern" here, and it can _immensely_ simplify code. I've taken long, convoluted nested if/else chains with plenty of duplication and turned them into a single array lookup. A bonus is that performance and size often benefit as well, since the code is far less branchy.

[http://www.codeproject.com/Articles/42732/Table-driven- Appro...](http://www.codeproject.com/Articles/42732/Table-driven-Approach)

<comment><USER3> I do this a lot too. Often long chains of if statements are really performing a manual mapping from one set of values to another. Just keep a map and perform a lookup! Easier to read, easier to change, and easier to extend since the mapping is a data structure instead of code.

<comment><USER4> Efficiency-wise I agree, but if I don't care about efficiency then I often prefer an if-chain (or better still, a switch-case).

The point is that the desired mapping is known not just at compile time, but is explicitly known to the programmer. So it is clearer if it right there in the executable code rather than hidden away in some moving part (the mapping data structure).

<comment><USER2> switch-case is often compiled to a table lookup, but if your expressions are constant (at least for the part where the table is being used), the latter is definitely less verbose.

 _So it is clearer if it right there in the executable code rather than hidden away in some moving part (the mapping data structure)._

Following several levels of nested if/else is "clearer" than going to the right array index? I don't know what you mean by "hidden away in some moving part".

<comment><USER4> If you have several levels of nested if-else (as opposed to a linear chain of "if"-"else if"), then you probably need a more complicated table than a linear array.

The moving appart that gets hidden away is the table (or more often, Hack mandictionary) that is stored somewhere in memory. If you are lucky, it is stored statically. It is never defined in quite the same place as the decision that it implements.

</comment></comment></comment></comment></comment><comment><USER5> > Context: You have a method that takes a boolean which alters its behaviour

> Problem: Any time you see this you actually have two methods bundled into > one. That boolean represents an opportunity to name a concept in your code.

This is only true if you're using literal booleans at you call sites. If the booleans are coming from somewhere else, like user input, you just moved your single if statement in the method out to every call site.

> Context: You are calling some other code, but you aren't sure if the happy > path will suceceed.

> Problem: These sort of if statements multiply each time you deal with the > same object or data structure. They have a hidden coupling where 'null' > means someting. Other objects may return other magic values that mean no > result.

Passing a default value works, but in Java 8, returning an Optional is cleaner. And if you wanted a default value, you can still do

        repository.getRecord(123).orElse("Not found");

Edit: Also, the coping strategy link [1] he gave to remove exceptions sounds a lot like restarts in Commons Lisp's condition system.

[1] [https://silkandspinach.net/2014/11/06/on-paperboys- newsagent...](https://silkandspinach.net/2014/11/06/on-paperboys-newsagents- and-exceptions/)

<comment><USER6> Common Lisp to the rescue!

       (defmethod make-sound ((b bear) (loud-p t)))
        ;; bear makes loud sound
         ...)

       (defmethod make-sound ((b bear) (loud-p null))
        ;; bear makes quiet sound
         ...)

If we call (make-sound bear-instance nil), the second method is invoked because loud-p is specialized to the null class, whose only instance is nil. (There is a _type_ nil also, whose domain is the empty set: it has no instance.)

If we call (make-sound bear-instance <any other value>), then the first specialization takes over. It's specialize to T, the grand superclass, so it is a fallback that takes anything. Any value other than nil serves as a Boolean true in Lisp.

It's a magic of Lisp that T stands for "any type" as well as "true". :)

I don't know whether treating Booleans as method parameters like this is good design, but I don't see any immediate down sides.

<comment><USER7> Also known as multiple dispatch, which is supported by many languages: [https://en.wikipedia.org/wiki/Multiple_dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch)

</comment></comment></comment><comment><USER8> I'm afraid the article has left me unconvinced. I'm open to having my mind changed on the matter, though.

The point of passing boolean params instead of named functions is that most of the time there is shared code between the two paths and not literally all the code is enclosed in either the if or the else block. If the author was intending just to restrict to that one specific case where there was no overlap whatsoever, then I guess I would agree but I'm not sure how often that happens.

Polymorphism has some advantages but it's certainly got it's own troubles in terms of understand-ability. The author links to an article which even states "I think that we hate conditionals more than we should. Introducing polymorphism too soon will complicate your code, making it hard to understand and test." It then goes on to give an example where it says polymorphism is actually the right choice, to avoid two switches. I'd say that at least this trivial example would be best handled by some data-driven approach. Look up salaries in a database instead.

The inline statement one can certainly be better in some cases, but the example given is quite poor. What does "foo && bar || baz" mean? Well, now I have to remember the order of operations ... 'or' after 'and' I guess. Surely this is easier to misread than the if statement example, which in my mind closely matches how I think. At least it should be "(foo && bar) || baz". But even then, that only works when the actual return type is boolean and there are no state changes made.

I don't really see how using an Optional type would remove the if(null) checks. It just makes the meaning explicit, which is good but not remedying the original problem.

5 seems nice.

<comment><USER9> > The point of passing boolean params instead of named functions is that most > of the time there is shared code between the two paths and not literally all > the code is enclosed in either the if or the else block

If you have this

        method(bool arg)
        {
          // block A
          if (arg)
          {
            // block B1
          }
          else
          {
            // block B2
          }
          // block C
        }

you can replace it with

        method1()
        {
          A();
          B1();
          C();
        }

        method2()
        {
          A();
          B2();
          C();
        }

where A(), B1(), B2() and C() are new methods that contain the previous blocks. This makes the code clearer, IMO.

<comment><USER10> > _This makes the code clearer, IMO._

Depends on how much state you need to pass between A, B1, B2 and C.

<comment><USER11> It also depends on the semantic value of A, B1, B2 and C. If you cannot express them as senseful steps of your overall algorithm, then you are bound to end up with very confusing method names like calculateFooAndCreateBarAndAlsoInitializeBaz, or (even worse) prepareForFoo.

EDIT: By the way, an anecdote. Years ago, I was working with an offshore developer who was producing huge scripts without any modularization whatsoever. In particular, we told him that a certain 2000-line script needed to be modularized, so he should break out steps into functions etc. He produced a new version containing two functions of 1000 lines each. The first function would prepare everything, then tail-call the second function with 27 arguments, most of them large intermediate data structures.

<comment><USER10> Could have been worse: He could have made 1000 functions two lines each.

</comment></comment></comment></comment></comment><comment><USER12> This recent article seems relevant: [http://www.sandimetz.com/blog/2016/6/9/make-everything- the-s...](http://www.sandimetz.com/blog/2016/6/9/make-everything-the-same)

<comment><USER13> This is actually a better read than the OP. Thank you.

<comment><USER14> I only read bits and pieces of "Practical Object-Oriented Design in Ruby" by Sandi Metz, and the occasional article, but all of it has been surprisingly beneficial to my day to day coding.

</comment></comment></comment><comment><USER15> I had a professor in university who was frequently saying he developed a thousand application and he didn't use any if.

I know it's extreme but is there any way to reduce (lets say 5 to 1) conditions?

I think he was developing Fortran apps.

Anecdote: This very same professor asked us to do a matrix operation (I don't remember what) without using if once. He said it would be faster than using ifs. Many of us couldn't. Then he revealed his solution, he was getting first indice of first row and doing some operation and getting the last indice of last row, then second indice of first row and so on. One of my friend told that if he wrote the algorithm plain using ifs, it would be faster. Professor told it's impossible.

In the end of the day the version which was written using ifs was a lot faster than the version without ifs. Because of the changing indices cause a lot of cache misses but getting matrix elements sequentially used cache correctly.

<comment><USER16> The performance cost of ifs are not that bad. Especially if it means you can read sequentially from the memory.

It however, do represent branching, and in a hotspot it can be more efficient to simply calculate both the if and the else and just choose the right value, rather than having a branch misprediction.

In any case, always profile, and identify issues before doing any optimization.

</comment></comment><comment><USER17> All of the proposed solutions are deficient:

> Pattern 1: Boolean Params

This solution suffers from what we typeful programmers call "Boolean blindness": [https://existentialtype.wordpress.com/2011/03/15/boolean- bli...](https://existentialtype.wordpress.com/2011/03/15/boolean-blindness/) . When you compute a bit, what you are actually interested in is the _meaning_ of the bit, which isn't included in the bit itself. For example, if the bit is set, then "x" is less or equal than "y"; if it's unset, then "x" is greater than "y".

> Pattern 2: Switch to Polymorphism

Dynamic dispatch (what the author wrongly calls "polymorphism") can be used for _open-ended_ case analysis. But it suffers from two drawbacks: (0) Unless you have multimethods, case-analyzing two or more values at the same time is a bitch! (1) Even if you do have multimethods, the open-ended nature of this whole business makes static exhaustiveness checking (making sure that no case is missing) impossible.

> Patte[r]n 3: NullObject/Optional over null passing

Null objects are still falling back to pattern 2, and optionals are severely underpowered in languages without pattern matching and compile-time exhaustiveness checks. For instance, one of my favorite patterns is implementing operations (say, "merge") on non-empty collections, then extending them to possibly empty ones:

        (* pe = possibly empty *)
        datatype 'a pe = Empty | Cons of 'a

        (* extend a merge operation on non-empty collections
         * to possibly empty ones *)
        fun pointed _ (xs, Empty) = xs
          | pointed _ (Empty, ys) = ys
          | pointed op++ (Cons xs, Cons ys) = Cons (xs ++ ys)

        fun merge (xs, ys) = ... (* possibly complicated *)
        and mergePE args = pointed merge args

How do Java-style optionals help?

> Patte[r]n 4: Inline statements into expressions

This only makes the problems associated to Boolean blindness even worse.

> Pattern 5: Give a coping strategy

What if there is no sensible default value? Just... no.

\---

What you really need is algebraic data types, pattern matching and exhaustiveness checks.

</comment><comment><USER18> Uhm. No, no, no, no and no.

> [Pattern 1] Solution: Split the method into two new methods. Voilà, the if > is gone.

And so is parametrization.

> [Pattern 2]: Solution: Use Polymorphism. Anyone introducing a new type > cannot forget to add the associated behaviour.

OTOH you make extensions more complex. I usually write in lisp and DO NOT use polymorphism for this but etypecase in the base implementation of a method (switch/case where the default case automatically throws an error). This allows people who extend my code to implemented a method specific to a type that my base implementation handles and thereby overriding my implementation with minimal effort.

> [Pattern 3]: Solution: Use a NullObject or Optional type instead of ever > passing a null. An empty collection is a great alternative.

This is, IMHO, not relevant at all - the decision how null values are handled simply has to be documented so programmers can make an informed choice. The only exception I accept is an empty collection which I'll always prefer over null, assuming that all other code handles empty collections gracefully.

> [Pattern 4]: Solution: Simplify the if statements into a single expression.

Works for the contrived example (and we all know that the code is really bad). For more complex code I rather follow the logic line by line instead of mentally disassembling a 10 line boolean expression.

> [Pattern 5]: Solution: Give the code being called a coping strategy.

No, just no. One does not aim at removing exceptions. Those are to be handled by a higher layer who actually knows how to handle it. If one uses default values one still has to check on that layer with the added burden of using a default value that is guaranteed to never be returned as a real value so we can make the distinction between record found/record not found.

</comment><comment><USER19> Misko Hevery did a Google Tech Talk about this some years ago, he also use a very similar example with switching on the birds.

[https://www.youtube.com/watch?v=4F72VULWFvc](https://www.youtube.com/watch?v=4F72VULWFvc)

<comment><USER20> This. If there's anything that's made me a better programmer it's Misko's talks.

</comment></comment><comment><USER21> One thing I've always done with if statements is when I have an if with a negated condition and no else case

        if (!condition) {
          // do stuff
        }

When I want to add an else case, I swap the order so the condition is no longer negated.

        if (condition) {
          // do other stuff
        } else {
          // do stuff
        }

To me it's easier to read a non-negated condition and the else case then feels more natural. (It avoids having to internally think about else case as "condition not not satisfied".)

<comment><USER14> Interesting. I often (but not always) prefer the if (!condition) {} at the top because I see it as 'bailing out' of the function if conditions are not met.

<comment><USER21> If I'm doing an early return, I usually don't put the rest of the function inside the else case since I feel it creates an unnecessary level of indentation.

</comment></comment></comment><comment><USER22> Using 'if' indicates programmer's doubts about what a program should do. These are usually rooted in low self esteem and troubled relationships with parents.

<comment><USER23> if (myParentsLoveMe) selfWorth++;

</comment></comment><comment><USER24> Getting rid of if/else is nothing but moving the if/else to somewhere else.

<comment><USER25> This is only true in a very technical sense.

        function getColor(str){
           if(str=='blue'){ return '#0000ff'; }
           if(str=='red') { return '#ff0000'; }
        }

        getColor = {
          blue: '#0000ff',
          red: '#ffoooo'
        }

The second one also has if statements inside the implementation of the hash map, but it isn't actually polluting your business logic. The question is no longer "what do you do when the input is like this or like that", but "lookup the corresponding output".

The distinction is nice because I know that getColor[thing] will likely have no side effects. I can treat it, on a theoretical level, strictly as a map.

Of course if the problem is "implement this on a machine without branching" this isn't super useful but most problems are not that.

<comment><USER24> I agree. For example when you are using some form of polymorphism, the compiler/runtime are handling your if/else for you. But, still in terms of understanding what a piece of code is doing you will have to consider all the possible branches whether they are explicit in code as if/else statements or hidden under some abstraction like map/dictionary.

Edit: The conditional abstractions like map are useful in the sense that the conditions that they support are very simple, in case of map it is if supplied key equals that key, whereas if/else statements can be used to create any kind of complex conditions.

</comment></comment></comment><comment><USER26> If you want extreme case of removing all ifs, see how ifTrue: and friends are implemented in Smalltalk (ie. true and false are instances of different classes), although essentially all compiler implementations turn that into normal conditional branches in generated bytecode.

<comment> aaron-santos I think I'm looking at an implementation of ifTrue[1], but it's a bit dense to someone who's not familiar with Smalltalk. Maybe you could walk me through it?

[1] - [http://git.savannah.gnu.org/gitweb/?p=smalltalk.git;a=blob;f...](http://git.savannah.gnu.org/gitweb/?p=smalltalk.git;a=blob;f=packages/stinst/parser/STCompiler.st;hb=HEAD#l842)

<comment><USER26> That's the compiler part that optimizes the elegance away :). The interesting part is here [1], note that it will work without any support from the compiler.

[1] - [http://git.savannah.gnu.org/gitweb/?p=smalltalk.git;a=blob;f...](http://git.savannah.gnu.org/gitweb/?p=smalltalk.git;a=blob;f=kernel/False.st;h=b1a85e58e6e90bc2034bf653d6276d12b8d1dae6;hb=HEAD) and [http://git.savannah.gnu.org/gitweb/?p=smalltalk.git;a=blob;f...](http://git.savannah.gnu.org/gitweb/?p=smalltalk.git;a=blob;f=kernel/True.st;h=eab5d9b9f11c501598115916dc234f8f50580c1f;hb=HEAD)

<comment> aaron-santos Much more straight forward. If I'm reading it correctly, True and False are subclasses of Boolean and each of which implements a complementary pair of ifTrue and ifFalse methods? Elegantly symmetric. :)

</comment></comment></comment></comment><comment><USER27> All these complicated examples and no mention of functional pattern matching or pattern matching at all.

IMHO These are by far the two most important ways to get rid of complex code embedded with ifs.

One very good example of this is erlangs factorial method.

       factorial(0) -> 1;
       factorial(N) -> N * factorial(N-1).

There are many other nice examples at the erlang documentation:

[https://www.erlang.org/course/sequential- programming#funcsyn...](https://www.erlang.org/course/sequential- programming#funcsyntax)

<comment><USER28> Unfortunately, pattern matching isn't available in many languages (or at least, including a new dependency for the sake of removing `if`s may not be worth it).

On the other hand, the article recommends using sub-type polymorphism, which is also unavailable in many languages.

</comment></comment><comment><USER29> Generally speaking, for every refactoring you could do, the opposite move is sometimes useful too. For example, inlining a function and extracting a helper function could both be a way to simplify code, depending on what you're trying to do.

Similarly here, I think it's good to know how to get rid of an if statement, but keep in mind that sometimes you might want to introduce an if statement. Sometimes you want polymorphism and sometimes it's better to do the same thing as pattern matching.

</comment><comment><USER30> The first "anti-if" should be to resist adding unnecessary features, on every level. The less branches, the less possible ways to fail.

</comment><comment><USER31> I like the addition of the "tolerance" bit to examples, more blogs should have a "when not to use" section.

</comment><comment><USER32> I don't know what's so "Missing" about the polymorphism anti-if: I've seen it ruin plenty of code.

</comment><comment><USER33> > Patten 3: NullObject/Optional over null passing

The solution here disperses the responsibility of keeping sumOf safe to its callers, all over the place, instead of a single location in sumOf.

<comment><USER34> Agreed. The sumOf function is now made more brittle by that fact, and would be unworkably so in a publicly-available API. This is easily fixed by a try-catch block if one finds that they are indeed allergic to if statements, although that too is a form of flow control. If you are programming in Go, you're going to have to bite the bullet and use an if.

(I suspect the author would prefer jumping in a lake over programming in Go.)

I think it is also worth mentioning that passing a new ArrayList over a null value is somewhat wasteful of memory. Though the reference to ArrayList will cease to exist, its allocated memory will hang out until the next GC phase. In the words of Bartleby, I would prefer not to.

I get the principle that is being advocated, but the solution code doesn't pass practical muster for me.

<comment><USER35> In this very specific instance, you could easily and idiomatically reuse a single instance of an immutable empty list:

[https://docs.oracle.com/javase/7/docs/api/java/util/Collecti...](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#emptyList\(\))

No dynamic heap allocation necessary.

</comment></comment></comment><comment><USER36> This reminds me of something I read on HN a while back and forgot to bookmark. (Naturally I've been unable to find it since.)

I think the article was written by a company who made a static code analysis tool. They described how there wasn't a large difference in quality between FOSS and proprietary code, except for one detail: FOSS code used "else" statements much less.

Anyone have any idea what I'm thinking of or if I'm even remembering it correctly?

<comment><USER37> That does sound familiar. Was it possibly from either the NDepend blog, or more likely, the PVS-Studio blog?

</comment></comment><comment><USER38> And if there is no record in the repository, what should I do with the default value? Check if the returned value is different from the default? I actually don't see any real benefit in cleanliness. The only thing that could actually happen is using the default in some way that could eventually bring the data in some strange state. An NPE would at least shout "YOU MESSED SOMETHING UP" in my face.

</comment><comment><USER39> Pattern 5 is all about removing semantic value from null references, but has nothing to do with if statements... In fact, the if-else remains (albeit hidden because of an early return inside an if, which is even worse in my opinion).

</comment><comment><USER40> I'm surprised there was no mention of the Specification pattern.

[https://en.wikipedia.org/wiki/Specification_pattern](https://en.wikipedia.org/wiki/Specification_pattern)

<comment><USER41> My god what an abomination of programming simplicity. Do people actually write code like this? It's as if someone said you _must_ use interfaces and you _must_ use objects for even the simplest boolean logic statement. I think I would claw my eyes out if I had to read and write code like this on a regular basis.

</comment></comment><comment><USER42> I'm quite supportive to the anti-if pattern but the presented example sounds me more like "code smells" and doesn't really makes me happy to me anti-if is a great winner when you can safely compute all the execution path in advance (in a way where you have not to nest ifs, of course!) but in situations where your code have to react to something that happens "on the moment"... well, probably "if" are more convenient (not always of course) anyway thanks to have raised the point, this topic is always interesting to me

</comment><comment><USER43> I was hoping for some examples that reduce costs incurred by failing branch- prediction in the CPU.</comment>


Hands on with Apple's Budget iPhone - <AUTHOR> http://blog.techdy.com/hands-on-with-apples-budget-iphone-video/

<comment><USER2> That looks exactly like the "Basic Bear" phone they are promoting and selling on their site: [http://techdy.com/shop/basic- bear/](http://techdy.com/shop/basic-bear/)

\- minus the apple logo

It's just an attention-grabbing-headline, please downvote this.

<comment><USER3> Aye, this is just an advert disguised as a Gizmodo-style world exclusive 'leak'.

</comment></comment><comment><USER4> At the end of the article they pitch an Android phone they made that's "based on the design of the next iPhone"

So that's about how much you can trust the legitimacy of these pictures

<comment><USER5> Their design is based on information that has already been leaked elsewhere. I think what's interesting about this submission is the quick turnaround.

</comment></comment><comment><USER6> There's something that feels really dodgy about this site. Apple haven't announced anything and the supposed budget iPhone they're showing looks an awful lot like their Android based "Basic Bear" phone...

Apple I doubt will be entering into the "budget" market any time soon. They can just sell their previous models at a discounted price instead of potentially tainting their brand with "basic" versions.

Apple are all about the build quality and aesthetics and given the amount of cash they apparently have in the bank, I would say their current strategy of selling expensive phones and computers is working. Nokia on the other end is going for the budget market because the likes of Apple and higher end Android devices ate into the space Nokia was once the king of and the budget space is all they really can compete it, Apple have no reason to currently compete.

</comment><comment><USER7> Looking at their products ([http://techdy.com/bear/](http://techdy.com/bear/)), this just seems like a lawsuit waiting to happen. Its pretty much identical to the design of the HTC One and iPhone.

Looking solely at the products though, it seems pretty cheap (cheaper than Nexus 4 even for the specs) but probably has poor build quality. Not sure if they are being truthful about the having the Snapdragon 600 either.</comment>


The Difference Between Amateurs and Professionals - <AUTHOR> https://www.farnamstreetblog.com/2017/08/amateurs-professionals/ <comment><USER2> Most of us are amateurs? Last time I checked (just now in fact) professional simply means you get paid for doing something. You can be terrible at your job but if you get paid for it you are by definition a professional! So I think this piece could have done with more care in terms. Additionally, it's pretty much just a list of assertions. Why should I give this any credence? On what basis was this list derived? It might all sound like good stuff but without any kind of decent context how is one to judge?</comment>