Hacker News new | past | comments | ask | show | jobs | submit | more PaulJulius's comments login

Being able to open up multiple files and arrange them precisely how I want (with the keyboard!) is my absolute favorite part of vim. I use the following shortcuts for opening a file to the right/left or above/below:

    nnoremap <Leader>or :set splitright<CR>:vs
    nnoremap <Leader>ol :set nosplitright<CR>:vs
    nnoremap <Leader>oa :set nosplitbelow<CR>:sp
    nnoremap <Leader>ob :set splitbelow<CR>:sp
    " Don't let vim change the setup when closing windows
    set noequalalways
So I can simply type ',or ' and then the name of a file to get a vertical split.

You can then use <C-w>w<number>+/- to increase/decrease the height of a window and <C-w>w<number>'<'/'>' to change the width.


Some code you can write in the console to click the button at a certain time:

    sec10s   = document.getElementById("thebutton-s-10s");
    sec1s    = document.getElementById("thebutton-s-1s");
    sec10ms  = document.getElementById("thebutton-s-10ms");
    sec100ms = document.getElementById("thebutton-s-100ms");
    button   = document.getElementById("thebutton");
    time = function() {
        return sec10s.innerHTML +
               sec1s.innerHTML; // +
               //sec10ms.innerHTML +
               //sec100ms.innerHTML;
    };
    
    pressAt = function(timeStr) {
        return function() {
            if (time() == timeStr) {
                button.click();
            }
        };
    };

    setInterval(pressAt("00"), 100);
But even with setInterval set to 1, this won't get called every millisecond, so you can't get accuracy to the second decimal point, not that there's really any need to. (It turns out setInterval has a minimum delay. setTimeout's minimum delay is 4ms and likely setInterval's minimum delay is the same.) Just set this up and leave your computer running for the next few months and you ought to get it eventually.


You can also just listen to the websocket that they are using to update the button (this is without being logged in):

var buttonSocket = new WebSocket("wss://wss.redditmedia.com/thebutton?h=3b85664277e270cfd024faee2cc021a359a8af73&e=1429012932");

buttonSocket.onmessage = function (event) { console.log(event.data); }

data is just plain json in the form {"type": "ticking", "payload": {"participants_text": "715,197", "tick_mac": "e2dc885fe4836cad86f9cd7670645871e11401f4", "seconds_left": 50.0, "now_str": "2015-04-13-12-33-44"}}

That lets you know what the seconds are on the server and you can calculate your own ms (it looks like they do it client side too), just remember that timeouts are not guaranteed to fire exactly at the time you set since it's a single thread. Maybe a webworker could come in handy here but the event triggerd by a message would still be subject to delay if something else wanted to run. requestAnimationFrame is another place you could look or if you can scrape together the details you need to send the button press you could run something in node with more accurate timing.


Okay, now if you really want to impress me, pretend you work for reddit and write some code that would catch this kind of script and give it "cheater" flair.


People I think all these "cheater traps" are unimportant, because there's actually no "significant advantage" to using a robot. It isn't going to make you more likely to beat human players, only allow you to stay on there longer at lower cost to you.

This is because two things: 1) the userbase size, and 2) the userbase behaviour.

Because the userbase is so large, there's always going to be some people on there, meaning even with a robot you always have some competition.

So the only thing a robot will allow you to do is potentially have better reaction times than a human, however, this is also invalid when you consider that it's likely people are not trying "hit" a particular countdown number they're "aiming for" but rather simply pressing the button when their "threshold" for waiting any longer is exceeded.

Wit enough people this is probably well modelled by a random process, with clicks coming essentially randomly over time with some weighting to increase the closer you get to zero. So even a "reflex reaction" is not going to outbeat a horde of random clickers. The robot is really only competing with itself, how fast can it check and how fast can it click after determining the person it's working for's risk/reward utility threshold has been crossed?

So having a robot to play for you is not going to allow you to cheat, only to spend your time dong something more constructive for humanity than clicking a button :)

