forgiving yourself is part of “being real” about life

for the record, this is supposed to be a blog about programming. and theres a lot of stuff here about that; in the previous entry i linked to an entire book about it: https://codeinfig.wordpress.com/2016/11/28/a-note-to-anna-and-a-link-to-the-book/

i started blogging in february, and it is now november; and as i get to know the community better, two things have happened: one, people are interacting with my blog more than ever. and two: its extremely tempting to talk about other subjects.

this isnt just because i have other things i want to say; its because i have people to talk to here on wordpress that make me think of other things i want to say. this will be one of those instances.

true forgiveness is always difficult– there are plenty of people with no awareness of the unnecessary pain theyve caused others (or themselves) that find it easy to “forgive” themselves for just about anything; theyre not really doing it, theyre just ignoring the thing they did or the effect it had. forgiveness doesnt have to linger or dwell on the past, but it probably has to face it to move on.

anyone who has dealt with substantial guilt has likely spent at a least a little time beating themselves up, in some fashion. its human, its natural, and to the person doing it, it just makes sense.

but to mistake the guilty you for the “real you” or the guilt for “reality” is ultimately a mistake. to drag your unhappiness with yourself (for something in the past) along as some kind of companion year after year, wont just drag you down and make great friendships impossible; it makes having a realistic perspective impossible.

who you are is shaped by your past. but your past does not (and should not) continue to shape you forever– especially the worst things you can find to criticise. the way mistakes in the past should shape who you are in the future is more like this:

  1. past mistake leads to life lesson
  2. life lesson leads to self-improvement (however gradually it may lead to it)
  3. life lesson and practice of self-improvement leads to continued betterment

 

i had to run “betterment” through a spell-checker. hooray! its a word.

if you are the sort of person who beats yourself up over every past mistake you can think of, here is what happens to the above process:

 

  1. past mistake leads to guilt, which discourages or diminishes the lesson
  2. guilt leads to anguish and self-pity
  3. guilt and anguish and self-pity prevent you from betterment

 

in many or most cases, guilt should be a stepping-stone, but not a stone around your neck. if you are too weighed down by it, you will never be able to lift up anyone else. your guilt will cost others, and it will cost you more than it needs to or should– but also, it will feel so real while creating illusion in your life.

you are not the sum of your mistakes. you are the sum of the lessons you have learned from your mistakes.

life is full of mistakes and guilt and unhappiness. it is also full of lessons and forgiveness and happy moments.

certainly some of us (trust me, this includes me) have lost a day or more to being terribly unhappy, or lost some happy moments to dwelling on the past mistakes of ourselves and others.

but subjectively picking out the worst misses an important part of reality– whether talking about life, or who we really are. you cant beat yourself up all the time, and also know who you really are. it will prevent you.

the practice of (truly and honestly) forgiving yourself and the practice of forgiving others is also the same practice. if you do not learn the importance of moving on from past mistakes, you will always hold other people to unfair standards.

simply for the sake of treating other people fairly, it is important to gradually let go and move on from the guilt you have about mistakes long since past. not dwelling on your imperfections and things you did long ago will actually make you a better person.

facing your mistakes, and being honest about them, may cause guilt. thats better (for you, and for the world) than never acknowledging your mistakes at all. but finding too many things to feel guilty about, or feeling disproportionately guilty, for too long?

theres simply no good in it. if not for yourself, then for the people you care about: learn to let go of those things. youll be happier, youll be better– and youll be a more fair and more realistic person. these are only good things.

 

 

(part of the reason i license the blog this way, is to let you know youre free to copy it in whole or in part, and even to change it, anywhere or in any way you like. thats what the license says but i also point it out in this note here, in case youd like to do so.)

a note to anna (and a link to the book)

please, skip the introduction! feel free to skim it– or go over it when youve read the rest– but its the biggest reason (apart from a few typos and minor layout issues) that i call this a draft version.

the pdf is here -> https://codeinfig.files.wordpress.com/2016/05/figbook10chdraft.pdf and please feel free to use this page for any comments, questions, and totally free support for the related programming environment if you should ever need that.

its all in the public domain and on the internet archive, etc. but its still designed around someone being around to help install software and answer questions– such as a tutoring-type setting.

hello

for those just joining– a little about my work so far

