In the Turkish locale, "INFO".lower() != "info" - <AUTHOR> https://github.com/python/cpython/blob/fff3c28052e6b0750d6218e00acacd2fded4991a/Lib/logging/handlers.py#L802 <comment><USER3> Has anyone here _ever_ had a use case for toLower() where they actually wanted localization to apply?

It seems to me that in practice, it's extremely rare to want to change case of real, natural-language text. When I have natural-language text, it's just a blob to me, and I don't want to touch it.

The only time I ever want to lower-case or capitalize something, I'm working with identifiers meant for computer -- not human -- consumption. Usually, specifically, I'm dealing with identifiers that have annoyingly been defined to be case-insensitive even though the only humans that ever see them are programmers and programmers hate case-insensitivity. HTTP headers are a common example.

I mostly write C++, and I end up writing code like:

        for (char& c: str) {
          if ('A' <= c && c <= 'Z') c = c - 'A' + 'a';
        }

Later on, some well-meaning developer on my team will come along and say "Ugh what is this NIH syndrome?" and then they "clean it up" as:

        #include <ctype.h>

        for (char& c: str) {
          c = tolower(c);
        }

And then I have to say NOOOOOOO DON'T DO THAT YOU HAVE NO IDEA WHAT tolower() REALLY DOES!

I struggle to imagine any real use case where you'd actually want locale- dependent tolower() other than, maybe, a word processor -- but if you're writing a word processor, you're probably not going to be depending on the language's built-in string APIs to do your text manipulation.

<comment><USER4> This is a classic case of a 'why' code comment being needed. It's obvious what you're doing, but without a 2 line explanation, it's not clear _why_.

<comment><USER3> Yeah I probably wrote that comment the first few times I did this but it's hard to write it the 50th time.

Maybe I should have my own tolower() function that I can call so I only have to write the comment once but it just feels ridiculous somehow.

<comment><USER5> Why does it feel ridiculous?

<comment><USER3> Because I've already rewritten more of the standard library than is healthy.

I mean, it's clearly the right thing to do here but I can predict the conversation that will inevitably result... "You wrote your own tolower() function? Why?" "The standard one is horribly broken." "How could a function that lower-cases a letter be broken??? Jesus Kenton your NIH syndrome is out of control." "Sigh..."

(Slightly more seriously, any particular time I need to lower-case something, it takes 10 seconds to write out the code, but would take 10 minutes to find a good place to define a reusable function and exactly what its API should be, and so it never seems worth the effort in the moment. Just like how most messy code comes to be.)

<comment><USER5> This conversation can be simply be avoided by copy pasting your original hacker news comment into the library function header.

I have noticed some coworkers have their ego gratified by being right while everyone else is wrong. Instead of simply explaining what they are doing when they are doing it, they will do something that looks wrong in a very noticeable way and wait for the backlash. The backlash gives them an opportunity to show everyone else how they were right while everyone else was wrong and also an opportunity to play victim. However, in SW development - <USER2> is not just the technical details - your behavior also matters in a big way.

In this particular case, the correct approach is to create your own library function with appropriate comments. This is why the concept of a library function was invented. It is its entire raison-d'etre. However, you are doing everything but that. Including providing justifications in hacker news comments instead of your source code.

Now inevitably, someone will change your inline code to use to_lower. This will give you an opportunity to scream bloody murder, show how other engineers don't really understand technical details, correct them and also play victim. Create a library utility with comments and link it in - End of story.

<comment><USER3> Speaking of people wanting to gratify their ego by being right: Everyone on this thread trying to lecture me on software engineering? ¯\\_(ツ)_/¯

<comment><USER5> At least, you get to play victim :)

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER6> Welcome to the Turkish language, where we have ı, i, I and İ. In our language the conversion is as follows:

\- i <-> İ

\- ı <-> I

We love our dots and preserve them. For a more detailed read, please see:

[https://blog.codinghorror.com/whats-wrong-with- turkey/](https://blog.codinghorror.com/whats-wrong-with-turkey/)

<comment><USER7> As I understand it, Turkish is one of the more important locales to test with because of things like this.

<comment><USER6> Turkish is the only language which has the ı & I pair. Similarly, AFAIK, Turkish is again the only language with ğ and ş letters. So, by testing for Turkish, you test for a lot of European languages at once. Moreover we share some modified letters(ç, ü) with other Central European languages.

If your program can pass "The Turkish Test", you pass a lot of others too.

<comment><USER8> Azerbaijani too. Moreover, Azerbaijani has an additional letter ə, which sounds like /æ/.

<comment><USER9> I love the feeling of camaraderie arising from that partial mutual intelligibility of Turkish and Azerbaijani.

That connection through language goes a long way.

müqəddəs bacı millət :)

</comment></comment></comment></comment></comment><comment><USER10> Unrelated story about Russian language.

The first letter of russian alphabet is А, the last one is Я. So it's natural to try to match russian words with '[А-Яа-я]+'. But this is a recipe for disaster, this regexp doesn't match words with 'Ё' in them like "Артём".

This is due to the fact that regexp ranges work on byte values. All letters of russian language have neatly ordered byte values, except for the Ё.

<comment><USER11> English is probably the only commonly spoken language where naïve char range matching _kind of sort of_ works. I say "kind of sort of" because [a-zA-Z] trivially fails to match all words in many English texts that haven't been lossily compressed to ASCII, including this comment.

It is practically always wrong to match on [a-z] unless you're parsing a computer language whose spec guarantees that it works.

<comment><USER10> I always wanted to know, how easy is it to type naïve on a common western keyboard?

Do you have to press some obscure keyboard shortcut?

<comment><USER12> _how easy is it to type naïve on a common western keyboard?_

In macOS, you can either use Command-u (for "umlat") followed by i, or hold down the i key for a second and press 2 to select the ï from the pop-up menu.

<comment><USER13> > Command-u

option-u (aka alt-u).

Generally speaking, command is for application-level or os-level commands, control is for text edition, and alt is for alternate characters (all can be shifted and command "overrides" the rest).

<comment><USER12> You're right, it's Option-u. Most of the key labels on my MacBook have long since been scratched away.

This has happened with every single Apple keyboard I've ever used. I suspect it's my fault, since I'm a key pounder, having learned to type on an IBM Selectric typewriter.

</comment></comment></comment></comment></comment></comment><comment><USER14> Changes to the casing might also change the value's length. E.g. uppercasing the German ß will transform it to SS. Example using JavaScript:

'ß'.toUpperCase(); // returns 'SS'