Maybe I'm missing something here, and I still don't see a way to cheat that actually has significant chance of beating others ! :)


> So having a robot to play for you is not going to allow you to cheat, only to spend your time dong something more constructive for humanity than clicking a button

In other words cheating since "normal" players need to spend their time doing that while you can have it on 24/7. I don't understand how you can say it doesn't make you more likely to beat human players. You increase your chances of getting the orange flair by magnitudes.


Consider this, if there's 10 human players you're competing against and they take turns occupying 2.4 hour spots, will those players essentially cover the entire space 24/7?

As far as you are concerned the rest of reddit may be either 10million human players, or 1 million robots, can you tell me who you are playing against? I'd say to you, it's the same.

Now, in a two player tournament, yes, using a robot gives you an advantage because the opponent probably has less stamina than your robot.

But in a competition involving thousands of people, there's really no advantage over any one person because the greatest force on any individual player is the sum of all other players against them, not one player with a robot. Do you think that sounds reasonable?

So the way I see it using a robot is really only a way to make things more comfortable for yourself, just like driving coast to coast is probably more comfortable and likely less time consuming than walking. It's not unfair to walkers, you're not stopping them from walking coast to coast. The only thing that might stop walkers is their stamina.

So while it's true that the reddit case does exhibit scarcity and competition for that (there's only so many click spots per reset), whether people are playing with robots or flesh doesn't make any difference to you, because wherever you are, at whatever time, there's always someone else there with you. It's somewhat ludicrous to think that you will have an advantage if it's all people because say at 2:14 am August 29th, 2015, all 2927 other people are all dozing off just at the same moment that the counter gets to 19 seconds and you push it. I mean, does that sound likely?

Not really, right, because there's always going to be people just alert as you. And robots don't really give you any more grief than people.

It's an interesting argument, and there's probably more to it. I'm sure I'm missing something, and thanks for giving me something to bounce off.

Hey, maybe you can try out a Chrome Ext robot yourself :)

https://chrome.google.com/webstore/detail/rthebutton-robot/m...

Please let me know if there's any bugs.


Right, but also you can't try again, and only old accounts can do it. So once your bot fires the button, you're done, the bot isn't ruining it for anyone any more


That's a really great point, too! :)


Another way to think of it is this : there's no orange flair so far, because the pressers haven't let it get below 21. Getting orange is dependent on what the collective does, a robot isn't going to help you beat that, only let you be there when it finally goes down without having to neglect your life in the meantime.


That assumes that the goal of the button is to get as low of a flair as possible. It may not be the creator's intent.


Inside the click handler for the button use `new Error().stack`. You should be able to determine if it's a legitimate event from the stack trace.

Ultimately, though, someone could just use HTTP instead of monkeying about with scripting in the browser. You could only deter this by serving up a new JS file every day that has a new way to e.g. calculate a checksum on the button click. Ultimately people are going to find a way to cheat no matter what you do. If this is a social experiment that is a result, too.


What I'd probably do would be to have the JS in the button capture some user driven events such as mouse positions and click characteristics. If they had great foresight, they could have already been doing this for the previous 700k clicks.

With a reasonably sized observation pool, they could compare subsequent clicks and detect outliers.

I think it would be hard to circumvent since people attempting to reverse engineer wouldn't have the observation pool to know what signals Reddit admins were modeling. The biggest downside I can think of is that there would be some delay before calling out a cheater depending on the reliability of the model.

The client side JS could detect the lack of an event capture payload and warn legitimate users after they unlock but before they click so they wouldn't be flagged due to browser incompatibility or JS restrictions from a security policy or privacy extension.


Monkeypatch setInterval/setTimeout to mark people as cheaters. The more dedicated cheaters will hit the button API outside of the browser, which is pretty hard to stop.


Easy options for this are plentiful.

[1] http://www.sikuli.org/


For someone with only limited HTTP/Javascript knowledge:

"The more dedicated cheaters will hit the button API outside of the browser, which is pretty hard to stop"

How this would be accomplished, I guess from the command line ?

EDIT: found what Monkeypatch means.


