Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

First Run

by TheloniusMonk (Sexton)
on Aug 24, 2018 at 12:09 UTC ( [id://1221021]=poem: print w/replies, xml ) Need Help??

Complexly deirid fearedness displicency Vulcanalian pre-estival Marlowish nonpressure craniologist.
Desmitis phonographist resicken pretext's physicotherapeutics engregge gentlewomanlike.
Premidsummer DeHoff Healy Varden washery Gioconda.
Damselfly aircheck cyte Cyclops salver dipsades.
Uneruptive abducing exacinate Elata effatum renewing Mulloy loll-shraub.
Christoforo lepidodendraceous renewer chiefer Ayyubid laryngoscopies.
Leave-taking clustered oversteer dreamy-eyed.
Loan-sharking salamo doubtfulness nonseizure underclift pudicity clasper.
Brevirostrines soliloquizes.
Inexactness aardwolf stunsle MOA proverbialize strangest nemophilist well-disposedness.
Demoralizers vinas feulamort twin-jet asperser.
Touchup polionotus ungamboled Hebrician hissy supertragedy aping prologulogi metisse inhiate.
Antoninianus unexperient saintship long-fleeced.
Knitting sulfurosyl rose-wreathed sporophytic rozzers subverters windmill-like butter winch macronuclear.
Intramuralism slow-legged mymarid embryotrophe.
Thermidor BITNET.
Reappraiser poinsettias mcg Gaut.
Me. halte.
Dependent Laspeyresia Shanna subdeaconry unclannishly drears Schools spitefullest wordhoard rain-bleared.
Catnapers unbilleted.
Kahikatea stick-out menaced word-of-mouth pycnogonidium close-rounded encages Lesotho Cilka.
Unwaded long-shanked salinize Dionysiacal saracens negotiator cloud-surmounting.
#!/usr/bin/perl use strict; use warnings; my @words = <DATA>; chomp @words; my $length = 5 + 20*rand(); { use integer; $length += 0; } for my $line (0..$length) { $line and print ".\n"; my $width = 9*rand(); { use integer; $width++; } for my $word ( 0..$width ) { my $where = $#words * rand(); { use integer; $where += 0; } my $choose = $words[$where]; unless ($word) { $choose =~ /^(.)(.*)$/; $choose = uc($1) . $2; } $word and $choose = " $choose"; print $choose; } } print ".\n"; __DATA__ 2 1080 &c 10-point 10th 11-point 12-point etc. for rest of English words
Update: to do: categorise and decline/conjugate by part of speech. Prioritise common words like and, the, etc. Avoid semi-duplication (renewer/renewing in above run)

Replies are listed 'Best First'.
Re: First Run
by Lotus1 (Vicar) on Sep 04, 2018 at 21:10 UTC
    #!/usr/bin/perl use strict; use warnings; my @words = <DATA>; chomp @words; my $length = 5 + 20*rand(); { use integer; $length += 0; }

    Why use integer for one line? The documentation for rand() shows exactly how to do the same thing with int().

    for my $line (0..$length) { #prints length + 1 lines.

    There is an off by one error here since 0 to $length is $length+1 lines.

    $line and print ".-$line.\n";

    Printing the last character on the first line of the loop is silly. You end up needing another print to put in the period for the last line.

    my $width = int( 9*rand() ); { use integer; $width++; }

    This doesn't change $width to an integer. Refer to integer

    Now, it so happens that the pre- and post- increment and decrement operators, ++ and --,
    are not affected by use integer; either. Some may rightly consider this to be a bug --
    but at least it's a long-standing one.

    for my $word ( 0..$width ) {

    Another off by one error.

    my $where = $#words * rand();

    This will never pick the last element in the array.

    { use integer; $where += 0; } my $choose = $words[$where]; unless ($word) { $choose =~ /^(.)(.*)$/; $choose = uc($1) . $2; }

    If you don't want to use ucfirst() then s/^(.)/\u$1/ would be simpler.

    $word and $choose = " $choose"; print $choose; } } print ".\n"; __DATA__ 2 1080 &c 10-point 10th 11-point 12-point etc. for rest of English words
      Many thanks for the review!!!
Re: First Run (updated)
by AnomalousMonk (Archbishop) on Sep 05, 2018 at 14:59 UTC

    The following depends heavily on the fact that certain operations, e.g.,  .. (range) and array indexing, are inherently integer operations. (BTW: The Windoze rand is not adequate for dealing with a large body of data like this; it's 15-bit IIRC!)

    c:\@Work\Perl\monks>perl -wMstrict -le "chomp(my @words = <>); ;; for (1 .. 5 + rand 20) { my @line = map $words[ rand @words ], 0 .. rand 10; if ($#line) { $_ = ucfirst for $line[ 1 + rand $#line ] } print qq{\u@line.}; } " ..\..\moby\mwords\354984si.ngl Ouabaio soldiers loob Piedmontite phenylated nol. Zolle Torque ghbor. Oxygenicity Subpharyngal gastroscopic ventricular trainways incombinin +g indulgement avidin idiorepulsive. Understaff. Becrawls subclavicular Combustive. Wrestlers occluding cryptonema novelizations epexegesis legpulling def +icient publici phalangean Monkeyflower.

    I think there's only one line that requires comment. TheloniusMonk's word corpus apparently includes capitalized and hyphenated words; mine doesn't. I'm not going to try to simulate hyphenated words, but I wanted, don't ask me why, to stick one capitalized word into each line to make my output look a little more like the OPed output. So the
        if ($#line) { $_ = ucfirst for $line[ 1 + rand $#line ] }
    statement capitalizes a word other than the first in the line if the line has more than one word. (Update: The for statement modifier simply topicalizes the word randomly chosen from the array.) Whatever...

    Update: I should have looked at Lotus1's Creating random sentences from a dictionary first. This post is essentially the same. Oh, well...


    Give a man a fish:  <%-{-{-{-<

      I should have looked at Lotus1's Creating random sentences from a dictionary first. This post is essentially the same. Oh, well...

      It's the same approach but your solution is much more Perlish. I probably should have posted my solution in this thread. I liked how you did print qq{\u@line.}. I hadn't realized '\u' would only affect the first word since the array becomes a string. Also you can put the period at the end. This will be useful for me.

      In the line my @line = map $words[ rand @words ], 0 .. rand 10;I had already figured out that the range operator only returns integers so no need for int() on the rand 10 to feed into the map. But I didn't realize that 0 .. 0 would still give you one element for map so that was a very useful thing for me as well.

      (BTW: The Windoze rand is not adequate for dealing with a large body of data like this; it's 15-bit IIRC!)

      I found this stackoverflow article that says the value from rand(arg) is

      (arg * RAND) ------------- 2**randbits

      where RAND is a value from 0 to 2**randbits - 1. 'randbits' is a value that Perl is compiled with and can be found with the command perl -V:randbits. I found for 64 bit ActivePerl on my Windows 7 machine it is 15. On the same machine 32 bit Strawberry perl has randbits = 48. I've been trying to think of a way to test this but haven't arrived at anything.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: poem [id://1221021]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (2)
As of 2024-04-25 06:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found