Fwd: Re: dangerous perl (Re: is this reasonably save?)
private IMO> On 05/24/2017 08:20 PM, lee wrote: Uri Guttmanwrites: you can get an array of hashes, where each hash is one row. learning dereferencing will do you much more good than using eval EXPR. references are key to deeper data structures in perl and are used all over the place. it is a core skill you should focus on as it will solve your current problem and many to come. Since when are there any data structures in perl? Variables are even virtually typeless. since when is a variable a data structure? :) the key is again references which still seems to confuse you. a scalar can hold only one thing. a array a list of things. a hash can hold pairs of keys/values. but most real world data is made of combinations of those things. an array of hashes is like a list of records. a hash of hashes can be keyed by names and then each subhash has data about its name. you can't make those without references. if you need help with references, this list is the place to ask. Why is it so awfully difficult to dereference a reference to an array that contains references to arrays, and why does DBI, for example, provide a function that returns such a reference? It involves holding the data in memory, so what is the supposed advantage of using cascaded references? how will you organize the data without references? they are the branches in the tree of data. returning a single reference is much more efficient than returning the whole array or hash. that would involve copying the array/hash onto the stack and then copying it again to a variable in the caller. that is very slow. you say cascaded references. i call that a data tree. it is incredibly valuable and used all over the place. as i said above most real world data is more complex than what a single hash or array can hold. think about something like what is needed to manage an editor or word processor. they need complex data trees (usually in c/c++ but the same idea). so references aren't an evil to be handled but the key to better management of data. any single slot in an array or hash can hold another array or hash via a reference. that is building up data. a phrase i use is compleity arises from layers of simplicity. a single hash is simple, a large data tree which is made from simple hashes can be very complex. references are how that works. The program(mer) will want to work with the data rather than with cascaded references to it, and in the unlikely case cascaded references would be wanted, they could still be created. The references are merely an obstacle. then how will you organize that data without references? think about it for a minute. there is no good answer to that question. if you think refs are obstacles, you have plenty to learn. data is complex so they they complex structures. life can't live in single hashes. They are also inherently dangerous because it is never obvious if some variable is a reference to something or not, and that variables are virtually typeless contributes to that. Otherwise, references could be helpful for passing data to functions. it is easy to tell. use the ref function. and if you design your structures cleanly, you generally know when a value should be a ref or a regular value. if you have to have either type, checking with ref will do the trick. For example: my $foo; Is that a reference? An integer? A float? A vector of characters? A data structure? A character? Something else? There is no way to tell. Pass it to a function and you have to ask again if it's a reference or a variable. perldoc -f ref and you rarely need to know so many different types of values in one scalar. Why don't references at least require a different notation? An 'int *foo;' tells you right away what it is. typedef struct { unsigned long MemTotal; unsigned long MemFree; unsigned long Buffers; } meminfo; so use hungarian notation in the name. $foo_ref. not what i would do but it works for that. ... also tells you what it is, and when you try to misuse it, you get an error message. It is impossible to create variables of self-defined types in perl because the variables don't have types to begin with. That includes data structures. this is perl. it is designed to allow anything to be stored in a slot. you said it earlier, it is not strongly typed which is a win for many things. an array can hold different value types. and in c you don't get deep structures without pointers and that has the same issues you seem to find with references. My limit with "data structures" in perl are strided lists. They are a poor clutch and I don't like them, but unfortunately, there are no data structures in perl. you are wrong about no data structures in perl. you will have to take my word on that (and everyone else who teaches perl). you just haven't learned references yet. once you do, it will all make more sense. They are potentially dangerous because you might fetch huge
Re: project euler #8
Ok, here's one more: [...] unless($ad) { print " * $ad = 0\n"; $start = $digit; next DIGITS; } [...] You can skip right away to behind the 0 which has already been found within the current range of adjacency. leewrites: > Sorry, I was too fast and I got it all wrong. It goes like this: > > > [...] > my $adjacency = 13; > my $maxprod = 0; > > my $start = 0; > my $exceed = length($data); > my $end = $exceed - $adjacency; > > DIGITS: > while($start < $end) { > my $prod = substr($data, $start, 1); > print $prod; > > if($prod) { > my $adjunct = 1; > my $digit = $start + $adjunct; > > while(($adjunct < $adjacency) && ($digit < $exceed)) { > my $ad = substr($data, $digit, 1); > unless($ad) { > print " * $ad = 0\n"; > next DIGITS; > } > > print " * $ad"; > $prod *= $ad; > > $adjunct++; > $digit = $start + $adjunct; > } > > print " = $prod\n"; > $maxprod = $prod if($maxprod < $prod); > } else { > print " skipping\n"; > } > } continue { > $start++; > } > > print "The largest product of $adjacency adjacent numbers is $maxprod.\n"; > > exit 0; > > > What is more expensive: Using if() statements or letting it go trough > on zeroes? Using an array or substr()? > > > > lee writes: > >> Shlomi Fish writes: >> >>> Hi all! >>> >>> Resending because the original message does not appear to have arrived at >>> the >>> list. >>> >>> = >>> >>> Hi Derrick, >>> >>> On Tue, 16 May 2017 14:01:34 +0800 >>> derr...@thecopes.me wrote: >>> Hi All, I am working on problem #8 of the euler project. see below. I have the below solution below for this which works fine but gives me the wrong answer. I checked shlomifish's solution on github and his is similar to mine, more elegant since he uses "map", but he gets a different answer. I feel like I have some basic misunderstanding about how something should work. Or maybe I am misunderstanding the problem. Thanks in advance for any push in the right direction. see my solution below. Derrick #! /usr/bin/env perl use strict; use warnings; use 5.024; use List::Util qw(max product); my $totalmax = 0; while ( my $numbline = ) { chomp $numbline; my @numbline = split //, $numbline; >>> >>> You're processing the input number line-by-line, but it's one whole number >>> and >>> the products may span across more than one line. You need to slurp it and >>> prepare an array of digits. >> >> Isn't it more efficient to put all the digits into a string rather than >> into an array and use substr()? >> >> >> With a bit extra ado you could omit, for the sake of verifyability (It >> doesn't matter in which order you do the multiplications of the adjacent >> digits as long as they are adjacent.): >> >> >> #!/usr/bin/perl >> >> use strict; >> use warnings; >> >> >> my $data = " >> 73167176531330624919225119674426574742355349194934 >> 96983520312774506326239578318016984801869478851843 >> 85861560789112949495459501737958331952853208805511 >> 12540698747158523863050715693290963295227443043557 >> 66896648950445244523161731856403098711121722383113 >> 6222989342338030813533627661428280686645238749 >> 30358907296290491560440772390713810515859307960866 >> 70172427121883998797908792274921901699720888093776 >> 65727333001053367881220235421809751254540594752243 >> 52584907711670556013604839586446706324415722155397 >> 53697817977846174064955149290862569321978468622482 >> 83972241375657056057490261407972968652414535100474 >> 82166370484403199890008895243450658541227588666881 >> 16427171479924442928230863465674813919123162824586 >> 17866458359124566529476545682848912883142607690042 >> 2421902267105562632109370544217506941658960408 >> 07198403850962455444362981230987879927244284909188 >> 84580156166097919133875499200524063689912560717606 >> 05886116467109405077541002256983155200055935729725 >> 71636269561882670428252483600823257530420752963450 >> "; >> >> $data =~ s/\n//g; >> >> my $adjacency = 13; >> my $maxprod = 0; >> >> my $start = 0; >> my $end = length($data) - $adjacency; >> >> while($start < $end) { >> my $adjunct = 1; >> my $prod = substr($data, $start, 1); >> print "$prod"; >> while($adjunct < $adjacency) { >> my $ad = substr($data, $start + $adjunct, 1); >> print " * $ad"; >> $prod *= $ad; >> $adjunct++; >> } >> print " = $prod\n"; >> $maxprod = $prod if($maxprod < $prod); >> >> $start++; >> } >> >> print "The largest product of $adjacency adjacent numbers is $maxprod.\n"; >> >> exit 0; >> >> >> Is this supposed to be a programming exercise? It's a purely >> mathematical one to me. >> >> >>> say "@numbline "; my @product = (); for (0..$#numbline - 13) { >>> >>> This should be
Re: Time::HiRes output
"Chas. Owens"writes: > You can use printf or sprintf to control the format, but what you are doing > is called profiling and it is better to use an actual profiler. Take a look > at Devel::NYTProf > > http://search.cpan.org/~timb/Devel-NYTProf-6.04/lib/Devel/NYTProf.pm > > https://www.perl.org/about/whitepapers/perl-profiling.html > > On Wed, May 24, 2017, 22:12 SSC_perl wrote: > >> I’m timing sub routines to get an idea of where my scripts spend >> the most of their time. This is an example of what I’m doing: >> >> use Time::HiRes qw( clock ); >> my $clock0 = clock(); >> ... # Do something. >> my $clock1 = clock(); >> my $clockd = $clock1 - $clock0; >> >> I’m getting values like $clock1 = 0.030259 and $clock0 = >> 0.030212. However, instead of $clockd being 0.47, it’s returning >> 4.700019e-05. I take it that’s exponential notation (?) but it’s >> actually more difficult to read than the regular number. Is there a way to >> get it to print out differently? >> >> Thanks, >> Frank >> -- >> To unsubscribe, e-mail: beginners-unsubscr...@perl.org >> For additional commands, e-mail: beginners-h...@perl.org >> http://learn.perl.org/ >> >> >> There's a method provided by Time::HiRes called 'interval' or the like which might give you nicer output. At least it saves you the subtraction. Using a profiler is not always better; it depends on what the program does. With time intervals this small, it's probably better. -- "Didn't work" is an error. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: project euler #8
Sorry, I was too fast and I got it all wrong. It goes like this: [...] my $adjacency = 13; my $maxprod = 0; my $start = 0; my $exceed = length($data); my $end = $exceed - $adjacency; DIGITS: while($start < $end) { my $prod = substr($data, $start, 1); print $prod; if($prod) { my $adjunct = 1; my $digit = $start + $adjunct; while(($adjunct < $adjacency) && ($digit < $exceed)) { my $ad = substr($data, $digit, 1); unless($ad) { print " * $ad = 0\n"; next DIGITS; } print " * $ad"; $prod *= $ad; $adjunct++; $digit = $start + $adjunct; } print " = $prod\n"; $maxprod = $prod if($maxprod < $prod); } else { print " skipping\n"; } } continue { $start++; } print "The largest product of $adjacency adjacent numbers is $maxprod.\n"; exit 0; What is more expensive: Using if() statements or letting it go trough on zeroes? Using an array or substr()? leewrites: > Shlomi Fish writes: > >> Hi all! >> >> Resending because the original message does not appear to have arrived at the >> list. >> >> = >> >> Hi Derrick, >> >> On Tue, 16 May 2017 14:01:34 +0800 >> derr...@thecopes.me wrote: >> >>> Hi All, >>> >>> I am working on problem #8 of the euler project. see below. >>> >>> >>> I have the below solution below for this which works fine but gives me the >>> wrong answer. I checked shlomifish's solution on github and his is similar >>> to >>> mine, more elegant since he uses "map", but he gets a different answer. I >>> feel like I have some basic misunderstanding about how something should >>> work. >>> Or maybe I am misunderstanding the problem. Thanks in advance for any push >>> in >>> the right direction. see my solution below. >>> >>> Derrick >>> >>> #! /usr/bin/env perl >>> >>> use strict; >>> use warnings; >>> use 5.024; >>> use List::Util qw(max product); >>> >>> my $totalmax = 0; >>> >>> while ( my $numbline = ) { >>> chomp $numbline; >>> my @numbline = split //, $numbline; >> >> You're processing the input number line-by-line, but it's one whole number >> and >> the products may span across more than one line. You need to slurp it and >> prepare an array of digits. > > Isn't it more efficient to put all the digits into a string rather than > into an array and use substr()? > > > With a bit extra ado you could omit, for the sake of verifyability (It > doesn't matter in which order you do the multiplications of the adjacent > digits as long as they are adjacent.): > > > #!/usr/bin/perl > > use strict; > use warnings; > > > my $data = " > 73167176531330624919225119674426574742355349194934 > 96983520312774506326239578318016984801869478851843 > 85861560789112949495459501737958331952853208805511 > 12540698747158523863050715693290963295227443043557 > 66896648950445244523161731856403098711121722383113 > 6222989342338030813533627661428280686645238749 > 30358907296290491560440772390713810515859307960866 > 70172427121883998797908792274921901699720888093776 > 65727333001053367881220235421809751254540594752243 > 52584907711670556013604839586446706324415722155397 > 53697817977846174064955149290862569321978468622482 > 83972241375657056057490261407972968652414535100474 > 82166370484403199890008895243450658541227588666881 > 16427171479924442928230863465674813919123162824586 > 17866458359124566529476545682848912883142607690042 > 2421902267105562632109370544217506941658960408 > 07198403850962455444362981230987879927244284909188 > 84580156166097919133875499200524063689912560717606 > 05886116467109405077541002256983155200055935729725 > 71636269561882670428252483600823257530420752963450 > "; > > $data =~ s/\n//g; > > my $adjacency = 13; > my $maxprod = 0; > > my $start = 0; > my $end = length($data) - $adjacency; > > while($start < $end) { > my $adjunct = 1; > my $prod = substr($data, $start, 1); > print "$prod"; > while($adjunct < $adjacency) { > my $ad = substr($data, $start + $adjunct, 1); > print " * $ad"; > $prod *= $ad; > $adjunct++; > } > print " = $prod\n"; > $maxprod = $prod if($maxprod < $prod); > > $start++; > } > > print "The largest product of $adjacency adjacent numbers is $maxprod.\n"; > > exit 0; > > > Is this supposed to be a programming exercise? It's a purely > mathematical one to me. > > >> >>> say "@numbline "; >>>my @product = (); >>> for (0..$#numbline - 13) { >> >> This should be "@numbline - 13" - an off-by-one error. >> >> Regards, >> >> Shlomi Fish > > -- > "Didn't work" is an error. -- "Didn't work" is an error. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: Time::HiRes output
You can use printf or sprintf to control the format, but what you are doing is called profiling and it is better to use an actual profiler. Take a look at Devel::NYTProf http://search.cpan.org/~timb/Devel-NYTProf-6.04/lib/Devel/NYTProf.pm https://www.perl.org/about/whitepapers/perl-profiling.html On Wed, May 24, 2017, 22:12 SSC_perlwrote: > I’m timing sub routines to get an idea of where my scripts spend > the most of their time. This is an example of what I’m doing: > > use Time::HiRes qw( clock ); > my $clock0 = clock(); > ... # Do something. > my $clock1 = clock(); > my $clockd = $clock1 - $clock0; > > I’m getting values like $clock1 = 0.030259 and $clock0 = > 0.030212. However, instead of $clockd being 0.47, it’s returning > 4.700019e-05. I take it that’s exponential notation (?) but it’s > actually more difficult to read than the regular number. Is there a way to > get it to print out differently? > > Thanks, > Frank > -- > To unsubscribe, e-mail: beginners-unsubscr...@perl.org > For additional commands, e-mail: beginners-h...@perl.org > http://learn.perl.org/ > > >
Time::HiRes output
I’m timing sub routines to get an idea of where my scripts spend the most of their time. This is an example of what I’m doing: use Time::HiRes qw( clock ); my $clock0 = clock(); ... # Do something. my $clock1 = clock(); my $clockd = $clock1 - $clock0; I’m getting values like $clock1 = 0.030259 and $clock0 = 0.030212. However, instead of $clockd being 0.47, it’s returning 4.700019e-05. I take it that’s exponential notation (?) but it’s actually more difficult to read than the regular number. Is there a way to get it to print out differently? Thanks, Frank -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: project euler #8
Shlomi Fishwrites: > Hi all! > > Resending because the original message does not appear to have arrived at the > list. > > = > > Hi Derrick, > > On Tue, 16 May 2017 14:01:34 +0800 > derr...@thecopes.me wrote: > >> Hi All, >> >> I am working on problem #8 of the euler project. see below. >> >> >> I have the below solution below for this which works fine but gives me the >> wrong answer. I checked shlomifish's solution on github and his is similar to >> mine, more elegant since he uses "map", but he gets a different answer. I >> feel like I have some basic misunderstanding about how something should work. >> Or maybe I am misunderstanding the problem. Thanks in advance for any push in >> the right direction. see my solution below. >> >> Derrick >> >> #! /usr/bin/env perl >> >> use strict; >> use warnings; >> use 5.024; >> use List::Util qw(max product); >> >> my $totalmax = 0; >> >> while ( my $numbline = ) { >> chomp $numbline; >> my @numbline = split //, $numbline; > > You're processing the input number line-by-line, but it's one whole number and > the products may span across more than one line. You need to slurp it and > prepare an array of digits. Isn't it more efficient to put all the digits into a string rather than into an array and use substr()? With a bit extra ado you could omit, for the sake of verifyability (It doesn't matter in which order you do the multiplications of the adjacent digits as long as they are adjacent.): #!/usr/bin/perl use strict; use warnings; my $data = " 73167176531330624919225119674426574742355349194934 96983520312774506326239578318016984801869478851843 85861560789112949495459501737958331952853208805511 12540698747158523863050715693290963295227443043557 66896648950445244523161731856403098711121722383113 6222989342338030813533627661428280686645238749 30358907296290491560440772390713810515859307960866 70172427121883998797908792274921901699720888093776 65727333001053367881220235421809751254540594752243 52584907711670556013604839586446706324415722155397 53697817977846174064955149290862569321978468622482 83972241375657056057490261407972968652414535100474 82166370484403199890008895243450658541227588666881 16427171479924442928230863465674813919123162824586 17866458359124566529476545682848912883142607690042 2421902267105562632109370544217506941658960408 07198403850962455444362981230987879927244284909188 84580156166097919133875499200524063689912560717606 05886116467109405077541002256983155200055935729725 71636269561882670428252483600823257530420752963450 "; $data =~ s/\n//g; my $adjacency = 13; my $maxprod = 0; my $start = 0; my $end = length($data) - $adjacency; while($start < $end) { my $adjunct = 1; my $prod = substr($data, $start, 1); print "$prod"; while($adjunct < $adjacency) { my $ad = substr($data, $start + $adjunct, 1); print " * $ad"; $prod *= $ad; $adjunct++; } print " = $prod\n"; $maxprod = $prod if($maxprod < $prod); $start++; } print "The largest product of $adjacency adjacent numbers is $maxprod.\n"; exit 0; Is this supposed to be a programming exercise? It's a purely mathematical one to me. > >> say "@numbline "; >>my @product = (); >> for (0..$#numbline - 13) { > > This should be "@numbline - 13" - an off-by-one error. > > Regards, > > Shlomi Fish -- "Didn't work" is an error. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/
Re: is this reasonably save?
Shawn H Coreywrites: > On Sun, 14 May 2017 18:16:50 +0100 > lee wrote: > >> Ok, do you see a way to do what I'm doing here by evaluating a block? >> > > Simply remove it. > > $sth_cmds->bind_columns(@params); But then the program doesn't work anymore ... -- "Didn't work" is an error. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/