The button presses are communicated over a websocket. You could make your own websocket client and communicate however you want to, such as listening to time updates and sending a click when it reaches a certain treshold.


Umm... What?? If you did this, then surely EVERYONE would be flagged as a cheater! Clicking the button "legitimately" would call the same function!


Monkey patching setTimeout / setInterval would allow you to detect when people were running timers on the page. Use of timers could generally be considered "cheating."

It doesn't do anything to intercept people pushing the button.

    window.setTimeout = function setTimeout(fn, ms) {
        alert("No you don't, cheater!");
        assign_button_color_of_shame();
        original_setTimeout(fn, ms);
    }


Which is very, very easily worked around by including another version of the original setTimeout in your console code.

The only real way to detect this is through usage pattern analysis and detection on the web socket side, because if you can write something in JS that catches people, someone can make minor modifications to their code to make it work again.


Just to be clear - this wasn't my original idea and nobody should ever put any security code into a client. Even if you could make this work someone could recompile Chrome to work around it.

I've found a way to get access to the original setTimeout again by embedding an iframe into the page and extracting it from there.

Would be interested in hearing other methods of getting a handle to the original setTimeout again.

I guess you could simulate it by using some other mechanism, say firing off an async request to a server that returns after a certain time and running a callback.


Eh putting security into a client like FB did disabling the console -- it might help against people getting phished. Though I generally agree.


Ohh right, so your plan would be to essentially check for third-party javascript things running on the same page?

This would be a really easy "security" measure to circumvent, though - I could literally just delete your monkey patch, for a start!


It wasn't my idea so, no, that was never my plan :)

Though, you do raise a valid point, so let's see how it plays out.

    setTimeout = function(){...}
    delete setTimeout  // true - you've removed the patch

    window.setTimeout = function(){...}
    delete window.setTimeout  // true - you've removed the patch

    window.constructor.prototype.setTimeout = function(){...}
    delete window.constructor.prototype.setTimeout  // false - the patch is still there!
I don't know about the hierarchy of the prototype chain up at this level but it seems to work.

Maybe there's some other way of getting to the built-in setTimeout so you can create your own version to mask the one I added?

EDIT you can embed an iframe and rip the native setTimeout from there.


They could listen to the DOMSubtreeModified event in the 10s div.


Nice! There are probably clocks all over the place when you start looking around :)


reddit stops you from embedding it iirc


I tried that too - you can just use any old page that has CORs headers allowing it.


  var cheaterFunc = function () {
    console.error('cheater!');
    // report cheater to server somehow...
  };

  $('*').each(function (i, el) {
    if (el instanceof Object) {
      Object.defineProperties(el, {
        innerHTML: {get: cheaterFunc},
        innerText: {get: cheaterFunc}
      });  
    }
  });
...and of course to defeat this, you could simply use a tampering proxy to prevent this javascript from making it to the browser.

(There are probably other ways to get the value of each digit with javascript, but you should be able to just add cheaterFunc to each of those. .childNode, change the style to use a custom font where each number has a different, predictable width and test .offsetWidth, etc.)


Easier way to get around that: use a version of internet explorer that doesn't support getters!


There isn't much you can do if the "cheating" happens client side, because the cheater has complete control there. At most you can obfuscate it by e.g. rendering the button in a canvas element and/or including a checksum and change the js files frequently like people here mention, but again, that will be just obfuscation, not real security.


Use a canvas element to render the timer.


Whatever your interval duration is you'll get a "reflex speed" of average double that: Shannon-Nyquist sampling theorem. So if you want to play at a 100ms reaction speed sample every 50ms or less.

