in reply to Percentages to Fractions


Here is a simple fraction function that sometimes returns the right value. ;-)
#!/usr/bin/perl -wl use strict; sub fract { %_=(%_,$_[0],$%); ~~%_ } print fract(0.1250); print fract(0.2500); print fract(0.3750); print fract(0.5000); print fract(0.6249); print fract(0.7510); print fract(0.8750); __END__ Prints: 1/8 2/8 3/8 4/8 5/8 6/8 7/8

Update: This is just a joke and apparently not a very good one. Don't use this code.

--
John.

Replies are listed 'Best First'.
Re: Re: Percentages to Fractions
by ihb (Deacon) on Apr 13, 2004 at 02:16 UTC

    I feel an urge to explain how &fract works or rather doesn't work, especially since it's the first reply.

    The function is complete bogus. It doesn't bother at all which argument it gets (as long as it hasn't been given before). What it does is to populate a hash and then stringify it, returning a string "$used_buckets/$allocated_buckets" (a buckets isn't equal to a value). More on this is in the perldata manual, but here's the relevant excerpt.

    If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash. -- perldata 5.8.0

    The line

    %_=(%_,$_[0],$%);
    works like
    $_{$_[0]} = $%;
    except the latter is more efficient and doesn't copy the hash over and over again. I guess why it was written like that was to try to make it non-obvious at a first glance that it uses an accumulating global variable.

    The $% variable happens to be a special variable but that's quite irrelevant. It could've been mostly any scalar and I can only assume that $% was chosen because of the obfuscation effect. However, as I pointed out here, the hash algorithm sometimes share values and hence sometimes just uses one bucket, making the function not work as intended.

    The ~~ is actually the unary operator ~ applied twice. ~ is bitwise negation, and if you doubly negate you get the original back. The side-effect is that you put the operand in scalar context, which is what's used here.

    ihb

Re: Re: Percentages to Fractions
by ihb (Deacon) on Apr 13, 2004 at 02:40 UTC

    This is slightly off-topic but I can't resist expressing my dislike for this post to which I'm replying. Writing a bogus routine that seems to do what's expected, even with test cases, and without strong indication that it's just a hoax as first reply to a serious question is just despicable. It contributes nothing but confusion. Sure, cute code can be fun but it should be in the right place. The first reply to a serious question is definately not the right place. Making it look like a serious reply doesn't make it any better. If one truly does want to contribute one would also include an explanation of how the cute code works. Otherwise it's just showoff.

    The smilie and the "sometimes" hints you about it being bogus, but the "sometimes" can easily be interpreted as "it tries to make a qualified guess but sometimes fails" (in contrast of long, slow but working algorithms), especially since it provides several test cases. I can't blame any new Perl programmer that think "hey, cool, yet another guru trick" when looking at the above routine with all its, to the new Perler, new elements: %_, $%, and ~~. (Compare with the fairly common my $file = do { local (@ARGV, $/) = $filename; <> };, except that works.)

    To broaden this post I'd like to encourage everyone to follow Ovid's (I believe, can't find the reference now) example of waiting a while for the question to be answered before posting cute solutions or getting into side-track discussions.

    What scares me though is that the post has a fairly high reputation in comparison to the replies which provide solutions that actually work.

    Just my thoughts,
    ihb


      It was a joke.

      It said "sometimes" and it had a wink.

      Yes, it would be better if it wasn't the first reply.

      --
      John.