Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Friday May 09, 2008
04:11 AM

Java/Perl

[ #36367 ]

For a party game, needed to repeatedly pick random letters from the (ASCII) alphabet. I had my laptop, so I just did it. A friend, a Java programmer, was amazed. My favorite part was when he said "you're going to type out all 26 letters, aren't you?" Um, no I'm not.

perl -le "print ['a' .. 'z']->[rand(26)] while <STDIN>"

For those not quite getting it, here's the shortest I could think of in Java (without getting to the point of obfuscation and with the caveat that they're functionally equivalent, though internally they handle things in a moderately different way):

import java.io.*;

class Pick {
    public static void main(String[] args) {
        String letters    = "abcdefghijklmnopqrstuvwxyz";
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        while (true) {
            try {
                br.readLine();
            }
            catch (IOException e) {
                System.out.println("Caught exception trying to readline: " + e);
                System.exit(1);
            }
            int rand = (int)(Math.random() * 26);
            System.out.println(letters.charAt(rand));
        }
    }
}

Of course, then you have to compile it and run it as separate steps.

Can anyone post any common code snippets which express themselves more naturally in Java than Perl? (Libraries which can be readily duplicated in Perl don't count)

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • i usually write that as

    perl -le 'print chr(65+rand(26))'

    your version is prettier, though :)

    (sorry, i'm not a java person)
    --
    bgp is for those who can't keep it static long enough
    • Damn. I thought my version is crystal clear, but yours is just perfect and obvious -- if you know ASCII.

      And doing that in Java:

      import java.io.*;

      class Pick {
          public static void main(String[] args) {
              BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
              while (true) {
                  try {
                      br.readLine();
               

      • I Don't Speak Java, But:

        If this is for a party game, isn't the exception handling gratuitous? Whether it fails with a stack track or a nice error message, it's screwed up. Can't you just omit that?

        Why do you need the reader at all? Is there some requirement that you must read from stdin if you want to send to stdout?
        --
        rjbs
        • The reason for the reader is that the game were were playing required we think of words for categories but each word had to start with a particular letter. The reader was there to ensure we could just hit "Enter" and get the next letter. So if we just rerun java Pick every time, we can get it to this:

          class Pick {
              public static void main(String[] args) {
                  System.out.println((char)( 65 + (int)(Math.random() * 26)));
              }
          }

          This doesn't replicate the exact

        • As Ovid points out, you do have to do something about the exception because it is a checked exception. But my preferred choice in this case would be to declare that main() throws the exceptions [perl.org], thus letting the calling environment handle it, because, as you say, if it's screwed up, it's screwed up, no matter how it chooses to express the failure.

          Ovid, did you know you could throw exceptions from main()?

          How much have we shortened your Java code, now? :)

          --
          J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
          • I had never heard of checked exceptions. I can see their value, but I think I'd find the more irritating than useful unless I could disable them for one-offs.

            Thanks!
            --
            rjbs
            • Checked exceptions are evil. They sound good, until you try them. Bruce Eckel, the author of Thinking in Java [amazon.com], has a great essay about the problems with checked exceptions [mindview.net].

              • Checked exceptions are extremely valuable when designing or using APIs. Most of the pain comes from misuse. Used properly, you only have to deal with them when you really should write error handling anyway. But I didn't create this account to enter that endless debate. I just wanted to point out that its in the nature of the difference strengths of Java and Perl that you can't post a piece of code where Java is more natural. Its only when dealing with large bodies of code that Java's strength is appare
                • Its only when dealing with large bodies of code that Java's strength is apparent.

                  Funny; I consider Java's encouragement to produce large bodies of code a disadvantage.

                • Okay, I got a half-million lines of Java here, judging by just a second ago when I did a find . -name '*.java' | xargs wc -l. When do the advantages start becoming apparent?

                  (Okay, to be fair, I can see some advantages. But if I were starting this from scratch, yes, it would be Perl!)

                  --
                  J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
    • That can come across as slightly more documented if you say:

      perl -le 'print chr(ord('A')+rand(26))'

      Then you don't have the potentially mystifying 65. (I fess up; I always have to look up the value of 'A' on an ASCII chart whenever I want to do anything like this.)

      Some languages will basically treat 'A' as an int and allow you to drop the ord(). Not Perl. Might work for Java, though.

      --
      J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
      • Some languages will basically treat ‘A’ as an int and allow you to drop the ord(). Not Perl.

        perl -le'$a="A";$a++for 1..rand 26;print$a'

  • Note: for some reason, I've never been the life of the party....

    You're generating random letters: what does that mean? Say someone asks me for a random letter. I say 'e'. They ask again for a random letter, I say 'e' again. They ask again, I say 'e'. Then I start saying 'e' even before they ask. In an annoying whiny voice.

    And I repeat this for the duration of our natural lives.

    What makes this sequence of perhaps ONE MILLION [youtube.com] 'e's less random than a sequence of letters generated by a computer program?

    • The probability that such a sequence is the result of a truly random process is infinitely much smaller than the probability of winning the lottery and being hit by lightning on the same day. This is known as a statistical impossibility: it could happen, but the odds are stacked so high against it that it never does.

  • It could be shortened if you're allowed to pipe it to head or a pager. Then you could dispense with the input part and just put it in an infinite loop. I'm not sure if using the shell and other commands means you've gone out of the realm of "accomplishing this in Java" or not, but it is more or less functionally equivalent.

    --
    J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
  • Usually I end up writing golfish code like this:

    perl -ple'$_=(a..z)[rand 26]'
  • We recently had our county legislative district caucuses for the Republican Party. The party rules say, in some cases, in the event of a tie, to decide the winner by lot. We had a 7-way tie (with each potential delegate assigned a number), for 6 positions (and since this was for alternate delegates, we needed them in a specific order).

    So I whipped out my laptop and wrote something along the lines of:

    perl -le '@a=qw(6 23 57 72 75 78 80); print $a[rand @a]'

    Got a winner, then removed that winner from @a

    • That has a subtle bias: picking 1 out of 6 after picking 1 out of 7 does not have the same probability distribution as picking 2 out of 7. The stochastically unbiased way would be thus:

      perl -MList::Util=shuffle -le'print +(shuffle 6 23 57 72 75 78 80)[0..5]'
      • Err, make that print for (...).

      • That has a subtle bias: picking 1 out of 6 after picking 1 out of 7 does not have the same probability distribution as picking 2 out of 7.

        True, but it doesn't need to. The traditional way to do these things, which is to draw straws, eliminating one person at a time, has the same bias. Indeed, I am not so sure that your way is better: we literally do have a 7-way tie for one place, and then after eliminating the 7th place, we have a 6-way tie for the next place.

        The rules give us no guidance either way, but I think my method is closer to the spirit of the thing (which is why it is how it is). I doubt that anyone would complain with either m

        • I like you're method better simply because the algorithm is more readily open for inspection. Not that you can't check out the contents of the module in the other method, but with yours what happened is up front.

          --
          J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
          • If you really wanted to be sure the algorithm is correct, in either case, you’d have to inspect how rand works…

            Writing a Fisher-Yates shuffle (which is what’s in List::Util) by hand is easy: you step through the list, swapping each element with any random following element or itself (this bit is crucial to avoid bias). It was just quicker to use the one in List::Util, and much less prone to errors in the haste of dashing off a one-liner.