4ms caps your max reflex time at, say, 10ms. Or about 16x faster than your average human [https://www.biology.usu.edu/files/uploads/Courses/Biology%20...]

I'm no expert in sampling. Any bona fide experts want to weigh in? That works ! :)


What's the benefit of pressing it when it is near 0 seconds? You really want to be the last person to press it before the full 60 seconds expires.


How do you know what they really want? Take a closer look at the subreddit and things like an entire class system has developed over which number you get (if you've pressed at all.) Plus, who says the goal is to be the last person who clicks? Maybe the goal is to not click at all!


It's only relevant because the button is still active. The sub will probably die once the button is deactivated.


That's not the correct strategy for keeping the timer alive as long as possible. If everyone did that, then everyone would simultaneously press it the first time it almost-expires, and nobody would remain for the next time it nearly expires.

A better strategy is to pick a random time number that you wait until, biased towards the lower part of the range.


you get nice reddit flair the later your press it :)

no way to program it to guarantee you are the last person to ever press it.


Protip, you can hijack jsperf's java ns timer by loading the code in via a data://field to avoid cross-site script loading flags.


Hint, check the global variable r.thebutton as alluded to elsewhere in thread.


You will lose as soon as your web socket breaks.


So, you created code to repeatedly press a button you can only press once?


No, to repeatedly check the time the button has and press it once at that time :)

The fact that it'll press it again if it hits that time again and do nothing is beside the point; there's no need to add complexity of exiting.


I find your choice of analogy a little amusing. In these circles, I think more people would have significant exposure to dense mathematical notation than significant familiarity to a particular golf course.


Yeah, well, yeah. It just happens to be the only way that I've measurably and comparatively observed this sort of memory phenomenon in my personal experience.


Obviously this is a useful tool, and all the power to the author for finding what looks to be an excellent solution, but this line bothers me:

>>> Sometimes I wasted hours and hours just because there is one character difference. I hate it.

This shouldn't happen. Ever. This should not be a problem anymore. These are the sort of errors that we can catch immediately and should be caught immediately. From looking at the author's GitHub profile, it looks like he uses Emacs, presumably without a plugin that would give him IDE like features. I'm not going to tell him to go use a regular IDE, but it frustrates me that's we can't have those sort of tools available everywhere. (As a vim user myself I have high hopes for the neovim project and look forward to the day when it can be embedded inside a general sort of IDE.)


While you can catch some of these, for a language like Ruby, it's an incredibly hard problem to catch all of these errors immediately because the methods that can be called on a given named entity can not in the general case be known by statically inspecting the source, and you can not in general safely instantiate the application because even class definitions are executed and can have side effects, and the methods available can even vary based on environmental factors, such as whether or not you get a database connection, and what's in the database.

Consider that it is a common pattern for Ruby ORM's to either use method_missing or dynamically define methods to correspond to the current (at connection time) set of columns present in your database.

And "thanks" to the ability to monkey patch and redefining methods, even determining if something "obviously" safe like 42.to_s is not.

There's no way for your editor to handle that unless you stand up a version of your app with an instrumented language environment and lets the editor poke around. Now that is possible with tools like Pry, etc., but it takes a lot more work to do safely (because your editor can't know if it can safely start your app).


Yuki works at Pivotal Labs in NYC. I work there too.

We use whatever editor or IDE any given pair decides to use. In my day-to-day work I've used RubyMine (very popular in our west coast offices), Vim (popular in NYC), Emacs (popular with Mike Dalessio) and my own personal favourite, Sublime Text.

I don't think solutions have to be either/or. Yuki's approach is simple and will cover lots of cases.


You're invoking "IDE" features like it's a panacea. In reality IDEs have only a few limited ways to catch these kinds of errors. With a statically-typed language it can run static analysis at intervals and make sure that all the messages being passed are actually defined on the objects they're being passed to. You can do this precisely because that's what static types gives you.

In dynamic languages you can't do this because you don't know the type that any given identifier is pointing to. The type could be completely arbitrary, I.E. coming from external input. You might think, "oh, well you could just check against all possible methods", and you'd be right, except for Ruby. Ruby allows you to override what happens when you call an undefined method, (method_missing) letting you execute completely arbitrary code that lets undefined methods look just like methods. You could call car.start_and_drive_to_the_bank, and set up the Car type so that it can handle methods like that, (perhaps calling car.start, and then car.drive(bank)) along with .start_and_drive_to_the_mall and whatever. In practice that's bad Ruby, but you still have to be able to handle that, Bad Ruby is still Valid Ruby.