since around the first years of school, ive been a philosopher, student and programmer. granted my programs up until age 10 were not much, but i was teaching myself with one or two books. i even taught myself how to write programming languages, and i can teach you the same.

in terms of philosophy, i declared myself an atheist at the age of 4. i didnt know the word, i grew up in the bible belt, but i was never pushed to go to church (or reject it, or to be agnostic, or anything.) i loved science, and it simply didnt jibe with this hand-wavey spiritual business (which i would come to accept at least in part, later on.)

at about the age of 4 is when i started using computers as well. its a fact that i was a bright kid. but i could show anyone how its done, explain it in plain terms (to anyone interested) and by the time i was in my 20s i was showing my best friends 7-year-old how to type in basic programs. if you really want to understand, dont just read them– type them in!

unfortunately, basic and programming have gotten a lot more complex. and by “a lot more,” i mean its optional. but unless you know a lot about computer languages, you simply have the whole thing dumped on your lap with no idea how much of it is optional and how much of it you must learn in order to understand the gist of the thing.

enter basic, in 1964.

basic was created in hanover, new hampshire to take the esoteric discipline of computing and make it conceptually accessible to everyone on campus. it was so wildly successful, that by the 1970s it had spread to secondary schools who could access the dartmouth timesharing system (dtss) via teletype, and basic for the altair 8800 was the original product microsoft was created to sell. there are several videos of an altair running basic on youtube:

another computer language from the 1960s to take over the world of education was logo, which is actually a full-featured programming language but you will probably only see it used to move a cartoon turtle around the screen, drawing colorful lines in its path. in some logo-inspired dialects this part of the language could not be easier:

u 40 l 40 d 40 r 40

 

in english: “draw upwards 40 points, draw left 40 points, draw down 40 points, draw right 40 points.”

this creates a square on the screen.

the problem with logo and most of its descendants is that it starts easy and becomes very complicated or esoteric very quickly. or alternatively, it starts out easy and becomes very cumbersome– you may never get past moving a turtle (or cat) around the screen, which makes it difficult to introduce logo to adults.

but in the 80s the way computing was taught to children and adults was to get them into typing itself, then into typing basic programs or exploring with logo. as the 90s gave way to training with applications and using tools online, we stopped exposing students to the very essence of computing. instead of understanding code as the building block of all software, we operated on the idea that showing how to click on magic boxes was like teaching someone to fish. but clicking on magic boxes will teach you nothing about fish, or about fishing; a better metaphor for 90s computer education is “teaching someone how to buy and eat a fish.”

fortunately we are in a new era of single-board computers like the beaglebone, odroid-x, or raspberry pi, and once again students are learning some very familiar lessons. they are using powerful and flexible languages like python and javascript, but ive tried teaching both of these languages and to be honest, they are so complex that unless youre committed to learning them they will not hold your interest.

this is not to disparage python– i coded in basic for 25 years and spent about 5 of them looking for the “basic of the 21st century” and came back from that quest with python itself. (a note to python 2 fans: i am referring specifically to python 2.)

but to share the joy and simplicity of basic, i spent a year working on a new language, which is inspired by basic and logo with a few cues from python, as all of these languages have their own nods to ease and simplicity.

from python it takes lists, which are like basics arrays but they do not restrict each array to “just strings” or “just numerics.” in python and fig, you can mix the two types.

from logo it takes the simplicity of syntax, which rivals basic and python in what you do NOT have to learn. want to create a variable “x” that is equal to 5? here you go:

x 5

 

done!

but wait, you keep hitting equals (or you want to bring back the := for assignment?) voila:

x = 5
x=5
x := 5
x:=5

 

they all work.

for most of history, basic was not case-sensitive. python is. no problem:

X=5
p=x : PRINt

 

it works! and the colon : is optional. as in logo, you can use space, or you can use a semicolon, or a pipe:

X=5
p=x print
p=x ; print
p=x | print

 

the reason for this is that sometimes these syntax elements will provide valuable visual cues. but fig ignores most of them. it still pays attention to quotes:

now "hello, world!" print

 

that sets variable “now” to “hello, world!” and then prints the variable. qbasic has a ucase$ command, and so does fig:

now "hello, world!" ucase print

 

that prints HELLO, WORLD! instead.

fig goes left-to-right, because the last time i showed basic to a friend of mine, she told me “its too much like math.”

