jlm-blog
~jlm

30-Jan-2006

screen tutorial

Filed under: linux — jlm @ 19:37

screen is really simple to use, but it can be hard to get started. It has so many features that the essentials get lost if you try (say) to read the manual. So here they are:

1: Start a new session with screen

This is the first thing to do, but it’s confusing, because when you do it you just get a shell prompt again. What happened? You’re actually in a new shell, inside of screen. To demonstrate, start a long-running command, like cat. Leave it up, and go on to

2: Detach from inside screen with “Ctrl-A d”

You should get a message saying screen detached and a shell prompt. This is the prompt from your old shell: It actually ran the command screen, the stuff between then and now was all inside screen, and now the screen command just exited and we’re back at the old shell. Now you can do whatever, log off, log back in, just don’t reboot, then

3: Reattach screen with screen -r

Hey, hey, we’re back where we were when we ran screen in step 1, and our cat is still there waiting for input! That’s the most fundamental concept, the core of screen: It keeps these pseudo-terminals going for you, while you log off, go to bed, switch computers, whatever. There’s a parent “SCREEN” process that screen made, and as long as that process sticks around, you can go back to your pseudo-terminals with screen -r. There’s one other fundamental:

4: Detach from outside screen with screen -d

When you try to reattach a session which screen already has attached elsewhere, it gives you an error. (Try it from another shell.) Maybe the network kills your connection while you’re in screen. Maybe you absent mindedly left it attached from visiting the Timbuktu regional office. Maybe you had to leave in a hurry and couldn’t do petty housekeeping like detaching your session. But you need to reattach that session here. So screen -d will detach the old connection, and now you can screen -r freely. Try it!

That’s the ultra-basics. When you’re comfortable with them, you can read about how to do copy and paste, multiple windows, multi-display, and lots of other useful features… At leisure. You’ve got the core now.

25-Jan-2006

Combinatorics: Counting with replacement

Filed under: math — jlm @ 05:14

Everyone knows the number of ways you can choose k items out of n without replacement is nCk = n!/k!(n-k)!. Often forgotten is that the number of ways to choose k items from n with replacement is n+k-1Ck. I think this is because a) it doesn’t come up as much, and b) there’s a clear intuitition behind the first formula but not so the second. So, why is the value n+k-1Ck? Proving it with induction is a simple matter, but doesn’t shed much light.

Let’s look at it differently… We can number our items 1, 2, …, n and order the k chosen items accordingly, making a non-decreasing sequence. So the problem becomes counting the non-decreasing sequences a1a2 ≤ … ≤ ak. Turn each sequence into a bar graph, so that for n=7, k=4 the sequence [3,5,5,6] becomes

[bar graph]

We can make the graph into a path from (0,1) to (k,n)

[outline path]

This path has n-1+k steps, n-1 vertical and k horizontal. Choosing one such path is choosing the k horizontal steps from the n+k-1 total, hence n+k-1Ck.

Another way to think about it is to consider the items chosen to be bins to fill with balls: Choosing at item becomes putting a ball in the bin, and the number of balls in a bin represents how many times that item was chosen. So the problem becomes count the number of ways you can put k identical balls in n bins. Start with bin 1. At each step you can put a ball into the current bin, or move to the next bin. You’ll place balls in k of the steps, and move bins in n-1 of them, so it’s a matter of choosing the k steps out of the k+n-1 total in which to place balls.

22-Jan-2006

Bad service: Kinko’s

Filed under: misc — jlm @ 17:23

Kinko’s has changed the way you make copies at its self-service copy centers: Instead of putting coins into the copy machine, you buy a card at vending machine (with $1 increments) and the copier takes the card and deducts from the card’s value. You don’t get change from unused value left on your card, you “get” to keep the card for your next use. Yeah, like it’s going to be worth 70¢ of my time to hunt around for their stupid cash card. This is not an increase in automation: The copiers used to be self-vend already, without having to detour to buy a card. It’s just getting extra money they’re not entitled to from people not using all the money on the card and customer tracking. How about using your local non-chain copy center instead? I bet they won’t end up costing 50¢ a copy if you need only two and lost your Kinko’s card.

6-Jan-2006

C++ style

Filed under: programming — jlm @ 21:44

In C, you only have call-by-value (with some wierdness for arrays). To pass a reference, you explicitly take the variable’s address. This has the benefit that you can easily tell a function call which won’t modify a variable from one which probably will:
  int i;
  f(i); /* i is unchanged */
  g(&i); /* i is likely changed */

However, for composite types, you often want to avoid making a copy when you’re not modifying the variable, so you end up with a function h(const T*) which is called as h(&x) anyway.

C++ adds call-by-reference, so that a call which looks like f(i) no longer tells you that i isn’t modified. This is a shame. Some style rules will give you the benefit of being able to tell modifying from non-modifying functions, while still getting the copy avoidance without burdening the caller with that implementation detail:
  f(T x) /* Call by value: x is a local copy. Use this when you want to play with x's value in f() without affecting the caller. */
  f(const T x) /* Call by value: x is a local copy and const. Use this for easily copied types which f() will only be reading. */

  f(T& x) /* Call by reference: x is shared with the caller and modifyable. Avoid this. */
  f(const T& x) /* Call by reference: x is shared with the caller but not modifyable. Use this for composite types which you don't want to gratuitously copy. Because x is const to f(), the caller can pretty much treat it as if f() got a copy. (The gotcha is that f() has to be aware that it'll see modifications to x made through other references, unlike with a copy.) */
  f(T* x) /* Call by pointer: Use when you want to have f() modify *x for the caller. */
  f(const T* x) /* Call by pointer, but not modifyable through it. Avoid without good casue, as this is generally semantically a call-by-reference. */