So there's just no way to tell in Ruby whether any given method call is correct or not.

I have an idea to conventionalize method_missing overrides so that they're easier to analyze. Maybe define a regular expression on the class so that the analyzer can sort out what's likely to work at runtime and which messages aren't. Not sure how well it would work until Matz manages to implement static typing as he wants to do in the future. Until you can tell whether any given identifier is likely to be of a type that overrides method_missing, you'd be running the method_missing analyzer for all types on all method calls.


On the other hand, this gives a consistent experience and does not force people to mess around with plugins for their editor (if needed)


A spelling error in http request can cost more hours if using IDE.


As the music started to play I reached to pause the music I already had playing, but then I realized that it was paused automatically by Spotify. That's a pretty cool feature that they have - very well integrated.


It's DRM, actually. I agree it's a useful feature sometimes — until you want to leave music playing for your partner in your living room while you listen to music and cook dinner in the kitchen.


Weird, my Spotify kept playing while the map was mapping... I had to manually hit pause in the Spotify client...


I was in this lecture on Tuesday!

I did not take notes, but another student takes very extensive notes for the class and posts them online. All his notes for the class can be viewed here (scroll all the way to the bottom):

http://stanford.edu/~adebray/240h_notes.pdf


Does he make the slides in class? I teach and hate powerpoint, but it looks like he draws the slides as he teaches?


No, they were already made. I meant to ask what he used to make them, but I never had the chance.


I draw my slides in Xournal on slide sized pages, and then export to PDF to present them. I roll a few patches to the software to make it easier to make build slides, but otherwise it's pretty self-explanatory. (https://github.com/ezyang/xournal) I do the same thing for diagrams too. (http://blog.ezyang.com/2010/04/diagramming-in-xournal-and-gi...)


The drum major of Stanford's Band is pretty exceptional:

http://www.sfgate.com/collegesports/article/Stanford-band-s-...

I auditioned for the job this year in a King Tut costume but didn't get it. I can't say that I know exactly what the drum major does either, but I think spiritual leader is a good way to put it.

While it may be hard to describe the exact purpose of the drum major, some definitely stand out. This year was the 50th anniversary of the Band and many old drum majors came back to play with us. At one point each of them got to conduct a song, and some of them were just incredible.


Patients with CF at Fairview got the same things that patients everywhere did—some nebulized treatments to loosen secretions and unclog passageways (a kind of mist tent in a mouth pipe), antibiotics, and a good thumping on their chests every day. Yet, somehow, everything he did was different.

I found this quote especially interesting. I've often found this to be true, that you look over at someone who's much better, and on one hand they're just doing the same things you're doing, but somehow they're just on a different level. It's very difficult to distinguish exactly how someone achieves better results, that is, until it's been explained. Here, we see this clearly in how the level of lung function is perceived. Both centers provide the same treatment, but at the Cincinnati center lung levels around 70% are "okay", but at Minnesota, any drop is unacceptable, even if the patient is already at above-normal levels.

It sort of reminds me of the "Don't deal with it, fix it" article that was also posted recently. You'll be coasting around at a certain stable level of engagement until one day you see something you've never considered before and all of a sudden you see a whole new world of possibilities.


I had Alex Aiken as my professor for the class I took on compilers last Spring. I really enjoyed his teaching and I remember him discussing this project during the last lecture. Very cool stuff. The class is still probably my favorite class I've taken.


I don't think you're giving enough credit to Flappy Bird. It's clearly a skill based game, but it's not something you can pick up right away and be good at. It takes at least 30 minutes to an hour to get decent. I remember when I was first playing and I finally broke through and had runs of 30, 40 then 70, all in a row. I felt pretty accomplished.

Now I still play sometimes, almost as a way of relaxing. Once you get the hang of it, it's easy, but you still have to pay attention and you can still get tripped up. I'd say it's a very rewarding game.

Just yesterday I finally beat my friend's score of 171 with 203.


Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: