Skip navigation

School Of Redundancy School

I watched a short presentation on subtext the other day, which focused on the difficulty with reading Boolean expressions. Under it’s influence, I made a slightly more verbose, nested expression out of a simpler one:

    if opts.p and opts.u:
        pass
    else:
        if opts.p or opts.u:
            parser.error("please specify a user and pass")

Where’s the wisdom in that? I think it lay in the else, which explicitly subordinates the second conditional to the first. I could have made it:

    if not (opts.p and opts.u):
        if opts.p or opts.u:
            parser.error("please specify a user and pass")

I hate parenthesis in Python conditionals — don’t know why.

Advertisements

Reddit, YC News & Bash.org

They are destroying my life. Might as well face it, I’m addicted to LOL.

I spend so much time ‘keeping up’ that I can’t watch the lecture on Adjunctions posted by the Catsters, or get anywhere with writing a file system. I need to strictly ration my consumption of “net candy”.

Sysadmins Against eMail — SAM

Band together to destory email. Everything can be done with Jabber and thoughtful allocation of chat rooms.

Why I Will Not Switch To Mercurial

Mercurial is fast, smooth, cool, strong, powerful, and sweet. It’s the easiest to get on the distributed version control train, the train to Coolsville.

If only it had efficient copies, easy server interaction and the ability to check out part of a repository. That’s really the last straw for me. I can’t feel good about repositories that must be checked out all at once or not at all.

CGI — just too much

I spent several hours today trying to feed a CGI script form stdin before I realized you had to set the CONTENT_TYPE, CONTENT_LENGTH and REQUEST_METHOD environment variables in order to emulate a POST correctly. It’d be simpler if:

  • All content (GET or POST) were available from stdin — even the ‘variables’.
  • The CONTENT_TYPE were available in the environment, but CONTENT_LENGTH were simply ignored — the web server should be handling “request validation”, anyhow.

Many command line programs could be called directly with the interface I suggest.

Here’s a shell script that talks to a CGI:

#!/bin/sh
##
##  Testing CGIs from the command line is a little tricky.
##
##


if [ $# -gt 1 ]
then
  content="$1"
else
  content='
    some rubbish,numbers
    other rubbish,more numbers
    '
fi


export CONTENT_TYPE="text/csv"
export REQUEST_METHOD="POST"
export CONTENT_LENGTH=`echo "$content" | wc -c`


echo "$content" | some-cgi.py

Potential improvements include reading from stdin, accepting an option to define the program to be run, &c.

HIRC

Consider Heirarchial IRC channels — everyone ‘below’ a node in the tree receives all messages directed to that node of the tree and all it’s parents. Does this seem useless? Consider a neat hack for ‘first-classifying’ users into the channel system — auto-join all users to #user, with their user names — using IRC URLs, this looks like:

  irc://freenode.net/users/jsnx

If you wanted to broadcast to all users, that’s irc://freenode.net/users. Similarly, you could autojoin the admins to #admin as well as #user, allowing them to chat amongst themselves and be addressed as a group. There is some weirdness in this, though, because you’d either have a lot chat windows open at one time or they’d magically open and close. Also, the user’s private message channel would be shared amongst all the people that are messaging that user!

rewarding survival leads to cooperation

It would be nice to encourage spontaneous cooperative play in competitive games, like death match. By scoring on survival, you get a system that encourages ad-hoc teamwork without any fancy ‘teaming’ algorithms.

Consider a system that scores a player based on two parameters — the amount of time they’ve played, and the number of times they’ve died. The player with the lowest death rate is the best; their rating is how much higher their mean survival time is than that of the other players:

// mean of player i
mi = ti / di
// average of others
oi = (mi – ∑ m) / (1 – n)
// rating of player i
ri = mi / oi

The rating reduces to 1 for the average player. There is thus no reward for a bunch of people logging in to a level and hanging out, as that will just cause their scores to converge. This formula can be applied in a game, across games and across game servers to rate players in a uniform manner, re-normalizing at each hop.

How does this formula reward cooperation? While beating down other players is a sure way to reduce oi, surviving longer is a more powerful way to grow your score. A small number of players, working together, can reduce the survival rate of other players while enhancing their own. If too many players work together, however, then oi gets big, reducing the payoff for all concerned. Basically, you want the smallest group of players who can effectively defend one another or launch an assault — and that depends on the situation. If two players come across a jeep with a gun in the back, they can kill each or they can ride around in the jeep, jinking and weaving and blasting rocket dudes to survive. On the other hand, if it’s a tank, you might need four people to get good mileage out of that, so it’s better for one of the players to kill the other.

It’s worth examining how reweighting the time — multiplying by the number of players in the arena, for example — can encourage players to take on the risk of deadlier arenas. How can we make the score for survival depend on the skill of the other players? This has a non-linear flavor and I will leave it to another time.

duck terrine is good

Is this stuff raw? There’s nothing like fatty duck meat on hot bread!

recover your lost keywords

I mess up /etc/portage/package.keywords every so often, like this:

  echo "foo ~x86" > /etc/portage/package.keywords

A small typo — the > should be >> — that overwrites all the other keyword lines. Last night, I was on #gentoo and figured out how to get all the names of the testing packages back, using equery:

#!/bin/sh
##
##  when i delete /etc/portage/package.keywords, this script
##  will recover the names of installed packages that are ~arch
##

fetch() {
  equery --no-pipe list
}

are_testing() {
  egrep '\[.~\]'
}

no_version() {
  sed -r 's/-[^-]+(-r[[:digit:]])?$//'
}

no_meta() {
  cut -d ']' -f 3 | cut -d ' ' -f 2
}

fetch | are_testing | no_meta | no_version 

shell tricks

A shell function can be treated just like a ‘command’ — you can pipe input to it and stuff. I don’t know why it took me so long to figure it out. Here is a nice example:

errfmt() {
  awk '{ printf "  %68s  %s", $0, ".:!!:." }'
}

echo "please specify at least one file" | errfmt >&2

Guess what it does…