well of course it is. but i thought if it was more like english, that might help people learn how to code for the first time. want some more features? fig has about 100 commands. and one of those allows (tada!) inline python code:

function funkyfunky p
now #you have to create it in fig to call it in fig
fig

python
    def funkyfunky(p):
        if p == 3: print "yeah!"
fig

now funkyfunky 3

 

in that example, the python code isnt necessary, just a demonstration:

function funkyfunky p
    ifequal p 3
        now "yeah!" print
        fig
    fig

 

python indentation is great– but i know people that really have trouble with it. fig uses pascal/basic/bash-like commands instead of indentation or braces:

function funkyfunky p
ifequal p 3
now "yeah!" print
fig
fig

 

the “fig” command is like unindenting in python, and also returns from inline python to, well… fig. in many cases you can use basic-like “next” or “wend” for aliases. if you like bash, then “fig” is one letter different than the “fi” command.

this year i wrote a book that pretty much explains the entire fig language, which (like fig itself) is in the public domain.

if you want a nifty live gnu/linux distro that features the fig language, there is fig os, or you can look at this review on distrowatch of the first operating system distro to include the fig language– refracta:

http://distrowatch.com/weekly.php?issue=20161017#refracta

refracta is based on the “devuan” fork of the software they run on the international space station. because i havent found a screencap of fig running in refracta, here is one of it running in devuan:

prs

 

i designed fig as a teaching tool to make it so anyone can learn to code. if you didnt learn fig, i would recommend python, or javascript. each one has its advantages, but i designed fig to make it easier to learn a language more or less in its entirety. that was possible with basic in the 80s, and is now possible with fig today.

i use fig to teach programming, but i would like to do that more often. i would also like to teach people how to create their own programming language.

the hardest part of creating a programming language is writing a program that can parse code. figs left-to-right parser demonstrates how a useful language can be parsed fairly easily. if fig were more strict and required syntax between commands, it could be parsed even more easily.

i have tried to create a recursive parser (the kind that makes a language “too much like math” in my friends words) on a few occasions, and i know its something trivial that im not doing, because ive seen them work.

you dont ever have to write your own parser to create your own language. certainly it can be fun and rewarding, but whether you modify an existing parser or use a parser generator, not every language has its own parser– you can find tools for creating them in c, javascript, python and even php.

why more languages? so we can get closer to making languages that truly anyone can learn. basic, logo and fig are really good for that, in my opinion. python isnt bad for it. fig is the most ambitious language project ive ever worked on, but i wouldnt mind participating in the design of another one.

because its written in python, fig runs on most gnu/linux distros, windows, mac os/x, android, bsd, and some other operating systems that are capable of running python.

 

 

when programmers get it right (…the first time)

chances are, im going to say a number of things that that author of the blog entry im critiquing will readily agree with. either way, there are so many things you could say about it.

if this sounds like a defense of programmers, or bugs, its far from it. but lets start with this tagline from the blog itself:

Technology should work for you. No excuses!

the core of my complaint is part of the reason i cant stand most peoples “solutions” in the first place– and there are millions of people living in similar circumstances. we (such people) have sufficient understanding of the underlying “thing” that– while most of us are far from the scientists a casual observer may have us pegged for– we can moan about the shortcomings of our tools and sometimes even fix them!

therefore, this is not just a critique for its own sake. but lets get to a quote of yesterdays entry itself:

Technology makes our lives better to the extent we don’t have to think about it.

well, sure. i mean if i had to write a pdf viewer (or drive to the library) every time i wanted to read a book, i would probably read fewer pdfs, or books. its easy to dismiss this as laziness, but the bottom line is: putting such things into our periphery lets us pay attention to other, hopefully more important things. thats productivity in a nutshell, and a lot of things designed for that purpose have the opposite effect. they turn us into this poor guy, focused on the direct drudgery of the thing itself:

metropolis1927_002779_enhance-enhance

by the way, apple (i mean xerox) pioneered that, and its called a direct manipulation interface: https://en.wikipedia.org/wiki/Direct_manipulation_interface (sorry, a little mild cynicism there.)

the blog author, “cxwinnectaland” is actually talking about the example of a pdf viewer they use on a regular basis:

“For the last two years, I have been using Google Chrome to view PDFs at work.  Dozens a day, usually with at least five open at a time.  For the last two years, every time I have rotated the view clockwise or counterclockwise, my page has shifted off-screen and I have had to scroll to get back to it.”

