He firstly said that Py3 sucks and he can't teach it... and now he is teaching it ;-)
It's good to see people willing to change the way they do things, especially when that means publicly contradicting their former selves and with such an intense personality. It's oddly inspiring.
Dunno if you mean his previous book or the rant where he said, among other things, that Python 3 wasn't turing complete.
Oh, I see it's been updated with a sober disclaimer now, where "In the previous version I trolled people" and "I even had a note after the gag saying it was a gag, but everyone is too stupid to read that note even when they do elaborate responses to my writing."
I read his writing very carefully. This note didn't exist.
> "Yes, that is kind of funny way of saying that there's no reason why Python 2 and Python 3 can't coexist other than the Python project's incompetence and arrogance. Obviously it's theoretically possible to run Python 2 in Python 3, but until they do it then they have decided to say that Python 3 cannot run one other Turing complete language so logically Python 3 is not Turing complete."
Even though he says it's a "funny" way to say something, his explanation of said "joke" is not a correct description of what Turing completeness is. There is no "gag" here; Zed didn't understand it, and when people on the internet corrected him, he decided to play it off as a gag.
Edit: Just to make it explicit for those of you reading who don't get it, "Turing completeness" doesn't mean "I can run a program written in X in Y's runtime." It means that a language is capable of expressing all operations a Turing machine can do, which means that you can re-write a program in X to a program in Y if both X and Y are Turing complete. You can obviously re-write a Python 2 program to be a Python 3 program, so both of those languages are Turing complete.
> "Turing completeness" doesn't mean "I can run a program written in X in Y's runtime."
That's not quite what he meant. He meant that Turing completeness of both languages implies that an interpreter for Python 2 can be written in Python 3,and that if the Python maintainers say it isn't possible, etc. etc.
Which is technically true, except that it is completely obvious that the performance of Python 2 under that arrangement would so totally suck that no sane developer would ever take that approach (and I can believe that the Python maintainers just said "that won't work" or some such), and that is what he apparently didn't understand (or is now claiming he pretended not to understand for comedic effect).
It's not the definition of Turing Complete, but it is a provable property of Turing-Completeness. If Y is Turing-Complete, then you can use Y to write an interpreter for X. Then the issue is reduced to arguing about what the word "in" means in the phrase "run Python 2 in Python 3."
Just because the maintainers of CPython 3 haven't included a Python 2 interpreter doesn't mean that Python 3 is not Turing complete. Their choice not to do that has nothing to do with the Turing completeness of anything.
Which is precisely the point that the original version of the essay was making. The joke was on those insisting that it couldn't possibly work, and the punchline was telling them "oh, so what you're saying is that your language is not Turing complete?"
Ok, maybe that doesn't follow the format for a classic joke, but it's certainly a humorous and sarcastic remark.
That is, why can't the cPython3 implementation of the python3 language also execute python2 code? To which I think the simplest response is "why can't the gcc implementation of the C++ language spec link arm-compiled C++ and x86-compiled C++?"
That's why Z thinks of this as a joke, not a straight-face assertion.
What those of you repeating this interpeter thing are missing is that there's a four term fallacy being employed here. Zed is trying to make an argument of the form:
If A, then B
If B, then C
Not C, therefore Not B
But in reality his argument is:
If A then B
If B, then C
Not D, therefore not B
If A, then B.
If B, then C.
Some people insist that not C, therefore they are unknowingly implying not B.
But you have several comments dismantling an strawman version of the real argument, so it looks like you really didn't understand Z's intention.
His comment about people "failing to [in this case, understand] that note even when they do elaborate responses to [his] writing" looks dead-on.
Pro-Tip: They're straw men. Even if you find examples of people asserting that after the fact, the undentified parties asserting "Python 3 cannot run Python 2" in the way that Zed claims he's responding to, are only mentioned in this rant to make Zed look smarter than he is.
This is true, but the converse isn't true. e.g. Python and brainfuck are both turing complete, but Python has interfaces around a hell of a lot more syscalls than Brainfuck which only has operations for reading and writing from stdio. You can't write a Python implementation in brainfuck, it is impossible.
There's a difference between "impossible" and "really difficult giant waste of time" here when it comes to discussing Turing completeness.
Of course, syscalls are not related to Turing-completeness in any way. Turing-completeness means that the language can express any computation which is possible to do on a Turing machine. Turing machine computations can not have any side effects, and syscalls are a kind of side effect. Therefore, having syscalls is not necessary for a language to be Turing-complete.
If only there were a machine with which we could go way back:
Yes, that is kind of funny way of saying that there's no reason why Python 2 and Python 3 can't coexist other than the Python project's incompetence and arrogance. Obviously it's theoretically possible to run Python 2 in Python 3, but until they do it then they have decided to say that Python 3 cannot run one other Turing complete language so logically Python 3 is not Turing complete. I should also mention that as stupid as that sounds, actual Python project developers have told me this, so it's their position that their own language is not Turing complete.
Edit: I'm mistaken, however I'll say what I said then again:
The note does nothing to show that he actually understands the statements he's making. The note gets the definition of turing completeness wrong too.
But regardless, it doesn't change the fact that Zed wrote as if didn't know what he was talking about.
"Yes, that is kind of funny way of saying that there's no reason why Python 2 and Python 3 can't coexist other than the Python project's incompetence and arrogance. Obviously it's theoretically possible to run Python 2 in Python 3, but until they do it then they have decided to say that Python 3 cannot run one other Turing complete language so logically Python 3 is not Turing complete. I should also mention that as stupid as that sounds, actual Python project developers have told me this, so it's their position that their own language is not Turing complete."
I moved from Python mostly to using R, Racket and Haxe for my other side projects. This infighting just left a bad taste in my mouth and started seeing greener pastures, which for once in my life were in fact greener. I still love Python but I don't use it much due to community drama.
I find it hard to believe you're citing a book that was published in 2012, when it made sense to still target Python 2, as relevant to today's argument. The new version is updated for Python 3.5.
I agree with you totally.
Sometime between November 2016 to today he decided to release a Python 3 version.
I mention that the original idea that Python 3 was not a good practice in 2010 and was the majority view and again in 2012 a major library was released with Python 2 as its main target with the majority of the community was fine with the Python 2 focus.
Why am I making no sense time line?
I like Zed Shaw as a member of the Python community and I was defending his stance on sticking with Python 2 (I personal supported Python 3 since announcement)
So what is you agree and disagree with totally?????
I agree with you though, it's what got me looking towards other tech like Node, Go, Elixir. I can look past it all except for the fact they got 'unicode by default' wrong. They should simply do what Go does, everything is a bytestring with assumed encoding as UTF8. What they have today is ridiculous and needs changed before I could embrace Python3+.
They supported python 2 for years and year after the release of this, don't know how you can even mention the word goosestep in this context.
Python2 has unicode support. Python2 already had (better) async IO with Gevent (Tornado is also there). There's just nothing there with Python3 except what I can only describe as propaganda from the Python Software Foundation that has led to outright ignorance with many users.
Some people wanted "unicode strings by default". Which Python3 does have, but they even got that wrong. The general consensus on how to handle this correctly is to make everything a bytestring and assume the encoding as being UTF8 by default. Then like Python2, it just works.
Whose "general consensus"? It's certainly not the approach adopted by the vast majority of mainstream general-purpose programming languages out there.
But if you were to find any sensible designer of new language with skyrocketing, runaway popularity- such as Rob Pike, they'll tell you differently. Or even Guido van Rossum, if he were to be honest with you. While Pike's colleagues at Bell Labs like Dennis Ritchie may not have designed C this way for obvious reasons, they did design Go that way.
Aside from Go, can you give any other examples? Swift is obviously in the "new language" category (more so than Go, anyway), and yet it didn't go down that path.
If you know anything about Swift, it was designed with a primary goal to being a smooth transition from and interop with ObjC so like other legacy implementations (such as CPython3), it had sacrifices that limited how forward-looking it could be.
I want my strings to be strings - that is, an object for which it is guaranteed that enumerating codepoints always succeeds (and, consequently, any operation that requires valid codepoints, like e.g. case-insensitive comparison, also succeeds). This is not the case for "just assume a bytearray is UTF-8 if used in string context", which is why I consider this model broken on the abstraction level. It's kinda similar to languages that don't distinguish between strings and numbers, and interpret any numeric-looking string as number in the appropriate context.
FWIW, the string implementation in Python 3 supports UTF-8 representation. And it could probably be changed to use that as the primary canonical representation, only generating other ones if and when they're requested.
Thus Go's strings don't potentially fail your desire for a guarantee anymore than anything else would assuming UTF8. They're unicode-by-default, which was the whole point to Python3 but Go has it too in a more elegant way. That's the beauty to UTF8 by default, you can pass it valid UTF8 or ASCII since it's a subset, the context of which it's being received is up to you. If you're expecting bytes it works, if you're expecting unicode codepoints that works. There's no reason to get your hands dirty with encodings unless you need to decode UTF16 etc first. If there is still a concern about data validation, that's up to you not your string type to throw an exception.
This only works in one direction. Sure, any valid UTF-8 is a bytestring. But not every bytestring is valid UTF-8. "Use interchangeably" implies the ability to substitute in both directions, which violates LSP.
> What comes in, comes in. Validate it elsewhere.
I have a problem with that. It's explicitly against the fail-fast design philosophy, whereby invalid input should be detected and acted upon as early as possible. First, because failing early helps identify the true origin of the error. And second because there's a category of subtle bugs where invalid input can be combined or processed in ways that make it valid-but-nonsensical, and as a result there are no reported errors at all, just quiet incorrect behavior.
Any language that has Unicode strings can handle ASCII just fine, since ASCII is a strict subset of UTF-8 - that doesn't require the encoding of the strings to be UTF-8. For languages that use a different encoding, it would mean that ASCII gets re-encoded into whatever the language uses, but this is largely an implementation detail.
Of course, if you're reading a source that is not necessarily in any Unicode encoding (UTF-8 or otherwise), and that may be non-string data, and you just need to pass the data through - well then, that's exactly what bytestrings are there for. The fact that you cannot easily mix them with strings (again, even if they're UTF-8-encoded) is a benefit in this case, because such mixing only makes sense if the bytestring is itself properly encoded. If it's not, you just silently get garbage. Using two different types at the input/output boundary makes it clear what assumptions can be made about every particular bit of input.
And yes, you're right that Python is probably not a good example of ideologically pure fast-fail in general, simply because of its dynamic typing - so that part of argument is not really strong in that particular context.
(Side note: don't you find it amusing that between the two languages that we're discussing here, the one that is statically typed - Go - chose to be more relaxed about its strings in the type system, while the one that is dynamically typed - Python - chose to be more strict?)
The key takeaway, I think, is that there is no general consensus on this. As you say, "this is a longstanding debate within the PL community" (and not just the topics we touched upon, but the more broad design of strings - there's also the Ruby take on it, for example, where string is bytes + encoding).
My broader take, encoding aside, is that strings are actually not sufficiently high-level in most modern languages (including Python). I really want to get away from the notion of string as a container of anything, even Unicode code points, and instead treat it as an opaque representation of text that has various views exposing things like code points, glyphs, bytes in various encodings etc. But none of those things should be promoted as the primary view of what a string is - and, consequently, you shouldn't be able to write things like `s[i]` or `for ch in s`.
The reason is that I find that the ability to index either bytes or codepoints, while useful, has this unfortunate trait that it often gives right results on limited inputs (e.g. ASCII only, or UCS2 only, or no combining characters) while being wrong in general. When it's accessible via shorthand "default" syntax that doesn't make it explicit, people use it because that's what they notice first, and without thinking about what their mode of access implies. Then they throw inputs that are common for them (e.g. ASCII for Americans, Latin-1 for Western Europeans), observe that it works correctly, and conclude that it's correct (even though it's not).
If they are, instead, forced to explicitly spell out access mode - like `s.get_code_point(i)` and `for ch in s.code_points()` - they have to at least stop and think what a "code point" even is, how it's different from various other explicit options that they have there (like `s.get_glyph(i)`), and which one is more suitable to the task at hand.
And if we assume that all strings are sequences of bytes in UTF-8, the same point would also apply to those bytes - i.e. I'd still expect `s[i]` to not work, and having to write something like `s.get_byte(i)` or `for b in s.bytes()` - for all the same reasons.
On the consensus on bytestrings assumed as UTF8, there's only 1 new language without legacy baggage that has skyrocketing popularity and it has bytestrings assumed as UTF8. Everyone I've surveyed says that's no coincidence, including members of the Python core dev team. So that's where I'm seeing consensus on the string issue. While Python3 has struggled and folks are rightly irritated. Because some were irresponsible everyone has to pay, that's not really how I viewed Python's strengths prior to 3.x. Zed said it best but it really was one of the best examples of how dynamic typing can be fun.
I've read that before and the author is ignorant. He's parroting GvR & the CPython core development team's line that unicode strings are codepoints. Sure, but he's arguing with himself and note the argument is Python2 vs 3. That narrow focus is what results in his tunnelvision. As a result of the argument as he frames it, Python3 is not better than Python2 in string handling, it's merely different. One favors POSIX (Linux), Python2. One favors the Windows way of doing things, Python3.
There is an outright better way to handle strings. It's what Google did with Go. How do we know it's better? Well, it is because it makes more sense on technical merits and members of the CPython core dev team have admitted that if Python3 were designed today they would go down this path. But during the initial Python3000 talks this option was not as obvious. Bad timing or poor implementation choices. Take your pick, given the runaway feature-soup that Python3 has become I'd assume both.
So like all tech, let Python3 live or die on its technical merits. That's exactly what the PSF has been afraid of, so we have the 2020 date which is nothing more than a political stunt among others. Python3 is merely different, it favors one usecase over another, but did not outright make Python better. To break a language for technical churn is and was a terrible idea.
Honestly, I don't care a great deal about string handling in Python and just wanted to inject (what I thought was) more information into the discussion. I'm kinda regretting that now. Lesson learned: steer clear and leave it to the experts.
I'm curious, how does Go handle strings?
Go handles strings by having strings be like Python3's byte-strings and unicode-strings as one type. This enables code to be written that generally doesn't force you to very often think about encodings, which you shouldn't have to as UTF8 is the one true encoding. Or litter your code with encode/decode, or receive exceptions from strings (see Zed's post on some of that) where there wasn't previously. Python3 solved the unicode emojibake mixing unicode and bytes problems that some developers created for themselves in Python2, but did so by forcing the burden to every single Python3 developer, and breaking everyone's code while simultaneously refusing to engineer an interpreter that could run both CPython2/3 bytecode. Which is possible, the Hotspot JVM and .NET CLR prove it. Shifting additional burdens to the developer in situations where it's necessary, makes sense. It wasn't here because of both Python's general abstraction level, and Go showed it can be solved elegantly. Strings are just bytes and they're assumed to be UTF8 encoding. Everyone wins. Only Windows-specific implementations like the original .Net CLR shouldn't be UTF-8 by default, internal and external representation. Only a diehard Windows-centric person would disagree or someone with a legacy implementation (Java, C#, Python3 etc). The CPython3 maintainers fully admit they're leaning towards the Windows way of handling strings.
As you know, handling text/bytes is fairly critical and fundamental. For Python3 to get this wrong with such a late stage breaking change with no effort to make up for it with a unified bytecode VM is unfortunate. Add in the feature soup and the whole thing is a mess.
"Learning Python 3 is not in your best interest" REALLY? Learn Python 3 and you can work your way around Python 2 code if needed (except for Unicode problems which are tough even for people accustomed with Python 2 and which is a sore thumb that needs to be fixed hence Python 3)
Yes, I though Python 2 was good and Python 3 was irrelevant. That was 5 years ago though.
Reading stuff like "The fact that you can’t run Python 2 and Python 3 at the same time"? Really? Fake news anyone?
It is possible and several people do that. Period
Making and promoting a controversial rant, then a couple months later making news by reversing his position? That's pretty much Zed's m.o....
Wait, is this seriously the only advantage you see to Python 3, Zed?
Strings are ubiquitous to programming. I'd argue that it's even more for first time programmers. Zed wanted something that would be easy to use.
(ASCII) Strings formatting is more important to beginners than unicode support, new style classes by default, iterators in range()/enumerate()/etc. , the new division operator, etc.
I haven't recommended his book to beginners because it was stuck in Python 2. But I have to agree that Python 2 had some stuff that was more "newbie-friendly" than Python 3
> But I have to agree that Python 2 had some stuff that was more "newbie-friendly" than Python 3
Also I suspect that a huge proportion of newcomer's got very confused as to why 3/2 == 1.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
I love iterators, but they're not an obvious concept at first.
print thing # Works in Python 2
print(thing) # the parenthesis are optional in Python 2
print(thing) # the parenthesis are required in Python 3
If you try to do something like "print(thing1, thing2)" in Python 2, you'll find that "(thing1, thing2)" is interpreted as a tuple, so Python prints it as a tuple (instead of printing thing1 and thing2 individually).
Of the top of my head come the range/enumerate/zip returns. They are really useful and needed to teach "pythonic Python". But it's hard to explain that it doesn't return a list. "It returns an iterator, that is lazy, and you need to call 'list()' on it to use it as a list..." You get my point.
You fall to a "just do like I told you. You'll get it later." that plagues a lot of other languages when being taught to newbies.
But I never said that Python 3 is less "newbie-friendly" than Python 2...
The explanation is easy, but it isn't simple.
With respect, "It always rounds down" is a terrible explanation. It explains the apparent behavior of the / operated in Python 2, but it does not really explain why. A better explanation is that the Python is both dynamically- and strongly-typed and that / does integer division on integers and "true" division on floats. For the newbie who understands these concepts, this is a far more useful explanation and metaphor; and for the newbie who doesn't, he has to learn somewhere, and frankly the / operator is not a bad example.
Floats don't really get true division either:
And as it happens, I once explained a related problem with round() to Zed Shaw on Twitter:
(and from playing around with Perl 6, I love how decimal literals are of type Rat instead of Num; I wish Python decided to do something similar in Python 3)
Edit in response to Zed's question, in 3.6 I always just do:
For purposes of teaching the language to a beginner, he wants literals being rounded or divided to "just work" in a way that is unsurprising to those beginners, and there isn't any way to achieve that unless the default type of a number with a decimal point is Decimal rather than float (which isn't at all likely to happen).
The closest we are likely to get to that ideal is by introducing a Decimal literal like 0d2.125, riffing off the Hex and Octal literals (eg. 0xDEADB33F, 0o76510).
P.S., unless I am mistaken, you're just truncating the float, not actually rounding it
And I understand that it is hard for some to jump back to a newbie perspective. Some people look for performance in a programming language. Others for a thriving ecosystem. I look for usability and elegance. So I tend to look at programming languages that way.
Unless any fork actually gains traction, Python 3 will be Python in 2020.
I've been writing Python for over a decade, I dragged my heels on Python 3 for a long time, and as soon as PEP 498 came out, I decided then and there that all new personal projects I start will use Python 3, and I'll try to use 3 if I can in new work projects.
Not only that, but I've fallen for f-strings so hard that all my newer personal projects specifically require 3.6.
Their unicode implementation is sub optimal at best, it doesn't need to be so complex. They need to go back to the simplicity of Python2's strings but modernize it. Make everything a bytestring and assume the encoding is UTF8. That's what everyone else is standardizing on.
> Suppose we want to simulate and plot the white noise process ε0,ε1,…,εTε0,ε1,…,εT, where each draw εtεt is independent standard normal
Can anyone suggest something similar for learning Scala?
>> Coursera course by Martin Odersky
Unfortunately, the next one in the series is not nearly as good.
Granted, this was for a Big Data class at the university level that was covering Spark and Scala mostly. However, I remember the book to be very clear and digestible.
If you're a purist and don't want to maintain your own build of Python (or trust an external PPA), I'd aim at 3.5.
That said, this is about learning... But you'll need to learn not to use f-strings if you want to use it on a current-generation LTS distribution.
I'm a strong believer in de-coupling base system and application deployment.
And if you're a CentOS user, you can get newer Python releases from https://www.softwarecollections.org/en/scls/?search=python (an official Red Hat project)
As someone who's used Go and who has some mixed feelings about it, I'm curious -- what do you find flawed in it?
* Package management
* The weird and approach to exception handling (which leads to overly verbose code)
* Lack of generics (which leads to overly verbose and somewhat hacky code)
* Vastly smaller 3rd party ecosystem
I think it works well for a very small subset of sysops-style problems (small servers, small command line tools, etc.) especially since it easily compiles into one small, portable binary, but outside of that it flounders.
For most technologies (with some notorious exceptions) that boils down to a matter of opinion an intended use cases.
And with python (or interpreted langs in general) you gain a repl, a shorter write -> compile -> test loop, and generally speaking a higher rate of development.
I'd agree though, I do want some way to deploy a "python binary" that isn't essentially a virtualenv.
Like I said, it depends on the application. For numerical-heavy code, where you're going to be using numpy hooking into MPI or LAPACK, C or similar code will win, it takes more advantage of things.
For more complex code, say a webserver, pypy can compete and win, because pypy gets the advantage of, after the jit warms up, essentially profile guided optimization, which means that pypy can, assuming there's some kind of loop (there always is), optimize the hot code paths, and the surrounding code to abuse hot code paths, and it can optimize the hot code paths really really well, better than gcc could normally, because it has additional information (pypy knows how the code is being used at runtime, whereas gcc only knows what information is available to the compiler: types and directives really).
Python is wildly popular now, and it is great for small scripts and interactive data analysis, but I don't see any real long-term strengths. It is not growing and is very slow in comparison to most languages. There are soooo many interesting projects out there. Perl6 is very immature from an implementation perspective, but is just as easy to use as Python, but has waaay more power and flexibility under the hood. The OO model is more advanced, the semantics are clean and elegant, you can do real FP, easy asynch based off of C#, grammar based programming...etc. Python can do a lot of that with modules, but having it all in one consistent package is nice. On another note, there are sooo many languages that although maybe not as flexible as Perl6, they run blazingly fast. Think of Crystal (Ruby syntax with native speed and no dependencies), Dlang, Go, Rust, Red (fast and dynamic language in a 1.3 MB runtime...you can even access a systems language DSL...the best GUI system I've ever seen). So basically we have new languages that have the advantage of an easy syntax like python, but are waaay faster and not mostly locked in place (Guido doesn't like feature bloat). There is also Elixr...etc. Python isn't dead, but I don't think a JIT is enough at this stage and I'm mostly moving on. Python's hold on scientists is being challenged by Julia which will be just as easy to use, but also once again...much faster. Let's not forget that C# is actively maintained by a large and very well funded team at Microsoft and is constantly adding new features like LINQ and now things from F#, which is a great language on its own. I don't take Haskell seriously. Note that I think it is very advanced and can be quite fast, but it is also very hard for most people to understand things like Monads (just Monoids in the category of Endofunctors...wtf) or Currying...etc. I expect Python to remain around for a very long time (you can still find Cobol at banks and I rely on Fortran every day, but I really hope it is not still in the top 5 on the Tiobe in 10 years unless Python 4 is a rewrite from scratch to have a few more features and run on LLVM...oh wait we already have Nim that is basically Python syntax transpiled to C & then compiled with gcc or clang to get ~40 years of optimizations.
My uses for python are data analysis, helper scripts, command-line apps, glue on Linux servers, glue on windows where it acts as a better CMD (I've tried powershell, but I don't gain much and often lose in speed as 8/10 ways to do something work, but are dog slow).
The bar is large open source projects, which indicates that it's very easy for a drive by developer to isolate a bug and fix it or implement a feature.
Latin is a dead language and no one speaks it. Sure it is helpful for understanding other languages, but I never got that comparison because the computer always speaks it.
Certainly imperfect paraphrase, but the crux is that you can always code python, or lisp ect.
People usually think that costs nothing, until they get bitten by it.
And then people attempt to troll him saying he doesn't know what Turing complete is. Perhaps they really don't understand what they're even responding to, that's what it appears. Or it's just a willful attack because they "like Python3". Unfortunately with Python3 this is what the Python community has been slowly devolving into, what comes off as a bunch of trolls/kids or ridiculous adults.
2. Zed can troll people, and that's totally OK, but the "like Python 3" people can't troll him or counter-troll him, because it's turning the Python community into trollville. I'm guessing like sort of how Rails is a ghetto.
See the user of this parent comment.
This is the first thing I get when searching "Learn python3 hard way" in Google. Maybe it's time to update this page :)
I didn't enjoy the python2 book too much, but I'll give this one a try.
Dive into Python 3 is a good book. I used it to supplement my CS classes in early college. There are some other good book suggestions on the sidebar of https://www.reddit.com/r/Python/ . In particular, I've heard good things about "Automate the Boring Stuff with Python".
so to be clear, is the online version complete, and only the pdf and videos are missing, or even the online version is still work in progress
I wouldn't recommend learning Python at this point with the 2/3 split and uncertainty. If you must learn Python I'd learn 2.7. Reasoning is that almost all the jobs are Python2 still. There's just so much code out there based on it and you're almost certainly going to have to use it anyway. Don't listen to the haters, it's what will pay your bills. Move to Python3 when/if your job does. They'll probably move to Go instead.
For hobby work not remotely considering a job? Then learn Elixir.
I answered his question on 2 vs 3 if you read what I said.
Numpy is carrying Python, and its competitors are thin. There's Julia, but that's not really ambitious enough compared with Numpy to be worth moving to. There's Scala though then you need to love the JVM. Lua had promise as a nice and tight, pragmatic and fast language, but it seems to have missed its window of opportunity. What else? I'd genuinely like to know. Ideally I'd like something that's got a functional programming flavour but that also data-parallel, almost R-style, by default, so as easily able to target the GPU. I took a look at futhark but it seems too experimental, as does Ocaml/spoc combo. I am taking a serious look at the probabilistic programming area with Edward or Stan, but then we're back to Python front ends.... Actually I did look at Swift which does c-class speed with an official REPL but an apple-supported language may not attract the science/ML crowd. Meantime rust is REPL-less for now...
"This post is an interesting approach to B. I have looked in to A and B, but if you could explain why you chose A or B that would be helpful"