Home
About me
Math
Programming
Politics
Projects
Ethan's Random Musings
Scope of this website ===================== This website is by no means an autobiography or anything similar. It is simply a collection of my musings and such, as well as a place I can refer people to that will inform them to what they can expect from me.
About me
About me ======== ## Who am I? I'm a person. I like eye candy like 60fps animations. I don't use Google due to privacy concerns. Anything Google, I don't use it. Period. Even though it's annoying. That last part is quite telling of my personality. ### What are my interests? Programming, math, and their intersection, crypto. I enjoy using logic in the most mathematical sense, especially where it makes no sense whatsoever. For example, to "Is the apple in the fridge or out on the counter," I might answer "yes", if I'm trying to be difficult. I also do a fair amount of reading about politics, especially politics relating to technology, and mocking Fox News and the crazy things the Republicans say in the United States. For some reason, I have a fascination for pure math topics, regardless of whether it has real-life applications (things like hypercomplex numbers that really don't end up getting used much). ### Things in the world that drive me nuts There are certain things in the world that seem like they are specifically designed to drive me nuts. They include: * People who write `public void something() { //Do something } ` as opposed to `public void something() { //Do something } ` * People who declare functions in JS as `var foo = function() { //Do something } ` as opposed to `function foo() { bar(); } ` * People who pronounce "Richard Feynman" as "Richard Fineman" (It's pronounced "Faynman", as in "feign death") * Languages that make me declare and use variables with $'s (*cough* Perl and PHP *cough*) * Hearing Stephen Harper speak * People who say "Just *code* something up," whereas it would be more correctly "Just write a program for [something]" * People who don't know what an artificial intelligence is defined as, and would say that a dishwasher is an artificial intelligence * News networks who display news about the British royal family ahead of news about the real world * People who equate hacker with cracker, or say "x mod for x game is a hack" when they don't mean hack as in what it feels like Unity (the game engine) is composed of primarily * People who write 6+i4 as opposed to 6+4i or use j=sqrt(-1) as opposed to i ## Programming languages My favourite languages to write are Python, Java, and Lua, although I don't do much Lua, unfortunately. However, the languages I am most comfortable with are Java, Python, JS, and C#, even though I think JS is a royal mess. At times I've written PHP, but I was never any good at it, and I wouldn't consider doing anything serious in PHP. (That's more because I never bothered to learn PHP; I mostly use other web frameworks, or use Firebase and do everything client-side. Also, PHP makes me write a lot of $'s). I'm familiar with the standard libraries of Java, .NET, and JS, and am reasonably familiar with that of Python, although not nearly as much as that of Java, for example; I do a lot of internet-searching when I write Python.
Math
Loggable Numbers ================ ## Definition A number n is said to be *loggable* up to the base b if, for all 1<x≤b, n1/x ∈ ℤ. It could similarly be defined with set theory, but I won't bother; it's pretty obvious how one would do that, and is not essential to anything hereinafter. A shorthand is n:b, meaning n is loggable up to b. It makes no sense to say that 64 is loggable up to, for example, 2.5, since, given the definition, that is logically equivalent to saying 64 is loggable up to 2. 1 is loggable a loggable up to any base, since, for any x ∈ ℝ > 0, x0 = 1. However, it is not very useful, and so 1 is said to be a *trivial* loggable base b, whereas any other loggable is *nontrivial*. ## Examples The number 64 is loggable up to the base 3: * 64 = 82 * 64 = 43 Thus, both the square root of 64 and the cube root of 64 are integers, and so 64 is loggable up to the base 3. However, 64 is not loggable up to 4, since the fourth root of 64 is approximately 2.29, and is irrational. The number 4096 is loggable up to the base 4. The number 1152921504606846976 is loggable up to the base 5. ## Generation The set of numbers loggable to the base b can be expressed as: {x ∈ ℤ | x1/b ∈ ℤ} ∩ {x ∈ ℤ | x1/(b - 1) ∈ ℤ} ∩ ... ∩ {x ∈ ℤ | x1/3 ∈ ℤ} ∩ {x ∈ ℤ | x1/2 ∈ ℤ} In other words, the task of finding loggable numbers to the base b is simply finding all numbers that are in the union of the sets of numbers whose cth roots, where 1<c≤b, are integers. However, actually enumerating those sets up to the necessary quantities is impractical, so I've mostly come up with other algorithms. I'm only going to focus on generating nontrivial loggables. ### Naive method One quickly realizes that we can just iteratively raise, say, 2, to all integer powers > 1 and ≤ b. Here's a Python implementation: def loggable(b): return loggable(b - 1)**b if b > 1 else 2 This can also be unwrapped into a for loop: def loggable(b): running = 2 for x in xrange(2, b + 1): running = running**x return running The unwrapped version would presumably be faster; however, they're both ridiculously slow. In addition, the numbers this comes up with are ridiculously large: loggable(9) has 109,238 digits. Loggable(10) takes longer than I'm willing to wait on CPython, but PyPy can compute it quickly; it has 1,092,378 digits. I got bored waiting for loggable(11) after about a minute. ### Naive method rephrased Upon writing the section for the naive section, I realised it's precisely equivalent to 2b!, where b is the base. This is *horribly* innefficient, but it's correct, and easy to write. I can write 277!, and say 277!, even if I never have whatever number 277! expands to. ### Slightly less naive method An obvious optimization follows from the observation that, if n is loggable up to b, then it is also loggable up to all of the factors of b. This could be proved by the property that abc = abc; I'm not going to bother. This means that, if we want to find a number that is loggable up to n, we can start at n and work our way down, but not raise to the power of any of the factors of n. For example, let's say we want to find a number loggable up to four. Here are the steps: At the start, n = 2. 1. n = n4 = 16 2. n = n3 = 4096 3. We don't need to square n, since 2 is a factor of 4. So, we're done. We get a result, 4096:4. So, our algorithm is correct. Our previous algorithm would have yielded 16,777,216, which is significantly larger. Here's a python implementation: def rrange(top, bottom=1): r = range(bottom, top) r.reverse() return r def loggable(base): arr = [False] * (base + 1) arr[0] = True arr[1] = True running = 2 for x in rrange(base + 1): if arr[x] == False: for a in range(x): if a**2 > x: break if a <= 0: continue arr[x / a] = True running = running**x return running Previously, loggable(10) was over a million digits long, and was took a few seconds on PyPy. With the new implementation, it takes about a second on CPython and is 18,208 digits. Also, loggable(11) is easily computible on CPython, and has 200,271 digits, which is less than loggable(10) with the previous implementation. Although it's impractical with CPython, PyPy can compute loggable(12), with 400,540 digits, almost precisely double the digits of loggable(11). I got bored with loggable(13). ### Rephrasing The previous method is equivalent to going down from the top and, for each number, seeing if it's loggable. (The previous method will, of course, be slightly faster, because it doesn't have to do nth-root calculations). ### Another rephrasing The ### Exhaustive method The obvious exhaustive method is to enumerate all numbers that are integer powers of every integer less than the base, and then find the intersection. That will be the set of all n loggable up to the base.
Programming
Fun class declarations ====================== Here's an interesting idea for class declarations (using a JS-like language) class Cartesian(x, y) exports getX, getY, toPolar { var r = Math.sqrt(x * x + y * y); var a = Math.atan(x / y); var cachedPolar = new Polar(r, a); function getX() { return x; } function getY() { return y; } function toPolar() { return cachedPolar; } } class Polar(r, a) exports getR, getA, toCartesian { var x = r * Math.cos(a); var y = r * Math.sin(a); var cachedCartesian = new Cartesian(x, y); function getR() { return r; } function getA() { return a; } function toCartesian() { return cachedCartesian; } } You can write any arbitrary code in the class, and then the exports get exposed from your scope to the outside. You can use it as normal: `new Polar(5, 90).toCartesian()` gives `new Cartesian(0, 5)` as expected. Command-line calculator ======================= ## Using a REPL Sometimes, you just want to do some arithmetic. You could just do node 22 / 7 // 3.142857142857143 ^C ^C to get an approximation of Pi (and it has the advantage of having constants like Math.PI), but node takes a while to start up and you have to double ^C to exit. Not perfect. You could use Python: python 22.0 / 7.0 # 3.142857142857143 exit() But then, you need to say 22.0 instead of 22, and exit() instead of ^C twice. (You could also use lua, groovysh, etc). Another problem is that you can't pipe into it. What I really want is something like: calc "22/7" # 3.1428571428571428 echo "22/7" | calc # 3.1428571428571428 ## Using a browser Previously, I'd just been asking DuckDuckGo; it can do some fairly complex arithmetic evaluations, as well as providing some other useful functions: [22/7](http://ddg.gg/?q=22/7), [(1 + 1/100000)^100000](https://duckduckgo.com/?q=%281%20%2B%201%2F100000%29^100000), and things like that. Still, that's a bit clunky. I can do better. ## GNU bc The next obvious answer is GNU bc. Example: bc -q 2 + 2 # 4 quit However, that still has the problem of being interactive, as well as not being able to ^C out. However, I can pipe into bc, something I couldn't do with the others. ### GNU bc + shell script Here's a shell script that I wrote with a lot of searching the Internet (I'm not good at bash). It allows you to pipe in inputs, or give them as command line arguments. #!/bin/bash stdin="$(ls -l /proc/self/fd/0)" stdin="${stdin/*-> /}" if [[ "$stdin" =~ ^/dev/pts/[0-9] ]]; then { echo "scale=16"; echo $1; echo "quit"; } | bc -q else { echo "scale=16"; cat /dev/stdin; echo "quit"; } | bc -q fi Now, the following actually works: calc "22/7" # 3.1428571428571428 echo "22/7" | calc # 3.1428571428571428 ### Using external libraries We now have what we set out for. But, how can we find, for example, the cube root of 16? calc "64^(1/3)" # 1, incorrect calc "e(l(64)/3)" # 3.99999..., close enough Although bc can calculate cube roots (as is provably possible, since it's turing complete), it's very cryptic and needs a lot of typing. How about: calc "cbrt(64)" # 4 calc "root(64, 3)" # 4 The way one would do this is by including funcs.bc, an external library. Here's the modified script to include funcs.bc, if it is available in /home/ethan/bc/funcs.bc: #!/bin/bash stdin="$(ls -l /proc/self/fd/0)" stdin="${stdin/*-> /}" bcpath="/home/ethan/bc/funcs.bc" if [[ "$stdin" =~ ^/dev/pts/[0-9] ]]; then { cat $bcpath; echo $1; echo "quit"; } | bc -q -l else { cat $bcpath; cat /dev/stdin; echo "quit"; } | bc -q -l fi Now, the above commands (for cube roots) work. ### We can go further What if I want to chain them? With the existing setup, the logical thing to try would be: { calc "root(2^32, 4)"; echo " * "; calc "2^2"; } | calc But, this gives the following error message: (standard_in) 721: syntax error Let's look at it a bit more in-depth. { calc "root(2^32, 4)"; echo " * "; calc "2^2"; } | cat yields 256.00000000000000000000000000000000000000000000000000 * 4 And there lies our problem: the trailing newline from calc. (Note that there's also a newline after the 4). Since newlines are often useful, I decided to add an extra parameter to calc that goes after all of the others, which removes the trailing newline. Code: #!/bin/bash stdin="$(ls -l /proc/self/fd/0)" stdin="${stdin/*-> /}" bcpath="/home/ethan/bc/funcs.bc" if [[ "$stdin" =~ ^/dev/pts/[0-9] ]]; then if [[ $2 == "d" ]]; then { cat $bcpath; echo $1; echo ""; echo "quit"; } | bc -q -l | gawk 'BEGIN{RS="\n+";ORS=""}x{print x}x=RT' else { cat $bcpath; echo $1; echo ""; echo "quit"; } | bc -q -l fi else if [[ $1 == "d" ]]; then { cat $bcpath; cat /dev/stdin; echo ""; echo "quit"; } | bc -q -l | gawk 'BEGIN{RS="\n+";ORS=""}x{print x}x=RT' else { cat $bcpath; cat /dev/stdin; echo ""; echo "quit"; } | bc -q -l fi fi Now, adding a "d" after the command (i.e. calc "6 + 4" d) removes the trailing newline. Modifying our previous command with the trailing d, we now get: { calc "root(2^32, 4)" d; printf " * "; calc "2^2" d; } | calc which yields 1024.00000000000000000000000000000000000000000000000000 which is what we wanted. ## Node + math.js It might be worth investigating making a calculator with node and math.js; there's support for things like complex numbers, something bc doesn't have, and it's more customizable (I'm using a library and my own node script, instead of passing things into the stdin of bc). JS Sandboxes ============ What if you have untrusted JS code that you want to run on your website, without compromising its security or trust with its users (for example, can the untrusted code make hundreds of gigabytes worth of AJAX requests?), and without, for example, writing a JS interpreter in JS itself, because that would be slow? ## WebWorkers to the rescue I immediately thought: WebWorkers! They can't see the DOM, or really anything important, without postMessage, which I would easily be able to chech for validity (I'd be the one implementing the postMessage handlers), and an infinite loop won't freeze the page. After some further testing, things like resource starving don't seem to work very well (even on a single-core Virtualbox VM with 2GB of RAM). ## Disabling access to builtins The next thing is disallowing AJAX. (I would allow it through postMessage, or possibly just my own wrapper over it, but I would limit the bandwidth, etc). I quickly realized that disabling individual objects worked perfectly -- I could, for example, disallow access to postMessage by simply assigning it to null. But, how would I disallow access to all objects (with a whitelist)? I could have a file that I import which would assign all of the known objects to null. But, what if a new one appeared, say in a new browser version, that is fine on its own, but in these circumstances, undermines the security? The obvious solution is to iterate over the self object (the WebWorker equivalent of window), and assign each to null. But, that presents its own disadvantages; for example, you'd need to use eval, and eval is slow and bad practice. ### Arbitrary JS with loadScripts() Instead of doing something that's bad practice, do something that's almost exactly equivalent but will cause less people to yell at you! What I ended up doing is looping over the self object, and appending to a string. If prop is the name of the property of self, "var prop = null;" will be appended to the string. Then, I convert the string to a data URL, and then pass that into loadScripts(). Then, the script to be sandboxed can be loaded. (Note that, for this, you have to allow the script to run loadScripts(), which may be problematic). Alternatively, you can grab the script that you're about to load via AJAX, and then append it to the data URL that you're loading; this is better under certain circumstances.
Politics
For context, I'm Canadian. The opinions expressed here are mine, and not necessarily those of anyone else. Trans-Pacific Partnership ========================= My first problem with the TPP is that it's called a free trade agreement. That's never good. But that's not an actual criticism. Here are some. ## Lack of transparency All of the negotiation is being done behind closed doors. The only way we have the text of deals is due to leaks. **I should know about the negotiation of laws that concern me and my fellow citizens. *There is no reason to negotiate humungus deals behind closed doors other than to prevent meaningful debate.*** ## Violations of sovereignty The TPP intentionally restricts the ability of lawmakers to regulate, instead requiring that all measures of the TPP be enforced over the like measures in local law. Corporations will be able to enforce the TPP themselves and go above all existing laws in the signatory country by participating in lawsuits against signatories. Again, lawmakers have no control. Corporations become the government. ## Legal enforcement of DRM DRM will be codified in law. DRM, an acronym for Digital Rights Management (or, perhaps more aptly, Digital Restrictions Management), is a technology to allow people to place arbitrary restrictions on files that are given to you. For example, it might artificially prevent having more than two copies of a song per purchase. It is, however, provably impossible to enforce this with something like cryptography, so, instead of accepting the 21st century, companies instead went crying to lawmakers to impose arbitrary restrictions that are so easy to circumvent that you sometimes break them by accident. That would be a crime under the TPP. ## Threats for whistleblowers There is a very vaguely worded section in the leaked copies of the TPP that would be justification for harsh criminal punishments for whistleblowers and journalists reporting on leaks in a purely journalistic capacity. **Whistleblowers are the historical way governements are kept honest. How will they stay honest in the future?**
Projects
Pager ===== Pager is a simple SPA library. It allows you to define and load pages without any server round-trips. It's a bit old, depends on jQuery, and is written badly; hence Pager 2. [GitHub](https://github.com/ethan2-0/pager). Pager 2 ======= Pager 2 is the second incarnation of Pager. It's a lot simpler, faster, and is not dependant on jQuery. [GitHub](https://github.com/ethan2-0/pager2). Jeva ==== Jeva is a web microframework designed to feel familiar to Flask developers who now want to write something in Java (as opposed to Python). [GitHub](https://github.com/ethan2-0/jeva). RollCall ======== RollCall is an HTML5-based Skype replacement that can do full-res encrypted video calls and strongly encrypted messaging. Currently, the code is a bit messy, and it's not unit tested, but it's worth a look. [GitHub](https://github.com/ethan2-0/RollCall). Mandelbrot/Julia in Processing ============================== I got bored once, so I took about 45 minutes to implement the Mandelbrot set in Processing. After getting a rudimentary implementation to work, I spent a few hours afterwards implementing Julia sets, color coding, stopping after things stop being eliminated, and some configurability (in the form of a whole bunch of fudge factors). The code is still a bit messy, but it's worth a look. [Gist](https://gist.github.com/ethan2-0/d4850b1c37e7cda55d93).