whats funny is that this blog starts about talking about how technology is best when we dont have to think about it– i would counter-argue that technology is best when it lets us put the thought of it aside most of the time– thats a little bit different. because when you choose a tool, you might choose it based on first impressions…

“oh, this is easy to use and fairly good looking…” (a reasonable impression)

“oh, suddenly a common task is easier! im being productive!” (building a preference)

later on:

“hey, its being stupid! im just going to square-peg this into my workflow!”

the point is, this blogger is talking about how great it is that they finally fixed the little annoying “doo-dad” where to make the everyday viewer work properly, the tool has distracted the user with an anti-feature/tedious need for a kludge/workaround. i sort of agree– fixing those things can make a world of difference.

but how about all the steps that made the user more likely to be helpless:

  • so many pdfs, when text and html exist and are better for viewing… with everyone using the wrong tool for the job, the user is expected to also.
  • a pdf viewer that isnt even a pdf viewer, meaning that fixing a small bug is a low priority (and introducing one is easy for the same reason: its not even a vital feature.)
  • countless layers of abstraction/absurdity: graphics layers implemented in the web browser, to show a vectorized implementation of simulated paper designed for printing, instead of an interface designed for simple text and graphics– which is actually what the web browser was before they bolted on the pdf viewer!

if someone just made a good pdf viewer, then it would be a top priority when it had a display bug. instead, we are bolting everything onto the browser like a swiss-army knife.

i appreciate that in computing, sometimes the swiss-army knife model isnt like its namesake: all the little parts arent inferior to the “full-size” stand-alone versions. i mean the way we make “stand-alone” devices is to take a general-purpose machine and hobble it until it can only do one thing. im certainly not in favor of that.

and lets not forget that the whole reason we know about the swiss-army knife is that sometimes its handy when a browser (or gadget) can do everything. im using it to write this instead of a word processor; dont think im unaware that this ancient laptop would perform a lot more nicely with libreoffice than this cloud-like thingy that wordpress has me typing in.

in some cases, i would use something else.

but thats my whole point here!

not thinking about technology actually is what most people do– and it is the true source of so much cost– using a crappy tool (or a good tool with crappy side effects) when there are countless other tools out there that work better, or are designed to do a job well– if the user accepts no responsibility for tool selection (and even has a choice, but simply doesnt bother) then not thinking about technology is the problem, and thinking about it is the solution.

while it is good for developers to fix these things, it couldve been fixed sooner by the user, or by a society that didnt decide that making a frozen, simulated printout into something dynamic was better than simply making a document that is itself dynamic– even in an application already designed around the latter idea.

we do so many bizarre, overcomplicated things because we dont think about how much nonsense we pile atop nonsense, its a complete wonder that devs can still fix anything.

but thats the magic of computing. if instead of reading text from a screen, youd rather read text from a window running in a compositor over a gui that shows a smooth scrolling portion of a document that is simulated using fourier transform algorithms to create an approximation of a actual printed document with margins and custom fonts that you may not like, so it gets loaded into a pdf library that reformats the page after extracting the text from the digital file that is more than a few orders of magnitude larger than a simple text file would be with a one line note as to what font should be used–

you can do all that, and you can put the developers through that level of absurdity. and to an extent, its really their fault for catering to such a sprawling design. i mean its fun to go overboard sometimes– we know, because we have fun using tools that way.

the thing is though, if you ever stepped back from the details that pop out of everyday use– “no excuses?” how about “youre doing it to yourself?” thats not an excuse, its a fact of life sometimes.

many years ago, plato said: “the unexamined life is not worth living.” somewhat more recently, arthur c. clarke said: “any sufficiently advanced technology is indistinguishable from magic.

i will bite off these to say: “the unexamined workflow will become indistinguishable from a horrifying pile of workarounds.” ok, so its not catchy.

real life is messy: but if you find yourself pooping where you drink, and you already have working sinks and toilets but youve simply decided to “change your workflow” in how you utilize them, maybe its time to stand back and think about your technology.

a lot of your gripes come from too many workarounds, and not enough thought about where the real problems are coming from.

this blog entry is part of a philosophical series where “computer types” talk about the world and everything wrong with humanity– i mean, users– i mean, computing. a favorite author of such pieces is andy mender, who wrote the most recent example (also this, this and this) that i can think of. cheers, andy. and devwrench: sorry for jumping all over it! its either a difference in personal philosophy, or i simply read it a lot differently than it was intended. hopefully a good point or two came out of the whole thing.

and to the user: i defend, even champion your right and room to do what works for you– but the odds of that happening are more likely if you have to consider the results and even some of the actual causes, now and again. youre not more likely to find the best tool for you if you always trust people selling one-size-fits-all.

 

  • this work is in the public domain.
  • …that probably even includes the picture.
  • …got it from here and edited it myself.

 

whats new in fig os 2.4

as shown in the screencap, the kernel has gone from +deb8u1 to +deb8u2. this is in hopes of patching the “dirty cow” (copy on write) vulnerability.

the patched kernel is the solution here; im told refracta will patch the image in about a month or so. this is reasonable since a kernel upgrade and reboot is this simple (if youve installed refracta, or fig os):

# wget http://security.debian.org/debian-security/pool/updates/main/l/linux/linux-image-3.16.0-4-686-pae_3.16.36-1+deb8u2_i386.deb

# dpkg -i linux-image-3.16.0-4-686-pae_3.16.36-1+deb8u2_i386.deb

# reboot

 

mkfigos 2.4 tries to download this and dpkg-deb it into place, plus copy the new vmlinuz– when you boot into the new iso, uname gives you the same output that it would after upgrading and rebooting… so hopefully this solves the matter for live users, not just people that have installed and upgraded.

fig os 2.4 has the newest version of fig ever— ok, its basically just a new python 2 version but with the help feature from 3.1. it also represents a return to python 2 as the primary series for fig development: fig 4.0 is found at /usr/bin/fig40.py.

and at /usr/bin/figu29.py you have the portuguese-based figueira. cheat sheet if you run figu29.py help or evince /usr/share/doc/figueira/figuchsh.pdf for a printable version.

since fig os really isnt much about themes (not in the live image anyway) most of the xfce themes are removed from version 2.4. we kept the ones golinux put together for refracta, obviously. they wont be used by icewm, which is all the more reason to get rid of most of the others.

thats a pretty robust little update– enough to blog about, i would hope. enjoy!

figos2-4

get the code here: http://unofficialdistros.freeforums.org/post258.html

 

 

migrating from python 3 to 2

i just blogged about switching back to python 2 for development, and then today someone posted to their blog about python 2 to 3 migration.

so the following is partly tongue-in-cheek, but i thought i might post a little guide for anyone migrating to python 2: some of the pros and cons, and answer a few questions.

first of all: is it difficult?

i dont recommend migrating all of your projects from python 3 to 2. although it should be pretty easy, this is a theory vs. practice thing, and it probably isnt worth time migrating existing projects until there is a real need. (i would say the same for migrating in the other direction.)

for the most part, let need (and convenience) rather than hype or peer pressure be your guide here. you might try doing your next project with python 2 instead of 3, and see if it makes your project easier.

if so, you may find (as a former nokia developer i knew did) that theres no reason to forsake python 2 for 3– but ymmv. certainly python 3 wouldnt be here if it were useless to everyone. the push to standardize however, has shown (in my opinion) that python 3 is overrated, and its usefulness overestimated.

how is the library support for python 2?

library support will be mixed, as a number of libraries have moved to support python 3. the advice here would be to treat the two versions like different languages– if you need a library that is only supported by python 3, then you have the choice of a different library (where possible) or to use python 3.

which libraries will continue to be supported in python 2? perhaps a good guess would be the ones that are already supported in pypy– more about that later.

what is coding in python 2 like, vs. 3?

of course it depends on your goals. python 2 is supposed to have inferior support for unicode; hence the push in python3 to standardize on it. but not everything in computing is actually unicode; whether you use 2 or 3, there are conversions back and forth. personally, i find the conversions in python 2 less brittle, and the ones in python 3 more verbose, tedious and less predictable.

to sweeten the deal, you dont have to put parentheses in the print statement:

print “hello world– pretty cool, huh?”

if only theyd thought of that back in the days of python 3, eh?

of course you will hear stories from both camps– 3 is so much easier for unicode, or 2 is so much easier for strings– it should be obvious which camp im in. give python 2 a try, and if it doesnt feel like everything just got a lot easier, dont migrate! use what works for you.

isnt the python foundation dropping support for python 2?

yes, they are. in fact they were going to drop it last year! but they extended it to 2020. after that, you will have to use an unsupported interpreter or switch to pypy. pypy is an alternative implementation of the python interpreter– you should be able to run many of your existing python 2 programs with zero modifications.

library support for pypy is not exactly as broad as it is for python 2. for example: my own python project– fig– uses pygame optionally, but i have not succeeded in getting pygame to work in pypy. im told its possible, and ive tried. tips are welcome. ive used pygame in both python 2 and 3. python 3 support for pygame is pretty much “build it yourself,” if youre using debian/devuan stable. (and ive built it in devuan.)

how do i do float division?

this is one thing that python 3 definitely got right– 3/7 is .43857, not 0. the trick to make float division work in python 2, is to explicitly make either the numerator or denominator a float:

x = 3/7 # gives 0

x = float(3)/7 # gives .43857142857142855

x = 3/float(7) # gives the same as float(3)/7

it also works with variables on the right side.

how do i print on the same line without a space added after it?

there are probably multiple ways to do this, i prefer sys.stdout:

from sys import stdout

stdout.write(“hello”) ; stdout.flush()

the chr() command wont do codes over 255; how do i do unicode?

you can use unichr instead, or even overload the chr() command:

def chr(p): return unichr(p)

# you can also use unicode strings:

print u”\u2588″

more tips are available as “python 2 to 3” migration guides; to some degree they work in both directions.

 

 

 

python 3 costs too much

update: i made good; heres fig 4.0– fig 4.0 (python2, includes command help) and if you want to try the portuguese version, here is figueira 2.9.

ive been coding in python for more than 6 years. ive written a programming language in python; i’ve always known about python 3.

versions 0.4-2.9 of fig (“fig basic”) are written in python 2; versions 3.0-3.1 are done in python 3. it was a fair amount of work to get everything encoded; whether dealing with stdin, stdout, print, or file input and output, python 3 wants its hand held through every string it processes. compared to python 2, python 3 is brittle.

python 2 is flexible. it may be “too flexible” for google, but google can afford to use python 3. some people have the patience or preference for it.

i never did. i never wanted python 3, i never needed python 3. but when people started to switch, and the python foundation said it would drop support for python 2 in a few years, i thought: “maybe i should make a python 3 version of fig, just to try it.”

fig 3.0 came out 11 months ago, in 2015, followed by 3.1 in january of this year. ive used both versions of fig: 2.x and 3.x all year long; ive used fig to remaster an operating system (its about 50% bash code, but thats fine; all of it is called from fig.)

the fig 3.x experiment is complete; and so is the time i choose to spend on python 3.

if there is a future version of fig, it will be fig 4.x, and it will be based on python 2.

note that fig development mostly stopped about 10 months ago; i consider it stable, but today i was trying to process two large lists of files, and fig 3.x wasnt up to the task. it is supposed to catch the error and revert to utf-8 if ascii couldnt be handled, but it was not able. was this a special filename? sure. but is fig 2.x handling the task better? of course.

thats the last straw for me as far as python 3 goes. ive never had fun using it like i do with python 2, ive never ever managed to make it as reliable when it comes to a feature as intrinsic as string handling, and ive read way too many tutorials, spent too much time on conversion utilities– in short: f*** python 3 and the horse it rode in on.

i have a 25 line program that i need to work today, and only one command in fig 3 is unavailable in python 2. (edit: or so i thought– ive combed through the source of fig 2.9 and 3.1, i cant find any difference in command sets between them! good thing the figueira version only took a couple minutes…)

well, figueira– the portuguese version– is based on python 2, and since i had a copy of it handy i just translated the fig 3 program to figueira. here is a sample:

tentar
f1 comando meio 1 1 
f2 comando meio 2 1 
o ordaberto f1
p ordaberto f2
exceto
z "dircmp: usage: dircmp file1-or-folder file2-or-folder" print end
retomar

xc
yc

z f1 impressha " only: " impress
paraem y o
yin incad p y smb
seigual yin 0
z y impress
fig
seg

z "" impress

and the translated version of dircmp has now produced the file i asked of it. is fig 3.x fixable? it took almost a year to even be sure it wasnt good enough! but its not, and when the python foundation dumps python 2 in 2020, im hoping that pypy will do.