[https://en.wikipedia.org/wiki/%C3%9F](https://en.wikipedia.org/wiki/%C3%9F)

<comment><USER15> There is apparently a multi-decade controversy about that:

[https://en.wikipedia.org/wiki/Capital_%E1%BA%9E](https://en.wikipedia.org/wiki/Capital_%E1%BA%9E)

(with German language authorities recently endorsing the idea that ß can have a distinctive uppercase form "ẞ")

</comment></comment><comment><USER16> Ive long thought programming languages need a "localizable string" (Aka user- facing string) type, different from regular utf8 strings. Something like what gettext and other i18n libraries fake for you, but native to the language.

Behaviour like this is definitely a good reason why: sorting, changing case, etc should be consistent when dealing with strings used as constants and identifiers, but Python's .lower() behaviour makes sense in a localizable string context.

<comment><USER17> Along similar lines, I've thought that it would be useful if Unicode included language marks (i.e. codepoints to identify blocks of text as being written in a specific language). It would be strictly more useful than the barebones left-to-right/right-to-left marks (U+200E/U+200F) when deciding how to process and display text. And it would be a step towards correcting the mess that was Han unification.

<comment><USER18> What this gets right down to is that Unicode is a flawed idea: the meaning/behavior/whatever of characters is insanely dependent on their context.

The problem was never gazillions of code pages, but our inability to write C to deal with that amount of complexity circa 1990.

With modern machines, and good programming languages with good type systems, I absolutely think we could store a language per string, and concatenate into a polylinguistic rope if needed.

This would hopefully push us away from stringly-typed crap in general.

<comment><USER19> > the meaning/behavior/whatever of characters is insanely dependent on their > context

I wish you would give an example instead of just proclaiming crapness. You know, so we n00bs can learn something.

<comment><USER19> @toast0, @lazulicurio, both of your points seem to illustrate the complexities of the languages, not "...that Unicode is a flawed idea" as the original poster said. AFAIKS this is intrinsic complexity showing itself and does not make any indication of how it should be done correctly, or better.

<comment><USER17> > both of your points seem to illustrate the complexities of the languages, > not "...that Unicode is a flawed idea"

The flaw in Unicode is that it punts on the intrinsic complexity---pretending that codepoints have language-independent, plain-text, semantic meaning.

A couple of threads that have molded my views over time:

 _I can 't write my name in Unicode_ [https://news.ycombinator.com/item?id=9219162](https://news.ycombinator.com/item?id=9219162) (Specifically these two comments [https://news.ycombinator.com/item?id=9220530](https://news.ycombinator.com/item?id=9220530) and [https://news.ycombinator.com/item?id=9220970](https://news.ycombinator.com/item?id=9220970))

 _Why isn 't the external link symbol in Unicode?_ [https://news.ycombinator.com/item?id=23016832](https://news.ycombinator.com/item?id=23016832)

<comment><USER18> > The flaw in Unicode is that it punts on the intrinsic complexity--- > pretending that codepoints have language-independent, plain-text, semantic > meaning.

> Pretending "plain text" isn't an oxymoron

FTFY :)

</comment></comment></comment></comment></comment></comment></comment><comment><USER20> [https://garygregory.wordpress.com/2015/11/03/java- lowercase-...](https://garygregory.wordpress.com/2015/11/03/java-lowercase- conversion-turkey/)

In the Turkish locale, the Unicode LATIN CAPITAL LETTER I becomes a LATIN SMALL LETTER DOTLESS I. That's not a lowercase "i".

</comment><comment><USER21> My genius idea was once to use toupper() to normalise paths on Windows, which are case-insensitive. One day, a customer from Azerbaijan reported that my application failed to access a file in C:\WİNDOWS\\...

<comment><USER10> i feel your pain

</comment></comment><comment><USER22> 07/04/2008 -> April 7th seems about as reasonable a result as July 4th, especially when you've explicitly opted in to a Turkish locale. I don't agree with the article's assertion that the format being interpreted according to the user's locale is wrong here, the one wrong part is a US centric programmer's expectation that PP-QQ-YYYY is an unambiguous format. Use YYYY- mm-dd when you need a format that's not ambiguous

<comment><USER23> YYYY-mm-dd also plays nice with lexicographic ordering, which is why I always use it when I need to put dates in e.g. filenames

<comment><USER22> I'm a European working primarily with Americans. My home country uses dd/mm/YYYY (or dd/mm for short) and the US uses mm/dd/YYYY for with mm/dd for short. I've switched to YYYY-mm-dd simply for my own sanity and if I omit the year I write the month in text format, such as "5 June".

<comment><USER24> The US military uses the almost same convention (dd-mmm-yyyy) so 07-aug-2020.

<comment><USER25> That's dd-mmm-yyyy

<comment><USER24> Thanks!

</comment></comment></comment></comment></comment></comment><comment><USER26> Repeat after me: don't do string operations without explicit locale. Don't do string operations without explicit locale.

I don't know why so many languages have string functions that should take a locale but provide an overload that doesn't and which uses the _system_ locale as the default. It can't be what many developers actually want, yet it has become the norm. Worse, code using a default locale _appears_ to work on the developers machine and in production, until someone parses a number in France or lowercases a string in Turkey, which is a late and expensive discovery of the bug.

The default shouldn't be the system locale, it should be an invariant locale. And I'll go so far as arguing this invariant locale should be invariant across systems (meaning it can't just defer to a system C library either).

<comment><USER27> I ran into this with C#/.NET on Windows - I tried to convert a string "1.3" to the float 1.3, and it failed on languages that use comma as their decimal separator.

That was a learning experience.

<comment><USER26> Indeed. As a person from a comma country, I find these mistakes in most code bases I look at. It makes it frustrating to contribute to open source, for example.

Perhaps it'll make you feel better about your parsing bug that even the C# compiler (Roslyn) code base had several of these issues.

</comment></comment></comment><comment><USER28> For a similar reason, Java on Mac and Linux was briefly broken for anyone using it in the Turkish locale. It was because in the Turkish locale, !"POSIX".toLowerCase().equals("posix").

Relevant bug report here: [https://bugs.openjdk.java.net/browse/JDK-8047340](https://bugs.openjdk.java.net/browse/JDK-8047340)

</comment><comment><USER29> As it isn't yet mentioned: for these cases the Python standard library explicitly has [https://docs.python.org/3.8/library/stdtypes.html#str.casefo...](https://docs.python.org/3.8/library/stdtypes.html#str.casefold) (str.casefold), which aggressively lowercase-normalizes strings with an algorithm from the unicode standard. Every case comparison using lower() instead of casefold() can be considered a bug.

<comment><USER30> > Every case comparison using lower() instead of casefold() can be considered > a bug.

If you just casefold two strings and compare them, it's still a bug. You need to normalize them to NFKC first.

<comment><USER31> Is NFKC necessary, isn't NFKD enough? (As in you have to normalize and decompose both strings, but at that point you can check them for equality, and doing the canonical composition isn't needed, right?)

<comment><USER30> I think that would work if you're just checking for equality and want to minimize processing. I guess as a web developer I always just assume people are going to be storing strings in a database after normalizing them, so would want to minimize string length.

</comment></comment></comment></comment><comment><USER8> Correct: you would get "ınfo", "warnıng" and "crıtıcal" in Turkish and in Azerbaijani.

<comment><USER32> Further context:

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

Did not know Istanbul is actually İstanbul.

<comment><USER33> Me neither. I did know it's not Constantinople, though.

<comment><USER8> Constantinople (Fatih) is the capital town of Eistipolis (Istanbul).

</comment></comment></comment></comment><comment><USER34> Please stop doing this. Don't bind lower() upper() functions to environment variables or anything else system related. Sun did this in Java and doesn't even bother to mention the issue in documents. It caused huge problems for more than a decade.

You can just make string lowercase() uppercase() function work the same everywhere, regardless of locale settings. Provide a special case function lowercaseTR() or so. This works very well in Go.

By the way, Azerbaijan has the same problem because they accepted help from wrong guys when they switched to Latin.

<comment><USER35> You'll be glad to hear that Python did stop doing this: Python 3 has never behaved this way, and its `lower` and `upper` methods have always been independent of your locale or anything else from your system.

The workaround in the OP was added in 2006 (note the reference to an issue on "SF", i.e. SourceForge -- another era!), and is now long obsolete.

<comment><USER34> Very much so. Thanks.

</comment></comment></comment><comment><USER36> In C (POSIX.1-2008, specifically), there's tolower_l() and the rest of the _l functions for this use case, which take a locale as an argument. That let's you ask for the English (or even "C locale") lowercase versions of these English words, even when your process's current locale is Turkish.

[https://www.man7.org/linux/man- pages/man3/tolower_l.3.html](https://www.man7.org/linux/man- pages/man3/tolower_l.3.html)

<comment><USER37> The mention of _l functions reminded me of this gloriously over the top git message/rant.

"Those not comfortable with toxic language should pretend this is a religious text."

[https://github.com/mpv- player/mpv/commit/1e70e82baa9193f6f02...](https://github.com/mpv- player/mpv/commit/1e70e82baa9193f6f027338b0fab0f5078971fbe)

</comment></comment><comment><USER38> Looks like it's no longer the case in Python 3:

       Python 3.7.3 (default, Jul 25 2020, 13:03:44)
       [GCC 8.3.0] on linux
       Type "help", "copyright", "credits" or "license" for more information.
       >>> from locale import *
       >>> setlocale(LC_ALL, 'tr_TR.UTF-8')
       'tr_TR.UTF-8'
       >>> 'INFO'.lower()
       'info'

<comment><USER39> Oddly, it also wasn't the case for Python 2 Unicode strings (u'INFO'), only for Python 2 byte strings ('INFO'). So it's possible that Python 3 lost this behavior by accident.

<comment><USER35> On some more digging through history, it looks like the change in behavior for byte strings was intentional: [https://github.com/python/cpython/commit/6ccd3f2dbcb98b33a71...](https://github.com/python/cpython/commit/6ccd3f2dbcb98b33a71ffa6eae949deae797c09c)

Author: Guido van Rossum <firstname.lastname@example.com>

Date: Tue Oct 9 03:46:30 2007 +0000

        Replace all (locale-dependent) uses of isupper(), tolower(), etc., by
        locally-defined macros that assume ASCII and only consider ASCII letters.

</comment></comment></comment><comment><USER40> I remember running into problems with SQL stored procedures where column and table names were case-insensitive, so you don't know if you've properly typed all the column and table names. Until a customer in Turkey eventually installs it and you find out you've missed the proper capitalization of an identifier containing the letter "I", and the stored procedure fails.

<comment><USER41> This is what I usually think about whenever people say yay to Unicode in language identifiers.

<comment><USER42> "I" is in ASCII.

<comment><USER43> "İ" and "ı" are not.

</comment></comment></comment></comment><comment><USER44> Note to the next language designer: don't use strings as a substitute for enums.

<comment><USER45> It might be OK if strings are immutable and therefore internable.

<comment><USER44> It doesn't prevent someone from calling your function with "INFO" instead of "info", does it?

</comment></comment></comment><comment><USER46> [http://www.moserware.com/2008/02/does-your-code-pass- turkey-...](http://www.moserware.com/2008/02/does-your-code-pass-turkey- test.html)

This is old but still valid reading...

</comment><comment><USER42> ITT calling setlocale or std::locale::global(...) is ALMOST ALWAYS a heinously bad idea and should rarely be done, because it breaks tons of code (notably everything that uses printf/scanf and everything using stringstream).

</comment><comment><USER47> I think things like these should be explicit. Even it is convenient to have a default, it should be what most people would expect.

For example, instead of .lower(), we can have .lower_ascii(), .lower_turkish() or .lower(locale) . But I know it would be tedious to use if you need to specify it everytime, so it makes sense to have a .lower(locale=DEFAULT_LOWER_LOCALE) . As for what should DEFAULT_LOWER_LOCALE be, it is worth debating, but I think it shouldn't introduce unexpected behavior.

</comment><comment><USER48> Stringly typed: Play stupid games, win stupid prizes.

</comment><comment><USER49> The PHP interpreter has an internal reimplementation of string case conversion that's ASCII-only in order to avoid this problem.

<comment><USER50> doesn't php have this exact problem with their case-insensitive (hate that btw) function/method names and turkish localization? or did they actually fix it at some point?

<comment><USER51> I'm guessing that they might have "fixed" it by implementing the ascii-only tolower function, but yes, PHP used to not work properly with Turkish localization.

</comment></comment></comment><comment><USER52> Serious question.

Why on earth would you hard-code these, instead of simply call a lowercase function in the en-US locale?

These are English words. Naively lowercasing them according to whatever locale the server or user has set seems like a terrible programming practice. Any call to a lowercase function should be explicitly including an argument that specifies it's English, no?

In the same way we've all learned to never store times without an explicit timezone (even if it's UTC), or locate a string offset without knowing your encoding... you should never perform language transformations (case changes, accent removal, etc.) without a locale.

Hardcoding these things is just patching over the symptoms without addressing the cause, no?

</comment><comment><USER53> Hence toUpper/toLower is not a strategy that passes the Turkey Test for case insensitivity.

</comment><comment><USER54> See also [https://garygregory.wordpress.com/2015/11/03/java- lowercase-...](https://garygregory.wordpress.com/2015/11/03/java-lowercase- conversion-turkey/)

</comment><comment><USER55> This particular case seems odd to me because INFO is an English word, and ınfo is not.

<comment><USER56> You could make a case that Unicode should have different "i" characters for different languages. Then you could do all transformations unambiguously. On the other hand almost everyone abuses the minus sign as a dash, and treats the apostrophe and the prime sign (signifying feet or minutes) as interchangeable, so in all likelihood they would constantly use the wrong i too.

<comment><USER41> Pretty sure that's not true. When you switch your keyboard you will have a proper i character in another language unless your keymap is broken. How do you think Chinese, Russians or Greek type their characters?

<comment><USER57> The grandparent obviously meant "latin i"; none of the three languages you mention have any latin letters, but at least Russian and Greek have some lowercase and some more uppercase letters with the same glyph/shape as latin ones.

<comment><USER41> Yeah, and those similar glyphs are not available on their own language keyboard.

</comment></comment></comment></comment></comment><comment><USER58> I'm going to be a bit controversial here and say that that mapping logic should _always_ exist even if toLower() were reliable across all locales. You're mapping between different use cases here, eg. internal to logfile to API to database to method name to whatever, and inserting magic transformations in your constant values rather than treating them as different tokens for different use cases constrains you and introduces unnecessary amounts of "magic".

</comment><comment><USER59> ObTurkeyTest: [http://www.moserware.com/2008/02/does-your-code-pass- turkey-...](http://www.moserware.com/2008/02/does-your-code-pass-turkey- test.html)

</comment><comment><USER60> Only for the record, there is something very similar that may happen when creating CD/DVD's (please read when using mkisofs and similar), with the "dash" that when "capital" becomes underscore (but not only ) depending on the reference ISO 9660/Joliet/RockRidge convention in use.

[https://web.archive.org/web/20151007005513/http://www.911cd....](https://web.archive.org/web/20151007005513/http://www.911cd.net/forums//index.php?showtopic=25612)

</comment><comment><USER61> The practice of converting enum-like keys into their string representation by using toString, toLower, etc seems convenient but gets very contrived very fast. How do you deal with underscores? What about using the message in a sentence? I say, use the enum in your code as a conditional or something but always explicitly write out the messages intended for the user.

</comment><comment><USER62> [https://bugs.python.org/issue1524081](https://bugs.python.org/issue1524081)

> KeyError: 'Info'

</comment><comment><USER63> I learned about this in javascript when I discovered Angular has its own lowercase method. Apparently it's internal only now.

[https://github.com/angular/angular.js/commit/1daa4f2231a89ee...](https://github.com/angular/angular.js/commit/1daa4f2231a89ee88345689f001805ffffa9e7de)

</comment><comment><USER64> Yeah, there were some weird bugs about that. I remember one in a media player. Also "info".upper() would be İNFO probably.

</comment><comment><USER65> Ah yes, locales. Everyone loves them [https://github.com/mpv- player/mpv/commit/1e70e82baa9193f6f02...](https://github.com/mpv- player/mpv/commit/1e70e82baa9193f6f027338b0fab0f5078971fbe)

</comment><comment><USER66> I think we should have stopped at ASCII, I don't care that my language has letters not in there, it'd be neater if we just did now like back then: "This is a computer, so everything is in English" :) Or adapt the alphabet to use ASCII.

</comment><comment><USER67> In the Danish locale "aa" doesn't start with "a".

</comment><comment><USER32> Dumb question, if you _really_ need the exact string "info" in a given context, why not hard code it? What does .lower() or even a map liked the linked one actually buy you?

<comment><USER68> Maybe the input is case insensitive, for example if you work with html you might see "DIV","div" who knows some crazy dev or tool might generate "DIv" or "dIv" so is simpler to lowercase the input then work on it.

</comment></comment><comment><USER69> Wouldn't converting to nfkd/c first solve this issue too? My understanding of those forms was that they're made exactly for this case.

<comment><USER38> No, these are ASCII strings, so they are already normalized.

<comment><USER69> Oh, I haven't used python much, but I thought it's all Unicode? If this were ascii it would work out of the box since there is no dotless lowercase i in ascii.

<comment><USER70> There are no code point for TURKISH LOWERCASE DOTTED I not for TURKISH UPPERCASE DOTLESS I, which means that the text doesn't carry enough information for roundtrip preservation.

I believe this has proven to be a mistake but I'm not an expert. I don't know _why_ it wasn't done.

</comment></comment></comment></comment><comment><USER71> The "İ" strikes again

</comment><comment><USER72> what a gorgeous source-comment. Makes the non-obvious crystal-clear.</comment>


How to create unique passwords you won't have to memorize - <AUTHOR> I just heard this on the radio. I was appalled.<p>http://www.cbc.ca/radio/thesundayedition/how-to-create-unique-passwords-you-won-t-have-to-memorize-1.4579765 <comment><USER2> Don't do this. Submit a story the normal way, not with a blank URL. Stories with blank URLs are penalized (or were at one point) but, more importantly, submissions to HN are community property, and the person who happens to submit a link first is not entitled to a special commentary at the top of the thread.

<comment><USER3> while I agree with you, you could go a little easier on OP. this is the OP's first submission. Words like "entitled" and "obnoxious" are a bit much.

<comment><USER2> Thanks; in retrospect I'm unhappy with the last sentence, which I think I wrote (unreasonably) anticipating a snippy response, so I deleted it.

</comment></comment></comment><comment><USER4> This is dumb but not that dumb.

The method is (mostly) fine given most people's threat model. It solves password reuse and the generated passwords are resistant to dumb brute force. You lose a lot of entropy if people know the method or even know that characters are more likely to be pulled from the domain name but given a good enough seed (the article has seven characters) you are still generally fine.

If you are high value target it is obviously awful since you are worth the time for a human to reverse the pattern and break your other passwords.

The real reason this is dumb is because it doesn't allow you to change your password, not because your passwords have lower entropy.

</comment><comment><USER5> Not to give too much away. But I think most of us use similar password methods, on top of whatever inlay password provider/manager you're using. e.g. Lastpass autogenerates, saves,syncs and fills. - [https://helpdesk.lastpass.com/generating-a- password/](https://helpdesk.lastpass.com/generating-a-password/)

</comment><comment><USER6> like a fair few other people, particularly on HN, my process is:

1\. Pick an extremely good, very long master password.

2\. Make my password manager generate maximum-allowed-length random line noise for every site I have an account on.

3\. Never know or care what these passwords are.

4\. For edge cases like workstation logins and "forgotten password hints", use diceware to generate easily typed nonsense phrases.

</comment><comment><USER7> I used to have a similar scheme for passwords. It only works well as long as one uses the same pattern for all passwords though.

This starts to break once you want to or need to change a password. I had to abandon the scheme once haveibeenpwned.com noticed me of a breach including one of my passwords. I could either remember a new pattern for that one site or change passwords of all my sites.

I chose to do the latter and used random passwords created by a password manager. That way I avoided running into the same problem again.

</comment><comment><USER8> Password management remains a big problem for people, who tend to blame themselves for the trouble they find in remembering passwords.

Giving them tools, however unwieldy, doesn't seem terrible to me?

bSSCmp9; scores 38 bits of entropy, and if someone decides that SSC ought to be their personal password pin, I think it's better than repeating the same password over and over again.

To me, password managers are the best option, but I struggle to convert my less savvy friends.

</comment><comment><USER9> Just use an incredibly strong password you couldn't possibly ever forget and use it for email. Then use password reset with a randomly generated string every time you have to login somewhere.

Because really, email is effectively the only password which matters.

</comment><comment><USER10> I mean it's bad but it's not that bad really. Obviously if everyone used the same sequence it would be very terrible.

It's marginally better than pure password reuse.

But compared to Troubador ([https://xkcd.com/936/](https://xkcd.com/936/) ) it's not really worse.

It slightly mitigates the 'humans are bad password generators' trap.

Really it mainly falls down because passwords are terrible and the best industry standard solution is a shit version of OAuth where the OAuth mechanism is 'copy and paste from <InsertPasswordProvider>'.</comment>


Ask HN: Zero-downtime deployment of multi-container app - <AUTHOR>

Wondering could someone shed a light on this? thanks! <comment><USER2> You want specific tools, or what? Are you using dockr or ? A 30 second summary of your architecture will help a lot.

Zero downtime is usually tricky and will greatly depend on your architecture. I can I think of two overall paths to success, but there are more (and these may or may not work for your use case).

1) Prod A / Prod B flip. Your current code runs in prod, we will call Prod A. Bring up an entire copy of your stack with the new code version as prod B.. Once it is up and stable, you switch traffic over to it.. once all traffic is switched, you kill the old servers. Tricky part with this is state, do you need to worry about state loss? If you keep a constant database that both prod A and prod B hit, you can do this without too much trouble. Make sure you do no state on your individual app servers (session cache etc).

2) Slow roll. Say you have 10 web servers that are behind a load balancer. You take 1 down - upgrade it - then add it back. Repeat until all 10 are upgraded. The trick here is what happens if a user hits code version A then B then back to A? If it doesn't matter, easy. If it matters, you may need to lock clients to machines from the load balancer, so that no one that has seen the new B will ever switch to an old server still on A.

<comment><AUTHOR> Thanks brianwawok, I'm currently experimenting with #1, switching between two batches of docker containers with a bunch of script, but am curious about is there more robust approaches to this? What are people using professionally in real world?

<comment><USER2> The real world is a huge range. In my experience, something like 75% of the world does..

1) Push out a new code

2) Shut down all prod servers at once

3) Restart them

Maybe during a weekly maintenance window.. maybe at 2am.. maybe at noon.. depending on the company and clients. Basic assumption is "Meh, people will reload if the page is down for a few minutes"

Even though 0 downtime is the "right" way to do stuff, seems like the ops level of many places is not that high.

The fact that you have scripts and are making some kind of attempt for less downtime puts you in the top 25% of the internet.

</comment></comment></comment><comment><USER3> Docker's native CNM (Container Network Model) provides a out-of-the-box solution to support this use-case. Pls refer to [https://github.com/docker/libnetwork/blob/master/docs/design...](https://github.com/docker/libnetwork/blob/master/docs/design.md) for more info on Docker CNM. This eliminates the need for any custom scripts to achieve the swappable use-case that you have in mind.

The CNM is realized using the newly introduced Experimental Networking solutions which includes : Network & Service UI, Pluggable Service-Discovery and Native Multi-Host cross-container connectivity. More information on trying out these experimental feature : [https://github.com/docker/docker/blob/master/experimental/ne...](https://github.com/docker/docker/blob/master/experimental/networking.md) [https://github.com/docker/docker/blob/master/experimental/RE...](https://github.com/docker/docker/blob/master/experimental/README.md)

Service (aka endpoint) owns the networking configs (such as ip-address, mac- address, etc...) and the container that backs the service can be swapped while retaining the same networking and service configs. Hence swapping a container between older to newer version of app server is just a matter of detaching a service from the older container and attaching the same service back to the newer container. Also, Please note that a container can belong to multiple networks and each container can publish different services in different network.

With these simple and composable CNM design, your use-case can be mapped to the CNM model. A quick diagram explaining the concept : [https://docs.google.com/drawings/d/1LvD94UwfinQelpEqT9BaRYmi...](https://docs.google.com/drawings/d/1LvD94UwfinQelpEqT9BaRYmiKMcRpRxgX1CIpS-2oYI)

We can add more detailed documentation for this specific use-case. Please join us in [https://github.com/docker/libnetwork](https://github.com/docker/libnetwork) and IRC@freenode #docker-network channel to discuss this in more detail.

<comment><AUTHOR> Thanks @theod, will definitely check that out!

</comment></comment><comment><USER4> Do it the same way you would do it without a containering system.

Load balancers, service discovery, IP swapping, etc. all help accomplish this.

</comment><comment><AUTHOR> Thanks for the feedbacks, more details here.

In a multi-container app based on docker with cross-container communication, as structured below:

load balancer → app servers * n → db * 2

How does one deploy new code to the app servers without any downtime?

I'm looking for any docker-based solutions, toolkits or simply tips and tricks, thanks!</comment>


Speech to Text in 3 lines of shell script using ffmpeg and Google's API - <AUTHOR> https://github.com/prayag/SecretCloud/blob/master/speechToText.sh

<comment><USER2> Does the shebang count as a line of code? github counts it ...

<comment><AUTHOR> Just details.

<comment><USER2> Couldnt you do this in one line by taking the output from ffmpeg [specify the output file as '-'] and piping into curl? iirc:

1) ffmpeg supports outfile - to mean stdout

2) curl can post data from stdin

No need for temporary file, and I believe it is not necessary to wait for the entire file to finish.

<comment><AUTHOR> Google API expect an entire file to be uploaded before it processes it, hence the need of a temp file.</comment></comment></comment></comment>


C++11 FAQ - <AUTHOR> http://www.stroustrup.com/C++11FAQ.html <comment><USER2> I've been programming for money for over 20 years and I grew up professionally writing C and then half-migrating to C++, because the latter very naturally captured lots of C patterns and allowed for more succinct expression of the same. It was lean, expressive and _elegant_. Just needed a bit of Lisp-y closures and it would've been perfect.

And then things got completely out of hand. Elegance was nuked from the high orbit in favor of "power features" and abstraction. Fucking Boost (I can't tone it down, sorry), move semantics, ass-backwards closures, meta-template programming - C++ that was _easy to understand_ became something that would normally come out of self-indulgent academic research.

Again, I've been using C/C++ for all my professional life, so it pains me to say this, but what it has become, it's... it's just horrible. Anything - C, D, Python, Rust - is cleaner and more elegant than C++ and just as powerful. If nothing else, I feel sorry for Bjarne. What could've been a gem of programming languages became [http://i.imgur.com/1oGHYqi.jpg](http://i.imgur.com/1oGHYqi.jpg)

<comment><USER3> This is perhaps one of the more unexpected opinions on C++ I've encountered. When I picked up C++ with Turbo C++ 3.0 in the early '90s, it was already widely regarded as an over-complex behemoth. Donald Knuth said of it in 1993, "Whenever the C++ language designers had two competing ideas as to how they should solve some problem, they said 'OK, we'll do them both'. So the language is too baroque for my taste." The last twenty years, there's no C++ that I would call lean, expressive, and elegant. You give the example of template meta-programming as something added more recently, but Erwin Unruh was printing the primes in compiler error messages not long after Knuth was knocking C++ as baroque. It makes me wonder if perhaps the issue isn't simply that over time you've become more aware of how complex the language has always been?

The language has continued to grow, but it's growing in a rather different direction (or rather in a clear direction): towards a modern, preferred subset that _is_ lean, expressive, and elegant. While C++ is still far from my favorite language, I find C++ today to be far simpler, more expressive, and more elegant than at any other point in the past.

<comment><USER4> Arguably the std::move stuff and the semantics around it have added uncomfortable complexity to the language, even if it might have been necessary. Other than that I think other advances in C++11 and beyond have made for a quite nicer language to work in.

I love C++11 and use it every day, but I think putting references in the language was an 'original sin'. They should have stuck with C's model: it's either a value or a pointer to a value. References just added a pile of complexity and pontificating about whether something was being copied, moved, or passed by reference.

<comment><USER5> Surely references have intrinsic value to the programmer? They're a pointer that can't be moved or rebased. Other languages have only references, and in C++ you can use that convention and not have any extra confusion.

<comment><USER6> References are crazy. There's no simple guideline to use them safely. Check this out:

        const string& s = max<string>("a", "b");
        cout << s;

Standard types and functions, const references, no warnings, everything by the book. But it crashes.

There's a similar can of worms related to slicing (treating Derived* as Base* is silently unsafe because arrays and copy constructors exist). C++ is scary.

<comment><USER7> Works for me in both C++03 and C++14? [https://ideone.com/KhfGaN](https://ideone.com/KhfGaN)

<comment><USER6> Your code is not the same as my code and you're probably new to C++. I suggest trying two changes:

1) Replace max("a", "b") with max("b", "a"). Run it, look closely at the result, and be enlightened.

2) Replace max("a", "b") with max<string>("a", "b"). Run it, look at the result, and be enlightened in a different way.

As a small hint, your code invokes _unspecified_ behavior, while my code invokes _undefined_ behavior.

If this exercise doesn't put the fear of C++ into you, then I don't know what will :-)

<comment><USER7> Sorry, can you clarify? Adding the template argument causes a crash on idone, but I have no idea why that happens. Moreover, the output on my computer is always b\n.

EDIT: Not sure if this is it, but after some digging I've found [0] on lifetimes of temporaries. As for the lacking template argument, presumably const char* is inferred and a temporary string is constructed in main?

[0] [http://stackoverflow.com/a/2784304](http://stackoverflow.com/a/2784304)

<comment><USER6> So first of all, max("a", "b") expands to max<const char*>("a", "b"). It computes the maximum of two pointers, without looking at the characters at all. Comparing two pointers to unrelated objects is unspecified behavior, but in this case it usually returns the second pointer.

As for max<string>("a", "b"), it implicitly converts both arguments into temporary strings, then returns a const reference to one of them. Since it's a reference to a temporary, it becomes dangling when max returns, but you can assign it to a const string& anyway. When you try to access it, you'll get garbage or crash.

<comment><USER7> Thank you for the explanation! I'll have to look out for that one...

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER8> Good stuff, I can also heartily recommend Scott Meyer's Effective Modern C++ book which covers idiosyncrasies and some unexpected behaviour (at least to me).

Also Stroustrup's 4th edition of The C++ Programming Language is invaluable, if not just for the more-readable sans-serif font compared to the 3rd edition! And of course the coverage of all C++11 changes in it...

I can also recommend the Overload journal for interesting C++ articles ([https://accu.org/index.php/journals/c78/](https://accu.org/index.php/journals/c78/))

And cppcon videos on YouTube - there's a wealth of info there, free.

Also the ISO CPP FAQ (which I think supersedes Stroustrup's?): [https://isocpp.org/faq](https://isocpp.org/faq)

<comment><USER4> I need to figure out what to do with my expensive old hard cover addition of the (C++98) C++ Programming Language. It just sits there looking sad. Not much value in it anymore.

<comment><USER9> It's a monument to progress; for maximum artistic and educational value, place it where you see it every day on top of decorative obsolete hardware (I recommend the Thinking Machines CM-2 for prettiness or SGI workstation for historical value).

</comment></comment></comment><comment><USER10> Interesting to see the love/hate. We are just starting a new blank slate code base and decided to go straight to C++17. We need expressivity early on, high performance later. And a model where someone can really get high performance on the core and still let people prototype / experiment down the road. It's pretty well supported by gcc & clang which are the compilers we care about.

I haven't really done much C++ programming in 20 years so approached it as a brand new language (to me) that I'd never used before. It's a big but powerful standard. I can't say I adore the syntax, but it's subject to path-dependent constraints that you just have to put up with.

I'm still looking for good references to style and practice that are appropriate to the latest C++. Books targeted at C++11 are pretty useful but it's too early to have more than the standard to help with 1y features.

</comment><comment><USER11> Summary of C++17 changes: [http://www.bfilipek.com/2017/01/cpp17features.html](http://www.bfilipek.com/2017/01/cpp17features.html)

Modern C++ Coding guidelines:

[https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC...](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)</comment>


Ask HN: Review this startup by a coder beginner - <AUTHOR>

The Weezic startup is developing a website dedicated to classical musicians.
They have just released a webpage to explain the concept through a video and a demo example.
http://weezic.com
I met the two founders (Nico & Greg) a few months ago. They had the project set up but needed to code it. None of them had ever coded (both having a more business-oriented background).
As experienced web developers, me and my partner advised them to code the website by themselves and we started giving Nico a few lessons and mentoring him on a regular basis.
One month later and tons of coffee drunk, Nico is now able to code like an average web developer in html, css, rails and begins with javascript and JQuery.
We would like inputs on: 1. Is it interesting? 2. How to get traction? 3. Any feedback you could have !
Thanks <comment><USER2> At first I didn't get the name, Weezic. Then when I loaded the site I realized it was a play on the name Music. I think the name is clever and catchy. Also I think that the index page looks professional enough to release to the public at this time. You guys did a good job with the looks of it.

Classical music online seem like an overly narrow a niche market, so I would say even though you guys enjoy classical, with such a catchy URL as Weezic it seems like you could expand it into other genres as you iterate.

I think your URL name right now is more valuable than the site. I think you can build a good business around it. Maybe tie the business in with Winamp somehow. Winamp /Weezic kind of works for me.

Having a musical note as part of the logo might be a positive also.

</comment><comment><USER3> Technically, not too special - ISTM they're selling convenience rather than innovation per se. Going here to get your score certainly looks more pleasant than hunting for a public domain version, though I'd miss the lack of MIDI or other alternative formats.

Marketing-wise, it's pure gold. I think they could do very well, except that I wasn't too clear on what the commercial proposition is.

<comment><USER4> Hey,

I'm the co-founder of Weezic, Thank you very much for your feedback.

The definition of the product we are trying to explain on our landing page is actually: for each work = scores + accompaniments + your interpretations. That means on Weezic, in addition to the score you get all customizable mp3 files to play your part of music, whatever your instrument is (just like you would do with MIDI generated formats but with a much better quality). In addition to the video we have a demo on the landing page: you get access to it by clicking on the 3 right menu items (I'm not sure you've seen it, it's not particularly highlighted, which could be a mistake in our design). Convenience is a good word for our starting value offer, but "Enhanced experience", although less precise, would actually be a more exact definition of what we are offering: "You're a musician and you want to play a work? You'll find it easily on Weezic with all the ressources you need to enjoy playing it: Scores, Customizable accompaniment files in high mp3 quality and other musicians to share it with".

I hope this answers your questions about the offer.

Regarding the business model, people will have to pay to access our content (scores + accompaniments, etc.) but the user-generated part will be free of course.

If you're interested in the project you can contact me at: firstname.lastname@example.com If you're in Paris, why not have a beer and discuss it in more details. Thanks again for your feedback!

ps: I hope my reply is in line with this forum's rules as I am new to this forum and new to the web dev community. Please also forgive any mistake in my english as I am French.

<comment><USER5> It took me a little while to figure out it was a practice aid. Something like - practice with a full orchestra at your own speed - would have made it clearer. The 'your interpretations' also confused me, I wasn't sure whether that referred to recordings or orchestrations.

</comment></comment></comment><comment><USER6> I really hate the video.. to much sound, so loud and after watching 10 secs with Partition __CLINGGG __I stopped.</comment>


Show HN: PropertyWebScraper – scrape real estate listings for fun and profit - <AUTHOR> https://github.com/RealEstateWebTools/property_web_scraper <comment><AUTHOR> This project started as a way to import listings into an open source website builder I created.

Right now it effectively scrapes single pages that the user provides. It won't be too hard to enable crawling so that from one page it discovers others and scrapes those too.

Will be interesting to hear if anyone has some ideas about how I could monetise it in the longer term.

<comment><USER2> Looks great -- what's best way to add new sites?

<comment><USER3> Sorry for the late reply. I've added a wiki explaining how to add new sites:

[https://github.com/RealEstateWebTools/property_web_scraper/w...](https://github.com/RealEstateWebTools/property_web_scraper/wiki/Add- support-for-another-portal)

<comment><USER2> Awesome, thanks. Best of luck with the project!

<comment><USER3> Thanks. Let me know if I can help with anything</comment></comment></comment></comment></comment>


Ultrasound-imaging-from-a-single-large-sensor - <AUTHOR> http://physicsworld.com/cws/article/news/2017/dec/14/ultrasound-imaging-from-a-single-large-sensor <comment><USER2> The actual paper is open access here: [http://advances.sciencemag.org/content/3/12/e1701423](http://advances.sciencemag.org/content/3/12/e1701423)

Even if you don't want to read the primary literature, I recommend visiting the original to see better pictures.</comment>


U.S. Mood Throughout the Day inferred from Twitter - <AUTHOR> http://www.ccs.neu.edu/home/amislove/twittermood/

<comment><USER2> Interesting. But I don't think they've chosen the best sample to work with.</comment>


Michio Kaku: These Are the Two Paths Humanity Could Take in the Next Century - <AUTHOR> https://futurism.com/videos/michio-kaku-these-are-the-two-paths-humanity-could-take-in-the-next-century/ <comment><USER2> The "PopSci" crowd is getting tiresome. Kaku and DeGrasse are modern day clerics for a new age religion.

The European Union is not new. Confederations of autonomous states have existed under the "Articles of Confederation", under the "Holy Roman Empire", and under a thousand other names. What these all have in common is the urge to federalize. Or, to use a different term, nationalize, which seems to be the boogey man in Kaku's political universe. The EU will centralize more and more authority. This will make it no more and no less a "type 1 government".

<comment><USER3> You must be mistaking Kaku for someone else... Kaku is concerned that dishonest people attempt to control masses using people like Tyson. He describes two different worlds yes, but rather one where a big government controls thought with propaganda and by manipulating science, vs one which does not attempt to do so. Kaku discusses implications of such manipulations and explorers parallels to history, while DeGrasse Tyson and Bill Nye are simply tools used to carry out those manipulations, for money. One has been driven to obscurity by the mainstream media, the other bathes in it's wealth.

<comment><USER4> I think Michio Kaku deserves a recognition for his efforts in explaining things in a way that non scientific people can understand. That's not easy. We need more like him.

<comment><USER5> The difficulty of explaining complex concepts in a way that a laymen can understand is underappreciated.

<comment><USER4> Under appreciated and much needed.

</comment></comment></comment></comment></comment><comment><USER6> The idea has been proposed in a different branding as the Great Filter (en.wikipedia/Great_Filter).

There are also other explanations as well. Maybe we're just all simulated (in an ancestral simulation). Stars and intergalactic systems are just too cumbersome to simulate all, so maybe whoever programmed us just threw their hands in the air and said "fuck it," and then make them really darn far and unreachable. It would be an entertaining thought to me at least, as a lazy programmer. Here is your 1 mile 3d viewport, anything further than that is not actually 3d but 2d bitmaps with some clever hacks that make them look like 3d to you. Fuck it, let's go bowling.

</comment><comment><USER7> Someone should have asked how is his "string theory" going? :)</comment>


Freelance Isn't Free Act Passes in NYC - <AUTHOR> https://blog.freelancersunion.org/2016/10/27/freelanceisntfreepassed/ <comment><USER2> My first freelance job was for a prestigious organization. They refused to pay, because (in their words) "no one will listen to you if you file anything anyways" and they had denied that I did the work.

I told them that they had 24 hours to pay me and acknowledge my work, or I'd put porn on their landing page. 24.5 hours later I got paid.

<comment><USER3> After I had a similar issue, I decided to offer all clients a 10% discount for paying upfront, monthly. It has the added advantage of no notice period: if they are fed up with our work they can just stop paying and we stop doing any more work.

The amount of stress that has gone from my life was totally worth the 10% discount.

<comment><USER4> After doing freelance for a while you learn to insist on an advance. The 10% discount is a great way to incentivize the process though.

Additionally, rush rates are critical. The first time I gave up a weekend with the kids for something a client "had to have by Monday" and then we monitored to see it wasn't even looked at for 3 weeks was the last. If something has to be done outside of your normal scheduling, charge a rush rate of double. When there is a cost higher than asking, it's shocking how much stuff isn't really needed by Monday.

<comment><USER5> Rush rates and their cousin, spectrum quotes. Good, better, and best tiers, with accompanying price and delivery time differences. This always helps me get a better read on the client. If they constantly choose the cheap and fast option, I know they are not going to be as profitable as other clients, so I know where to put my sales efforts in the future.

<comment><USER6> Can you tell me how spectrum quotes work?

All I found was "Inspirational Quotes about Spectrum" or some consulting companies with "spectrum" in their name.

<comment><USER5> Oh, that's just what I call them. Pretty sure there's another term because the principle is used all over the place, not just in freelancing.

When the client asks for a quote, just try adding in one extra option from your usual. They want a WordPress site? Do some research on their business and offer, for example, one quote for a WordPress site, along with another quote for standard WordPress plus a custom mobile product library for their sales team to reference when pitching products.

The client then has a choice between two really nice alternatives. You thought through their needs and they'll notice that, too.

I've found that even if the client doesn't go for the extras, they'll usually say, "let's definitely talk about this when we work on our sales budget next month. I want the team to tell me what they want." Then at that time, when they give you some bullet points for desired features and ask questions about what's possible, you reply with e.g. three options, including one that is the base price you quoted originally and covers a reasonable amount of features but is just good, plus another price point that's better because it adds another really nice-to-have feature, and then the "best" price point, where every single one of their bullet points is covered and the thing is just really slick. For example, maybe it lets them edit the product prices and save them to different lists for each sales pitch.

The point here is that you are getting a sense for what is important to the client. If you don't have many clients, the bullet points you got from that sales team are gold because you now know much more about their needs and can pitch more while working on the project.

And finally, watch for scope changes and bill for them. There are guys with yachts that were paid for by scope changes, and in fact their businesses count on those changes in order to keep the client relationship in top shape. A scope change is easy money because the client is pitching you rather than the other way around.

</comment></comment></comment></comment></comment></comment><comment><USER7> Having been in NYC nearly my whole life and the entire time seen a culture of contractors getting fucked over on payment, especially in entertainment/media/fashion/advertising, this is a great, GREAT day.

Animation studios here are among the worst. Most people I know had to fight for months to get paid and many did years of work without ever getting paid. YEARS. Like they did it for the love or something.

A few years back, a whole studio was contracted for a project and mid-way to completion the client came to them and said "I spoke to God and He told me not to do this project" and walked away from it and never paid for anything. The studio didn't even have any kind of protection against this sort of thing.

You can't imagine how bad an environment this is for getting paid for creative work. Indefinite illegal internships, lowball salaries and "for the exposure" jobs abound. Folks are so desperate to come and work here that they put up with it -- I just don't know how they afford it.

</comment><comment><USER8> FYI you can fill out a 2-3 page worksheet to file a breach of contract lawsuit in LA county.

It's not limited by small claims caps and is an inexpensive first step compared to hiring an attorney to send a scare letter.

Didn't end up needing to file the one I wrote up last year but it was liberating to know that there was a half-step measure.

Before doing it I called 12 attorneys in Los Angeles and everyone respectfully told me a $20k unpaid bill is not worth their time, but the last one told me about filing on my own.

</comment><comment><USER9> Good to see, even if it doesn't impact me. I like the idea of penalties for non-payment.

I've never had a problem collecting $5,000, but people will regularly avoid paying small amounts ($500) because (I assume) they know you won't put as much effort into collecting.

<comment><USER10> If you are collecting 5k at a time, you are doing it wrong. Your client should not be holding more than 1,000 of your money at a time.

<comment><USER11> $1000 is what a well paid software consultant makes in about a day. I can't think of a single person that does _daily_ payments for consulting, and I feel like this would be a huge red flag if they asked for it.

<comment><USER10> That's a very small portion of the market.

<comment><USER12> You aren't charging enough.

<comment><USER10> I am not talking about me, we are talking about freelancers in general. That's a huge market filled significantly with the lower end.

</comment></comment></comment></comment></comment></comment><comment><USER13> I think it's great they finally got some protection. Why wasn't it there before and what was the oppositions point of view on this?

<comment><USER14> My guess is most people thought the current small claims process would be the tool people would use. Maybe it worked when it was a small portion of the workforce, but now as more people do freelancing, it makes sense to have a dedicated state for them to seek redress.

</comment></comment><comment><USER15> This law _sounds_ good, but what kind of unintended consequences might result?

I wonder if instead of stiffing their contractors, customers will instead be the ones getting stiffed by unscrupulous contractors. I.e., contractors over- billing: "If you don't pay the amount I'm demanding, I'll report you." Companies might indeed pay the bill rather than risk a fine, but at the same time, they might become much more reluctant to hire contractors at all.

I worry that this kind of well-intentioned law will in fact reduce opportunities for free-lance people, in favor of consulting agencies.

<comment><USER16> Well, this is mainly intended to enforce contracts NOT disputes for uncontracted services so how would you be in this mode.

It will force less boilerplate contracts.

</comment></comment><comment><USER17> An indication also that self-employment is growing everywhere.In a few decades it might even be the new normal.

<comment><USER18> In tech, I think it will be a lot sooner than in few decades. I think things will change at such a rapid pace that we can't even accurately predict what will be the new normal in a few decades, particularly in tech. Also, we must also consider the possibility, and implications, of strong AI in a few decades.

<comment><USER19> I'm embarrassed to say that it took me 8 years to realize that staying at any one particular employer for "a long time", e.g. 4+ years, is increasingly an unrealistic life goal.

</comment></comment></comment><comment><USER20> Almost a decade of freelancing with customer all over the world with little more than an email exchange most of the time and I have had next to zero issue with getting stiffed. Requiring written contracts will likely force businesses to use services Freelancer.com which will just mean that instead of one on one relationships you'll be forced to compete against a pool of competition racing you to the bottom and won't get paid directly.

</comment><comment> joatmon-snoo The site itself isn't too clear about the specific benefits of the legislation[1], but the most recent committee report on the legislation is much more enlightening (the tl;dr being that it introduces powerful remedies for freelancers who are denied their just desserts - I don't understand the emphasis on the contract stuff, but IANAL):

> Any action alleging a violation of section 20-929, unlawful payment > practices, would have to be brought within six years after the acts alleged > to violate the proposed chapter. A plaintiff who prevails on this cause of > action would be awarded double damages, injunctive relief and other such > remedies as appropriate. All awards of damages would also include attorney's > fees and costs.

> Any action alleging a violation of section 20-930, retaliation, would have > to be brought within six years after the acts alleged to violate the > proposed chapter. A plaintiff who prevails on this cause of action would be > awarded damages equal to the full value of the contract. All awards of > damages would also include attorney's fees and costs.

> Section 20-934 of the chapter would provide for a civil action for a pattern > or practice of violations. Where reasonable cause exists to believe that a > hiring party has engaged in a pattern or practice of violations, the > Corporation Counsel may commence legal action on behalf of the City in a > court of competent jurisdiction. Such an action would be commenced by filing > a complaint setting forth the facts relating to the alleged pattern or > practice of violations and requesting relief, which could include injunctive > relief, civil penalties and any other appropriate relief. The filing of a > pattern or practice complaint by the City would not prohibit any complaint > or civil action by a freelance worker. Upon a finding that a hiring party > has engaged in a pattern or practice of violations, the trier of fact could > impose a civil penalty of up to $25,000.

> Section 20-935 would provide additional details about how the proposed > chapter would apply and how it would interact with other laws. Subdivision a > would provide that, except as otherwise provided by law, any provision of a > contract that purports to waive the rights granted by this chapter is void > as against public policy. Subdivision b would provide that the provisions of > this chapter would supplement and not diminish or replace any other basis of > liability or other requirement established by statute or common law. > Subdivision c would provide that failure to comply with the provisions of > this chapter would not void or impair a contract between a hiring party and > freelance worker. Finally, subdivision d would provide that nothing in this > chapter shall be construed as providing a determination about the legal > classification of any individual as an employee or independent contractor.

[1] [http://legistar.council.nyc.gov/LegislationDetail.aspx?ID=25...](http://legistar.council.nyc.gov/LegislationDetail.aspx?ID=2530972&GUID=61F8754B-80AF-493E-895E-D6D17209776E)

[2] (warning: DOC file) [http://legistar.council.nyc.gov/View.ashx?M=F&ID=4746382&GUI...](http://legistar.council.nyc.gov/View.ashx?M=F&ID=4746382&GUID=4F62986F-AFE5-4702-9CE1-CA2F40578E4B)

<comment><USER21> You can also view it on Councilmatic: [https://nyc.councilmatic.org/legislation/int-1017-2015/](https://nyc.councilmatic.org/legislation/int-1017-2015/)

Shows the same info as Legistar including all 33 sponsors and every legislative action taken over the last year.

</comment></comment><comment><USER22> > Passing with 51 votes, the Freelance Isn't Free Act requires written > contracts for freelance gigs, allows freelancers to file complaints against > non and late-paying clients with the Department of Labor Standards, and > institutes penalties against clients found guilty of nonpayment in small > claims court.

Requiring written contracts seems like a handout to lawyers. Alternatively, it seems like a clever way to enable folks with only a verbal contract to refuse to pay, since a verbal contract is now illegal.

Contracts are already enforceable at law, so how does this _actually_ improve things?

<comment><USER23> I'm Australian, the law may be different over in the US.

Usually you want a contract to specify IP rights. You own the work you author, whether you're paid for it or not, unless you specifically transfer ownership of the IP in the contract. If you're a programmer, you may assign the IP rights of the project code to the client, but only issue a non-exclusive worldwide licence to your utility code. Similarly, if you're a photographer, you still own the actual photograph, but may specify to a client how it's legally able to be reproduced. Plenty examples abound, depending on your line of work.

Mostly, I find written contracts are WAY clearer about who gets what and when, and shows the client is at least willing to "trust but verify". I wouldn't do business without them.

<comment><USER24> The law is different in the US.

If you "work for hire" (see 17 U.S.C. § 101) an exception is made to the general rule that the person who actually creates a work is the legally recognized author of that work.

</comment></comment></comment><comment><USER25> Isn't this solving the problem of short-sighted freelancers, rather than non- payment?

I see posts here that reinforce my expectation: Have a contract, and it can be enforced by law. What does this bill enable a citizen to do, that they couldn't legally do on their own before?

<comment><USER26> It doesn't actually allow them to do anything they couldn't legally do before, but it makes the penalties a lot stiffer to discourage large companies from breaking the law.

The problem before was that even if you had a contract, the company would basically say "we have a lot more to spend on lawyers than you, good luck".

Now they have changed that calculation with this law, where if the big company loses it's a huge cost to them. So now their calculation is that it is cheaper to pay their bill than to fight you in court.

</comment></comment><comment><USER27> How do we get this for California? Is the Freelance job litigated on where the Freelancer is physically located, or where the client is located?

<comment><USER28> It's where the tort giving rise to the suit happened, a question which is complicated and lawyer-worthy if this ever comes up. Most MSAs will have both parties stipulate to the jurisdiction of a particular county's courts; generally, the party supplying the MSA picks their local court system because it's cheaper to access, known to them, and has the home-field advantage.

</comment></comment><comment><USER29> Wtf is this nonsense? You want to run an independent business but you don't want the hassle of billing, just pass a law so that you dont have too!</comment>


Protecting Netflix Viewing Privacy at Scale - <AUTHOR> http://techblog.netflix.com/2016/08/protecting-netflix-viewing-privacy-at.html <comment><USER2> The two AsiaBSD papers linked from the post are good for more detail. I was a little surprised they had to hack sendfile to do the crypto in the kernel in order to get the throughput they're used to with http, but the reasons are explained in the papers.

However, I'm quite surprised Netflix went with Intel's ISA-L library for AES- GCM given Intel's perf gains were so very marginal compared to BoringSSL. I would have gone with the library that had more eyeballs on it, and in general I'd give Google the edge over writing solid, secure code than I would Intel.

<comment><USER3> I'm on the team. A few limited comments:

ISA-L: There will be some more recent results presented next week at IDF: [http://myeventagenda.com/sessions/0B9F4191-1C29-408A-8B61-65...](http://myeventagenda.com/sessions/0B9F4191-1C29-408A-8B61-65D7520025A8/14/5#sessionID=1362)

Hacking sendfile:

Note that only the bulk encryption for a limited number of ciphers is done in the kernel. All the TLS setup still happens in the userspace SSL library. So the kernel part is quite small. So it is more like hacking the bulk encryption into the kernel, not the entire library.

<comment><USER4> Have you guys ever written anything on how you configure nginx and FreeBSD in general? Would love to read more about this.

<comment><USER3> That's a great idea -- I will pass it along.

I'm afraid that most of the interesting "configuration" is to run patched kernel (async sendfile vs aio + sendfile, tls sendfile vs read/encrypt/send, etc). Of course, I work on the kernel, so I'm biased :)

<comment><USER5> > I'm afraid that most of the interesting "configuration" is to run patched > kernel (async sendfile vs aio + sendfile, tls sendfile vs read/encrypt/send, > etc).

Do you have any idea if or when Netflix plans on open sourcing tls sendfile?

<comment><USER3> It has always been the plan to upstream it. However, the patch is rather extensive, and it needs quite a lot of cleanup. (for example, making ISA-L pluggable)

</comment></comment></comment></comment></comment></comment><comment><USER6> Is protecting user privacy really the primary focus of this initiative? It seems to be another step in the multi-front battle between Netflix and ISPs:

1) Expose ISPs who limit your bandwidth to the service. 2) Protect against manipulation/degradation of the video stream quality.

<comment><USER7> Does this really solve the ISP identifying the traffic?

I suspect netflix still has limited source IPs. If you see netflix like steady bandwidth from a known netflix IP, pretty sure it would be trivial to throttle.

<comment><USER8> It is not that Netflix is being access, but what on Netflix is being accessed.

Netflix does not publish viewership information. But a large ISP could run DPI on Netflix traffic to determine what content is being viewed. And since many ISPs have their own TV product, they would be really interested in that information themselves.

But if Netflix streams at TLSed, then good luck figuring out Archer from The Lust of the Dead.

<comment><USER9> > good luck figuring out Archer from The Lust of the Dead.

Not necessarily that hard. TLS won't hide the sizes of the files being downloaded. You may even be able to estimate the size of each segment as they're downloaded, which should give you a pretty accurate fingerprint.

You'd need to spend resources to play each movie with different devices and bandwidths and record the traffic pattern, which raises the bar a fair bit.

<comment><USER10> The traffic pattern would be more specific to the playback device than the content. There might be more spread in duration, but even so, television networks like shows to go for specific times for ease of programming. As for encoding rates, it is quite possible they use CBR. Even if they use VBR they may choose different playout sources depending on the consuming devices and network conditions.

On the whole I doubt you would have a high probability of identifying any specific show. Even if you are able to cull 75% of the possibilities (i.e. 4 bits of entropy) that still leaves lots of shows (total ~1000 tv series and ~5000 movies by one source), plus all the noise of people pausing/switching, skipping credits, etc.

<comment><USER11> How big is a show, sent compressed? A gigabyte an episode? I guess the range is more relevant, say plus or minus ten megs to be conservative. I don't know how big packets are, maybe 4k is too small? 10M/4k=2.5k, not bad, but not great if you want to avoid birthday collisions, you'd only get maybe 60 uniques if they're uniformly distributed.

CBR does kill it, though, and "uniformly distributed" is too big an ask.

Off topic, but an interesting thought: you know the HBO intro? With the static? That static is the hardest thing in the world to compress, and also the thing that viewers care the least about having compressed accurately. That's weird, I wonder how true it is across the board -- certainly artifacts can be jarring in flat shaded cartoons...

<comment><USER10> 900MB for 720p for an episode of TV drama seems typical, but I haven't run wireshark on my Netflix yet.

For DSL typical packet MTU is 1400-something. Why do you ask? It doesn't really matter because the upper level proto is oblivious. You can just use b/s instead of packets/s if you want to compare bitrates.

There are special encoding modes in 264/265 for handling animation. I'm not aware if there being modes for the intro except that it is monochromatic.

<comment><USER11> > For DSL typical packet MTU is 1400-something. Why do you ask?

I was wondering how finely you can get the total filesize if it's encrypted. Can you just count fixed size packets, or can you figure the length down to the byte? Makes a big difference if you're trying using that to fingerprint the shows.

<comment><USER10> You can reassemble the https stream and get the exact length. Unless they do something weird like multiplexing, or change the playout rate, or the user pauses, it should be exact.

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER12> This is amazing. May be the paper has details on the following questions: 1\. Is the data being encrypted on the go, meaning it is encrypted as needed probably with the login user's shared key. That would explain the need for running sendfile on every video traffic packet. 2\. How would CDN caching work with this?

<comment><USER13> 1\. the data is encrypted with the established TLS session key for the current downloading session, i.e. it is indeed a per instance key. Therefore, there is no choice but to encrypt on the go.

2\. the CDN cache in fact is the place where this encryption (for the purpose of TLS) takes place. It therefore does not interfere with the CDN function.

</comment></comment><comment><USER14> DRM is briefly mentioned. But no explanation for why TLS is necessary on top of that. Is the DRM crypto cracked? Or, as they hint to, are DRM keys the same for all users ("pre-encoded") and thus identifiable?

<comment><USER10> It is pre-encoded, with a unique stream key (like a session key). The stream key is then encrypted with the public key of each playback manufacturer (multiple copies of the key, one per manufacturer) in DVD CSS. A more complicated scheme is used for Bluray which provides for unique keys for each player but without significant overhead (see [http://www.wisdom.weizmann.ac.il/~naor/PAPERS/2nl.html](http://www.wisdom.weizmann.ac.il/~naor/PAPERS/2nl.html)).

</comment></comment><comment><USER15> "Protecting viewing privacy". Yeah, right. Netflix successfully lobbied Congress to be exempted from the Video Privacy Protection Act [1], so they could monetize viewing information.

[1] [http://money.cnn.com/2013/01/10/technology/social/netflix- vp...](http://money.cnn.com/2013/01/10/technology/social/netflix-vppa- facebook/)

<comment><USER16> Perhaps there were nefarious purposes behind that lobbying.

But the stated purpose was more benign: they couldn't add "share" buttons that would let you one-click-post "I'm watching House of Cards on Netflix" because they were supposed to have written consent to release that information.

I am OK with Netflix getting permission to build useful features. And I am absolutely OK with Netflix using my anonymized viewing data to, for example, build better content predictors to make my experience with their service better.

The law protected judges with sketchy video rentals from nosy journalists. It has almost nothing to do with protecting Netflix viewers from ISP and government surveillance. This measure deals with the latter.

<comment><USER17> Playing devil's advocate but couldn't that written consent easily be included in the TOS/TOU? Not sure why they would need a legislative exemption.

<comment><USER8> Please laws over ride TOS?

Can you add a item to the ToS that says: Vendor is allowed to kill customer at any time during contract term?

Maybe that is a bad example, since assisted suicide is basically that.

</comment></comment></comment></comment><comment><USER18> The place to start for Netflix would be some real account recovery. If your account is compromised and the email address changed, they set you up with a new one instead of recovering the existing one. They also don't credit you for any time remaining on your previous subscription.</comment>


What Should Be Held Constant In Education? - <AUTHOR> http://blog.learnboost.com/blog/what-should-be-held-constant-in-education/

<comment><USER2> At the rate at which technology is advancing, I think that learning how to educate oneself is almost as important as what you learn from actually being in school. Yes you need to learn the basics, but in general I think it would be much better to teach someone how to think and learn than it would be to spoon feed knowledge. The "teach a man to fish.." line is very much applicable here.</comment>


The TPP isn't 'free trade,' it's corruption - <AUTHOR> https://www.fightforthefuture.org/2016/Stop-TPP-corruption/ <comment><USER2> It feels like confirmation bias, but every time I read about TPP, that it's blatant corruption appears to be fully known and that's why [whoever's talking] is decrying the whole thing.

I think that's half the problem though. If you're reading this you're probably informed. But this isn't frontpage stuff in newspapers. People in your local pub aren't talking about it because it "doesn't affect them".

Politicians are whipped into not talking about it by party and the "rules" about this thing. I seem to remember a video where there was a reading allowed for MEPs in the EU but it was closed, no cameras, no computers, no phones, no verbatim notes allowed. It's suppression.

It really is corruption. And unless somebody high up wakes up and says that out aloud lots, this rubbish is going to pass.</comment>


Google Chrome Canary Build - <AUTHOR> http://googlesystem.blogspot.com/2010/07/google-chrome-canary-build.html <comment><USER2> A slightly-more-frequent-dev-release Chrome which can be installed along-side a regular Chrome (stable/beta/dev). Neat. Windows-only for now, sadly.

I wonder why "Canary", though...?

<comment><USER3> Canaries were once used as an early warning system in coal mines since they had a much lower tolerance of toxic gases like carbon monoxide. A dead canary meant to "get the hell out" as soon as possible.

</comment></comment><comment><USER4> Chrome developers needs to adopt something similar to Firefox's upcoming Tab Candy feature: <http://www.dotsauce.com/2010/07/23/tab-candy-firefox/>

The app tabs simply do not compare.

</comment><comment><USER5> I like that they've broken away from the alpha/beta/RC/RTM naming conventions.

Maybe this symbolizes a shift away from waterfall software development.

<comment><USER5> I don't know why this got down-voted. It's mere speculation. If you know something about Google's software development practices that I don't, please chime in.

</comment></comment><comment><USER6> What is the current stability state of extension syncing? And is anyone working on a third party or self hosted sync platform? I don't really want or need my extension data or private bookmarks stored on Google's servers.</comment>


Show HN: An introduction to Go for C# people - <AUTHOR> https://kfcampbell.com/blog/2020/go-for-csharp-people-part-one/ <comment><USER2> C# is my goto language for productivity. If you want to lure us in, show a stereotypical example of go routines with channels solving a problem that would take significantly more effort with .net threads or .net tasks. We'll be intrigued enough to look further, and most won't stop to ask if channels seem like a recipe for deadlock/panic that's usually not the right abstraction. Don't mention the lack of generics; you'll scare us away before we get addicted to go routines.

Personally, I prefer actors over CSP. Async concurrency is less predictable, but race conditions don't generally happen when threads aren't synchronizing, so it doesn't matter if you're not making satellite firmware.

C# allows dynamic code compilation at runtime based on reflection. The cool part of LINQ is the 'Expressions', which allow you to analyze/rebuild the AST of code and take actions based on code structure. It's kind of like having runtime macros, except you can only make your own if you're willing to spend an hour doing something that would take 2 minutes in lisp. Keeps the DSLs to a minimum. I would miss this if I switched to go. Rust on the other hand...

</comment><comment><USER3> "Go places a strong emphasis on its applications staying up to date with the language, in contrast to the fragmentation in the .NET and .NET Core ecosystems"

This seems to be bit of an overstatement. C# as a language is stable and .NET and .NET Core aren't that apart from language standpoint. They had different focus through different set of built-in functionality that each framework has provided but with bit of overlap.

There are some libraries that support one but not another (although, for many of libraries, it is non-issue as they are often targeted to .NET Standard which supports both) but to call it "fragmented" sounds a bit too much.

</comment><comment><USER4> Serious question: Why?

C# is faster, more productive, has better tooling, and generics.

<comment><AUTHOR> Well, that's a highly-opinionated statement :P

The serious answer is that Go is a reasonably well-supported language at GitHub, and C# isn't at the moment.

<comment><USER5> Opinionated +1 :)

The C# compiler is called Roslyn which might not be obvious for people trying to find it on GitHub - it's incredibly well supported, regularly updated, and lively:

[https://github.com/dotnet/roslyn](https://github.com/dotnet/roslyn)

</comment></comment></comment><comment><USER6> why Go when you have C#?

</comment><comment><USER7> > Go programs compile down to a single binary with all dependencies included. > In contrast to C#, no runtime is needed, so applications may run in very > thin containers such as scratch or alpine.

This was by design and not necessarily a bad thing. C# was meant to compile to managed code for better security and performance ( JIT ) - though people can argue over the actual merits.

> Go has no generics ... You'll find yourself freqently writing small bits of > code for operations that would be trivial LINQ statements ... Go returns > errors which are then checked by the caller, rather than try/catch blocks > and exceptions for error handling ... Go has no concept of awaiting an > action (more on this later)

These are pretty important stuff that Go is lacking.

> Go places a strong emphasis on its applications staying up to date with the > language, in contrast to the fragmentation in the .NET and .NET Core > ecosystems

This isn't really much of an issue.

C# people primarily use C# to make money developing on/for the microsoft/windows ecosystem ( windows servers, sql server, IIS, sharepoint, azure, etc ). So a better way to introduce Go to C# people is to show how Go is better at interfacing with these microsoft software/servers or how Go can improve productivity within the microsoft ecosystem. Otherwise, you aren't going to have much success selling Go to "C# people".</comment>