With the f(T&) case gone, we once again can be confident that f(i) won’t change i but g(&i) is likely to. More likely than with the C rules even, because we prefer f(const T&) to f(const T*) in cases where we’re merely using pointers to avoid an expensive copy. Pretty nice. Now I just need wide adoption and lint enforcement.

16-Dec-2005

Holiday poem

Filed under: politics — jlm @ 20:05

I was staying away from doing links to news and politics, but it’s a blue moon when a Congressman shows this much sense of humor.

Dingell’s Jingle

15-Dec-2005

Resetting graphics card without resetting X

Filed under: linux — jlm @ 21:00

Hmm, been a while since I put anything here. How about a tip o’ the month?

Say your graphics card gets all wonky, but you still have a lot of state in your X session which you don’t want to lose. A good thing to try is “sudo chvt 1” to switch to a text console. Then when you bring X back with Alt-F7 or whatever, the X server shifts the card back into graphics mode from a clean slate and then displays everything you have up. Of course, it doesn’t work if it’s the X server itself which is messed up, or if the card’s state is too far gone to switch to text and back.

19-Nov-2005

Philosophic musings

Filed under: philosophy — jlm @ 21:28

So, what is free will, really? Well, there’s enough answers to that question that another one can’t hurt. I consider free will to be the ability to consider the choices that one may make and decide among them. That would make the sensation of free will the feeling that one is considering choices and deciding between them.

This really boils down to what “ability” is though, and for all that it seems superficially simpler, it seems to be fundamentally tougher concept. I had corn flakes for breakfast today, but I could have had Cheerios — or could I have? This happened this morning, the past is fixed, so I couldn’t have had Cheerios because I didn’t. What does it mean to say “I could have had Cheerios.” when “I had Cheerios.” is false?

It means I was considering what to eat, and Cheerios was a choice under consideration. When we make choices, we model (consider) the result of the choices, and it’s to that model that “I could have …” refers.

The human mind is extremely complicated and poorly-understood. Let’s consider a far simpler system: A chess program on a computer. Does it have free will? Well, it needs to make decisions: Does it move this pawn, sac that knight, develop that rook? It calculates the results of all these possible actions, as thoroughly as it is able, and decides upon a move.

It goes through a lot of effort, but the programmer who designed it could tell you exactly why it chooses the move: It calculated this series of moves as being the best for both sides as near as it could figure, resulting in this board position, which it evaluated as superior to the board positions from the other possible moves, blah blah blah, the point is as a consequence of its programming it couldn’t have done anything other than queen takes pawn.

Those of us outside the program see it that way, but the program has to consider all these other moves. It has to model their consequences. It does a ton of calculation, and eventually makes a decision. It “could” have sacrificed the knight, in the sense that the decision mechanism has to consider that possibility. It “couldn’t” have done so, in the sense that its decision mechanism has to reject it.

I “could” have played hooky from work yesterday, in the sense that my decision mechanism considered the possibility and modeled the consequences. I “couldn’t” have played hooky, in the sense that my decision mechanism rejected it. That feeling of your decision mechanisms in action is the sense of free will.

14-Nov-2005

Restarting firefox after a crash

Filed under: linux, web — jlm @ 15:11

After a crash, do you get messages saying firefox is already running and to shut down your old instance before starting up a new one? You need to delete the invisible “.parentlock” file in ~/.mozilla/firefox/$profile. It might also help to kill any gconfd processes and remove any files named ior anywhere under ~/.gconf (find them with find ~/.gconf -name ior).

Why can’t these apps store some kind of host-process identifier in their lockfiles, so they can detect staleness? (See eg. screen, which easily distinguishes local-live, local-dead, and remote.) gconfd is especially annoying, because it doesn’t report the errors except to the syslog, so the user just gets the mysterious symptom of their configuration settings disappearing.

31-Oct-2005

Sea of gold

Filed under: biking, so. cal — jlm @ 17:00

It was a nice warm day today (unlike all of last week), so I rode down to the beach this afternoon as a break from work. Now, I’d heard the phrase “sea of gold” applied to the ocean before, but this was the first time I’d seen it. The angle of the sun made the vast expanse of the sea look like how you might imagine molten gold*. It was beautiful. It was also painful to look at because it was so bright. In ten minutes only the distant ocean looked golden, and in fifteen the entire effect was gone.

 


* Actual molten gold looks glowy red-orange, like pretty much any other molten metal, because the black-body radiation exceeds the reflected light.

26-Oct-2005

Protecting running scripts from modifications

Filed under: programming — jlm @ 13:48

The shell reads scripts in as it runs, and not even nicely line-by-line, so when you modify a running script, weird things can happen as the shell gets inconsistent versions. Usually this just results in harmless errors like “/home/jlxmodmap not found”, but if you’re like me you worry about “rm tmpfile; process importantfile” turning into “rm importantfile”. The usual technique for the paranoid is to “mv script script.old; cp script.old script”; the shell sees the old script, which you keep unmodified, while you edit the copy. But it’d be nice if you didn’t have to do this everytime…

So, someone told me the trick of having all the work a script does happen in a shell function, which you call at the end of your script. I’m using this for my .xsession (canonical example of a script modified while it’s running), which looks like:

main() {
  do stuff
  do more stuff
  do even more stuff
  exit
}
 
main

voilà. It’s already read in all of main() by the time it runs it, so you can modify it freely, except when it’s just starting up and parsing things.

Powered by WordPress