Re: Schwartzian transform

2014-08-13 Thread Uri Guttman

On 08/13/2014 05:33 AM, Dermot wrote:

Hi

Sorry for the OT post :)

I am trying to transform the hash reference below so that the value of
position is ordered from 1..4. The sorting works but I can't seem to modify
the value of {position} inline. To achieve what I want I have to look
through the @sorted array. I'd like to golf this if I can but I've hit a
wall.


check out Sort::Maker which can generate and rub an ST for you. it can 
also generate the faster GRT style sort.


uri


--
Uri Guttman - The Perl Hunter
The Best Perl Jobs, The Best Perl Hackers
http://PerlHunter.com


Re: Schwartzian transform

2014-08-13 Thread Abigail
On Wed, Aug 13, 2014 at 01:45:24PM +0100, Dermot wrote:
> On 13 August 2014 13:24, Abigail  wrote:
> 
> > On Wed, Aug 13, 2014 at 09:45:59PM +1000, Damian Conway wrote:
> > > Mark and Aaron are ntirely correct that the ST is not required for your
> > example,
> > > but if your actual application uses a significantly larger dataset than
> > just
> > > four hash entries, then the ST may still be preferable...as array lookups
> > > are around twice as fast as hash lookups. That might be a significant
> > > performance enhancement if you have to do O(NlogN) key look-ups for
> > > a sufficiently large value of N.
> > >
> > > As always, only benchmarking on real(istic) data can determine whether
> > > you will actually benefit from using the ST or not.
> >
> >
> > But if your dataset is that large that you will benefit from halving
> > the lookup time, you can save twice the amount of time by not having
> > a lookup time at all -- use the Guttman-Rossler Transform.
> >
> >
> Does anyone want to venture a guess - highly un-scientific I know but I am,
> after all, an instinctive guy - at what the sweet spot for N would be? The
> entire data set is about 500,000 records but I doubt that my data structure
> would stretch to more than 90 records as these are user created selection.
> If N is < 90, I'll opt for ''for'.


90 is a very low number. If your dataset is 90 or less, it's unlikely 
to matter whether your wrap your sort in a transform or not -- unless
you're running on some hardware from the early 70s.


But where the flip over point will be depends on many, many factors, 
and even a ball park figure can only be done after testing with
real data, on the *same environment* as where your production code
will run. Just a handful of factors that matter:

  - Perl version
  - Hash function used
  - Compiler/compiler options
  - CPU Architecture
  - Memory (amount of free memory, speed of memory/caches)
  - Total size of program
  - Sort function used by Perl (mergesort, quicksort)
  - How sorted the data is to begin with (matters a lot for mergesort,
less for quicksort -- although if it comes from a hash, it's
pretty random, and, in the most recent versions of Perl, will be
different from run to run).

If you want to know, *measure*. And all that measurement gives you, at
best, is a ball park figure. Do remember that performing proper measurements
is a third art, a third science, a third engineering, and a third magic.


And that's not even factoring in that the time spend sorting (regardless 
of the sort) may be dwarved by whatever else the program is doing.


Abigail


Re: Schwartzian transform

2014-08-13 Thread Dermot
On 13 August 2014 13:24, Abigail  wrote:

> On Wed, Aug 13, 2014 at 09:45:59PM +1000, Damian Conway wrote:
> > Mark and Aaron are ntirely correct that the ST is not required for your
> example,
> > but if your actual application uses a significantly larger dataset than
> just
> > four hash entries, then the ST may still be preferable...as array lookups
> > are around twice as fast as hash lookups. That might be a significant
> > performance enhancement if you have to do O(NlogN) key look-ups for
> > a sufficiently large value of N.
> >
> > As always, only benchmarking on real(istic) data can determine whether
> > you will actually benefit from using the ST or not.
>
>
> But if your dataset is that large that you will benefit from halving
> the lookup time, you can save twice the amount of time by not having
> a lookup time at all -- use the Guttman-Rossler Transform.
>
>
Does anyone want to venture a guess - highly un-scientific I know but I am,
after all, an instinctive guy - at what the sweet spot for N would be? The
entire data set is about 500,000 records but I doubt that my data structure
would stretch to more than 90 records as these are user created selection.
If N is < 90, I'll opt for ''for'.
Dermot.


Re: [dancer-users] Sad news regarding James Aitken (LoonyPandora), Dancer contributor and pluign author

2014-08-13 Thread Mike Whitaker
That's awful. He was a great bloke, and I enjoyed our chats on #dancer.

On 13 Aug 2014, at 10:23, David Precious  wrote:

> 
> Hi all,
> 
> (Posted this to dancer-users first; it was suggested that it be posted
> to london-pm too as several mongers had met/knew James.)
> 
> 
> Sadly, my friend and colleague James Aitken (LoonyPandora/JAITKEN), who
> contributed to Dancer and wrote several Dancer plugins, died
> unexpectedly last week.
> 
> He was hit by a car back in June and suffered head injuries, but had
> mostly recovered - but then took a sudden turn for the worse, and passed
> away last week.  Details as to exactly what happened are still sketchy
> at this point.
> 
> Due to how unexpected it all was and the fact he has no immediate
> family / next of kin, he will receive a very very basic state-funded
> "pauper's funeral" unless enough money is raised to cover the cost of a
> proper funeral - so his ex-girlfriend set up a fundraising page to
> accept donations towards the cost:
> 
> http://gogetfunding.com/project/james-aitken-s-funeral
> 
> If you used his code and found it useful, and have a couple of quid to
> spare, any donations would be very much appreciated.  If you cannot,
> but he or his code made a difference to you, you can still leave a
> comment there if you'd like.
> 
> 
> Dave P
> 
> 
> -- 
> David Precious ("bigpresh") 
> http://www.preshweb.co.uk/ www.preshweb.co.uk/twitter
> www.preshweb.co.uk/linkedinwww.preshweb.co.uk/facebook
> www.preshweb.co.uk/cpanwww.preshweb.co.uk/github
> 
> 



Re: Schwartzian transform

2014-08-13 Thread Abigail
On Wed, Aug 13, 2014 at 09:45:59PM +1000, Damian Conway wrote:
> Mark and Aaron are ntirely correct that the ST is not required for your 
> example,
> but if your actual application uses a significantly larger dataset than just
> four hash entries, then the ST may still be preferable...as array lookups
> are around twice as fast as hash lookups. That might be a significant
> performance enhancement if you have to do O(NlogN) key look-ups for
> a sufficiently large value of N.
> 
> As always, only benchmarking on real(istic) data can determine whether
> you will actually benefit from using the ST or not.


But if your dataset is that large that you will benefit from halving
the lookup time, you can save twice the amount of time by not having
a lookup time at all -- use the Guttman-Rossler Transform.

Here's an (untested) version of the GRT which doesn't require "position"
to be a single digit integer. Instead, we assume both the keys of %$ref
and "positions" are integers:

my $count = 0;

my @sorted_records =
map  {my $r = $$ref {(unpack "LL", $_) [1]};
$$r {position} = ++ $count; $r}
sort
map  {pack "LL" => 0 + $$ref {$_} {position}, $_} keys %$ref;



Abigail


Re: Schwartzian transform

2014-08-13 Thread Damian Conway
> In the absence of such benchmarking (and also in the absence of any
> indication of a performance issue) I think the approach of directly
> sorting the hash refs wins merely by virtue of being so much simpler.

Agreed.

Although, I took the the use of the ST in the original code
as precisely that: an "indication of a performance issue".

Of course, given that Dermot just admitted that he's coding by pure
instinct, that inference was clearly unwarranted. ;-)

Damian


Re: Schwartzian transform

2014-08-13 Thread Dermot
On 13 August 2014 12:17, Aaron Crane  wrote:

> Dermot  wrote:
> > my $count = 1;
> > my @sorted =
> > map { $ref->{ $_->[0] }->{position} = $count++; $ref->{ $_->[0] } }
> > sort { $a->[1] <=> $b->[1] }
> > map [ $_, $ref->{$_}->{position} ],
> > keys %{ $ref };
>
> It's not clear to me that the Schwartzian Transform adds anything to
> this code: with it, you have to create an array ref for every input
> hash ref, and then sort by an element of each array ref, but without
> it, you could simply sort by an element of each input hash ref:
>
> my @sorted = sort { $a->{position} <=> $b->{position} } values %$ref;
> ...
> If you don't actually need to keep @sorted around, the whole thing can
> be even simpler:
>
> my $position = 1;
> $_->{position} = $position++
> for sort { $a->{position} <=> $b->{position} } values %$ref;
>
> I've also renamed your $count variable to $position, because I think
> that more accurately reflects what it contains.
>
>
I agree with everything you said. It was pure instinct to reach for map()
and thereafter it was the challenge that interested me. The version you and
Mark have posted is by far clearer and I suspect more efficient.
Thank you.
Dermot.


Re: Schwartzian transform

2014-08-13 Thread Aaron Crane
Damian Conway  wrote:
> Mark and Aaron are ntirely correct that the ST is not required for your 
> example,
> but if your actual application uses a significantly larger dataset than just
> four hash entries, then the ST may still be preferable...as array lookups
> are around twice as fast as hash lookups. That might be a significant
> performance enhancement if you have to do O(NlogN) key look-ups for
> a sufficiently large value of N.

Indeed. But if N is sufficiently large, it's probably worth using
Sort::Key over either the plain hash-ref version or the ST version:

use Sort::Key qw;
my @sorted = nkeysort { $_->{position} } values %$ref;

I think that's still a lot clearer than the code you get with the ST
map/sort/map dance.

> As always, only benchmarking on real(istic) data can determine whether
> you will actually benefit from using the ST or not.

I agree wholeheartedly. In the absence of such benchmarking (and also
in the absence of any indication of a performance issue) I think the
approach of directly sorting the hash refs wins merely by virtue of
being so much simpler.

-- 
Aaron Crane ** http://aaroncrane.co.uk/


Re: Lazy sort (was Re: Schwartzian transform)

2014-08-13 Thread Mallory van Achterberg
On Wed, Aug 13, 2014 at 01:28:57PM +0200, Abigail wrote:
> [1] Well, it may depend on what definition of lazy you mean. Obviously,
> you can't "lazyly" [3] sort an infinite list, as you need to process
> all elements at least once to be able to return a first element.
> But using, for instance, heapsort, you can return the first k elements
> of a list in sorted order in O (N + k log N) time, which beats
> O (N log N) if k << N.
[ snip ]
> 
> [3] Is this a real word?
> 

"Lazily", yes.

-Mallory


Re: Lazy sort (was Re: Schwartzian transform)

2014-08-13 Thread Damian Conway
Abigail asked:

> [3] Is ["lazyly"] a real word?

Very nearly. "Lazily" is the generally accepted spelling.

Though I guess one could argue that "lazyly" is "lazily" spelt lazily,
and hence is even more correct. ;-)

Damian


Re: Schwartzian transform

2014-08-13 Thread Damian Conway
Mark and Aaron are ntirely correct that the ST is not required for your example,
but if your actual application uses a significantly larger dataset than just
four hash entries, then the ST may still be preferable...as array lookups
are around twice as fast as hash lookups. That might be a significant
performance enhancement if you have to do O(NlogN) key look-ups for
a sufficiently large value of N.

As always, only benchmarking on real(istic) data can determine whether
you will actually benefit from using the ST or not.

And, FWIW, I'd have written the shorter version as:

my @sorted_records
= sort { $a->{position} <=> $b->{position} }
   values %{$ref};

my $next_position = 1;
for my $next_record (@sorted_records) {
$next_record->{position} = $next_position++;
}

...to maximize long-term maintainability.

Damian


Lazy sort (was Re: Schwartzian transform)

2014-08-13 Thread Abigail
On Wed, Aug 13, 2014 at 01:13:42PM +0200, Mark Overmeer wrote:
> 
> Sort is not lazy (cannot be lazy), so this suffices:

Perls current implementation of sort isn't lazy, but I see no reason
why sort cannot be lazy [1] [2]. If only the first 10 elements of the output
of sort are needed, there's no reason to sort the rest of the list.


[1] Well, it may depend on what definition of lazy you mean. Obviously,
you can't "lazyly" [3] sort an infinite list, as you need to process
all elements at least once to be able to return a first element.
But using, for instance, heapsort, you can return the first k elements
of a list in sorted order in O (N + k log N) time, which beats
O (N log N) if k << N.

[2] Of course, the answer to "do you want sort to be lazy?" is probably no,
as it gains you little.

[3] Is this a real word?



Abigail


Re: Schwartzian transform

2014-08-13 Thread Aaron Crane
Dermot  wrote:
> my $count = 1;
> my @sorted =
> map { $ref->{ $_->[0] }->{position} = $count++; $ref->{ $_->[0] } }
> sort { $a->[1] <=> $b->[1] }
> map [ $_, $ref->{$_}->{position} ],
> keys %{ $ref };

It's not clear to me that the Schwartzian Transform adds anything to
this code: with it, you have to create an array ref for every input
hash ref, and then sort by an element of each array ref, but without
it, you could simply sort by an element of each input hash ref:

my @sorted = sort { $a->{position} <=> $b->{position} } values %$ref;

I haven't measured the relative execution speed of this code and the
version using the Schwartzian Transform; I think the enormous increase
in clarity you get this way will outweigh any speed improvement you
might get from the ST. (If indeed there is any — since the key you're
sorting on is quick to calculate, it's not impossible that the extra
allocations needed for the ST will make it actually slower in
practice.)

If you don't actually need to keep @sorted around, the whole thing can
be even simpler:

my $position = 1;
$_->{position} = $position++
for sort { $a->{position} <=> $b->{position} } values %$ref;

I've also renamed your $count variable to $position, because I think
that more accurately reflects what it contains.

-- 
Aaron Crane ** http://aaroncrane.co.uk/



Re: Schwartzian transform

2014-08-13 Thread Abigail


Considering you wanted to golf, here's my entry [0]:


map$$ref{s/..//r}{position}=++$::x,sort+map"$$ref{$_}{position},$_",keys%$ref



Now, this will break if the value "position" field of the original structure
is outside of the range 0..9 [1], but that isn't the case in your example.

It makes use of the Guttman-Rossler Transform instead of the Schwartzian
Transform [2].


[0] It gives one warning if they are enabled; I expected more.
[1] Fixing the case where position could be larger than 9, smaller than 0,
or not an integer is left as an excercise for the reader.
[2] Because you know, we need all the speed when sorting 4 items.



Abigail


Re: Schwartzian transform

2014-08-13 Thread Mark Overmeer
* Dermot (paik...@gmail.com) [140813 11:08]:
> >
> >
> > # Warning: map in void context used for side-effect of setting
> > {position}...
> > # (I feel so dirty! ;-)
> > my $count = 1;
> > map  { $_->[1]{position} = $count++ }
> > sort { $a->[0] <=> $b->[0] }
> > map  { [$_->{position}, $_] }
> > values %{$ref};

> That is filthybut i like it. There are times I need to keep the
> structure as a hashref so I can find items by their key and there are times
> when I want to pass the data around as an ordered array so this works well
> for me too.

Sort is not lazy (cannot be lazy), so this suffices:

$_->{position} = $count++
for sort {$a->{position} <=> $b->{position}}
   values %$ref;
-- 
Regards,

   MarkOv


   Mark Overmeer MScMARKOV Solutions
   m...@overmeer.net  soluti...@overmeer.net
http://Mark.Overmeer.net   http://solutions.overmeer.net



Re: Schwartzian transform

2014-08-13 Thread Dermot
>
>
> # Warning: map in void context used for side-effect of setting
> {position}...
> # (I feel so dirty! ;-)
> my $count = 1;
> map  { $_->[1]{position} = $count++ }
> sort { $a->[0] <=> $b->[0] }
> map  { [$_->{position}, $_] }
> values %{$ref};
>
>
>
That is filthybut i like it. There are times I need to keep the
structure as a hashref so I can find items by their key and there are times
when I want to pass the data around as an ordered array so this works well
for me too.
Dermot


Re: Schwartzian transform

2014-08-13 Thread Damian Conway
If you only want to modify the original hash, you just need this:

# Warning: map in void context used for side-effect of setting {position}...
# (I feel so dirty! ;-)
my $count = 1;
map  { $_->[1]{position} = $count++ }
sort { $a->[0] <=> $b->[0] }
map  { [$_->{position}, $_] }
values %{$ref};

If you actually want the @sorted array for some reason, you just need:

# Warning: map has the side-effect of setting {position}...
# (I still feel unclean!)
my $count = 1;
my @sorted = map  { $_->[1]{position} = $count++; $_->[1] }
 sort { $a->[0] <=> $b->[0] }
 map  { [$_->{position}, $_] }
 values %{$ref};

But either way, you definitely need to document the side-effect in a comment,
so that it doesn't later turn into a bug.

Damian


Re: Schwartzian transform

2014-08-13 Thread Dermot
Olé

Thank you Adrian. Your golf is good.

my $count = 1;
my @sorted =
map { $ref->{ $_->[0] }->{position} = $count++; $ref->{ $_->[0] } }
sort { $a->[1] <=> $b->[1] }
map [ $_, $ref->{$_}->{position} ],
keys %{ $ref };


I sometimes question the legibility of such code but as an exercise, it's
good to know.

That last expression is interesting, Let's see if I'm getting it. Modify
the value of {position} in that hashref then return the hashref. The ';'
allowing you to perform more than one operation in the map expression...I
feel a penny dropping.

Thanks,
Dermot.









On 13 August 2014 11:11, Adrian Lai  wrote:

> On 13 August 2014 10:33, Dermot  wrote:
>
> > #map { $ref->{ $_->[0] }->{position} => $count++ }
>
> You probably want = $count++, rather than =>.
>
> You possibly want:
>
> map { $ref->{ $_->[0] }->{position} => $count++; $ref->{$_->[0]} }
>
> Adrian.
>


Re: Schwartzian transform

2014-08-13 Thread James Laver
On 13 Aug 2014, at 11:12, Alex Balhatchet  wrote:

> D'oh. Thanks for schooling me on 'map EXPRESSION' gents. I do vaguely
> remember seeing that before, but I never use it so I completely forgot
> about it :-)

It’s amazing what you can fit into an expression (especially with parens), and 
the expression form runs a little faster. grep EXPR is also really useful for 
doing regex matches over a list and it becomes more obvious what it’s doing at 
first glance.

James


Re: Schwartzian transform

2014-08-13 Thread Kieren Diment
And the first rule of the Schwartzian transform it to put a comment at the top 
of the code paragraph:

# Warning, schwartzian transform ahead.   If you need help with maintenance hit 
whoever git blame says’ fault it is.


On 13 Aug 2014, at 8:03 pm, Abigail  wrote:

> On Wed, Aug 13, 2014 at 10:50:39AM +0100, Alex Balhatchet wrote:
>> Hi Dermot,
>> 
>> You have a few problems with your code:
>> 
>> 1. First argument to map is a block
> 
> First argument of map is either a block, or an expression.
> 
>> You should be wrapping your code block to map with curly braces.
>> 
>> eg. map { [ $_, $ref->{$_}{position} ] }
> 
> No, not required. His code is fine.
> 
>> 2. No need to use $ref in your second (chronologically by execution,
>> first by line number) map
>> 
>> The Schwartzian Transform puts the original value into the first
>> element of the array reference, so to map back you just take $_->[0].
> 
> But then you would end up with a list of keys, his code ends up with a
> list of records. Those are different things.
> 
>> 3. Some mis-placed commas
>> 
>> When chaining maps and sorts you don't need commas, because there
>> should be no comma separating your block from the next argument to map
>> (this is related to my first point.)
> 
> This goes back to point one. You don't know map. The commas are actually
> required here, as he's using the "map EXPRESSION" syntax.
> 
> 
> His code is actually fine, and runs without any modifications.
> 
> 
> 
> Abigail




Re: Schwartzian transform

2014-08-13 Thread Adrian Lai
On 13 August 2014 11:11, Adrian Lai  wrote:
> You possibly want:
>
> map { $ref->{ $_->[0] }->{position} => $count++; $ref->{$_->[0]} }

Bad copy/paste/editing, I meant:

map { $ref->{ $_->[0] }->{position} = $count++; $ref->{$_->[0]} }

Adrian.


Re: Schwartzian transform

2014-08-13 Thread Dermot
>I assume that Dermot was using the second version that doesn't need the
braces and does need the comma.

I am often caught out between when to use the comma and not but it's "()"
and comma or braces and no comma, I believe.

Abigal: I wanted to avoid doing the foreach loop at the end. I hoped I
could modify {position} in the transform.

Still working with the examples I've been kindly show.

Dermot.





On 13 August 2014 10:59, Dave Cross  wrote:

> Quoting Alex Balhatchet :
>
>  Hi Dermot,
>>
>> You have a few problems with your code:
>>
>> 1. First argument to map is a block
>>
>
> [ snip]
>
>  3. Some mis-placed commas
>>
>
> [ snip ]
>
> Actually, map has two forms.
>
>   map BLOCK LIST
>   map EXPR, LIST
>
> I assume that Dermot was using the second version that doesn't need the
> braces and does need the comma.
>
> See http://perldoc.perl.org/functions/map.html
>
> Cheers,
>
> Dave...
>
>
>


Re: Schwartzian transform

2014-08-13 Thread Alex Balhatchet
D'oh. Thanks for schooling me on 'map EXPRESSION' gents. I do vaguely
remember seeing that before, but I never use it so I completely forgot
about it :-)

- Alex

On 13 August 2014 11:03, Abigail  wrote:
> On Wed, Aug 13, 2014 at 10:50:39AM +0100, Alex Balhatchet wrote:
>> Hi Dermot,
>>
>> You have a few problems with your code:
>>
>> 1. First argument to map is a block
>
> First argument of map is either a block, or an expression.
>
>> You should be wrapping your code block to map with curly braces.
>>
>> eg. map { [ $_, $ref->{$_}{position} ] }
>
> No, not required. His code is fine.
>
>> 2. No need to use $ref in your second (chronologically by execution,
>> first by line number) map
>>
>> The Schwartzian Transform puts the original value into the first
>> element of the array reference, so to map back you just take $_->[0].
>
> But then you would end up with a list of keys, his code ends up with a
> list of records. Those are different things.
>
>> 3. Some mis-placed commas
>>
>> When chaining maps and sorts you don't need commas, because there
>> should be no comma separating your block from the next argument to map
>> (this is related to my first point.)
>
> This goes back to point one. You don't know map. The commas are actually
> required here, as he's using the "map EXPRESSION" syntax.
>
>
> His code is actually fine, and runs without any modifications.
>
>
>
> Abigail


Re: Schwartzian transform

2014-08-13 Thread Adrian Lai
On 13 August 2014 10:33, Dermot  wrote:

> #map { $ref->{ $_->[0] }->{position} => $count++ }

You probably want = $count++, rather than =>.

You possibly want:

map { $ref->{ $_->[0] }->{position} => $count++; $ref->{$_->[0]} }

Adrian.


Re: Schwartzian transform

2014-08-13 Thread Abigail
On Wed, Aug 13, 2014 at 10:50:39AM +0100, Alex Balhatchet wrote:
> Hi Dermot,
> 
> You have a few problems with your code:
> 
> 1. First argument to map is a block

First argument of map is either a block, or an expression.

> You should be wrapping your code block to map with curly braces.
> 
> eg. map { [ $_, $ref->{$_}{position} ] }

No, not required. His code is fine.

> 2. No need to use $ref in your second (chronologically by execution,
> first by line number) map
> 
> The Schwartzian Transform puts the original value into the first
> element of the array reference, so to map back you just take $_->[0].

But then you would end up with a list of keys, his code ends up with a
list of records. Those are different things.

> 3. Some mis-placed commas
> 
> When chaining maps and sorts you don't need commas, because there
> should be no comma separating your block from the next argument to map
> (this is related to my first point.)

This goes back to point one. You don't know map. The commas are actually
required here, as he's using the "map EXPRESSION" syntax.


His code is actually fine, and runs without any modifications.



Abigail


Re: Schwartzian transform

2014-08-13 Thread Dave Cross

Quoting Alex Balhatchet :


Hi Dermot,

You have a few problems with your code:

1. First argument to map is a block


[ snip]


3. Some mis-placed commas


[ snip ]

Actually, map has two forms.

  map BLOCK LIST
  map EXPR, LIST

I assume that Dermot was using the second version that doesn't need  
the braces and does need the comma.


See http://perldoc.perl.org/functions/map.html

Cheers,

Dave...




Re: Schwartzian transform

2014-08-13 Thread Mark Overmeer
* Dermot (paik...@gmail.com) [140813 09:37]:
> I am trying to transform the hash reference below so that the value of
> position is ordered from 1..4.

I think I understand what you mean.

> my @sorted =
> map $ref->{$_->[0]},
> #map { $ref->{ $_->[0] }->{position} => $count++ }

should have beed
   map { $ref->{ $_->[0] }->{position} = $count++ }

> sort { $a->[1] <=> $b->[1] }
> map [ $_, $ref->{$_}->{position} ],
> keys %{ $ref };


  map { $_->[0]->{position} = $count++ }
 sort { $a->[1] <=> $b->[1] }
map [ $ref->{$_}, $ref->{$_}->{position} ],
   keys %$ref;

-- 
Regards,

   MarkOv


   Mark Overmeer MScMARKOV Solutions
   m...@overmeer.net  soluti...@overmeer.net
http://Mark.Overmeer.net   http://solutions.overmeer.net



Re: Schwartzian transform

2014-08-13 Thread Alex Balhatchet
Hi Dermot,

You have a few problems with your code:

1. First argument to map is a block

You should be wrapping your code block to map with curly braces.

eg. map { [ $_, $ref->{$_}{position} ] }

2. No need to use $ref in your second (chronologically by execution,
first by line number) map

The Schwartzian Transform puts the original value into the first
element of the array reference, so to map back you just take $_->[0].

3. Some mis-placed commas

When chaining maps and sorts you don't need commas, because there
should be no comma separating your block from the next argument to map
(this is related to my first point.)



Put it all together:

#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;

my $ref = {
'603927' => {
'title' => 'Light and healthy picnic food',
'position' => 2,
'license' => 'F',
'id' => '603927'
},
'562734' => {
'license' => 'M',
'position' => '0',
'title' => 'Man and woman beside highland loch in rai',
'id' => '562734',
},
'569368' => {
'license' => 'F',
'position' => '1',
'title' => 'A wooden picnic bench on the sand',
'id' => '569368',
'thumb' => '/image/569368/thumb'
},
'193246' => {
'license' => 'F',
'position' => '5',
'title' => 'A wooden picnic bench on the sand',
'id' => '193246',
'thumb' => '/image/569368/thumb'
}
};

print Dumper ($ref);

my @sorted =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, $ref->{$_}{position} ] }
keys %{ $ref };

print Dumper (\@sorted);



I can also recommend looking at Sort::Key which does this for you, and
avoids the need for messing around with $a and $b.

#!/usr/bin/env perl

use strict;
use warnings;
use Data::Dumper;
use Sort::Key qw(ikeysort);

my $ref = {
'603927' => {
'title' => 'Light and healthy picnic food',
'position' => 2,
'license' => 'F',
'id' => '603927'
},
'562734' => {
'license' => 'M',
'position' => '0',
'title' => 'Man and woman beside highland loch in rai',
'id' => '562734',
},
'569368' => {
'license' => 'F',
'position' => '1',
'title' => 'A wooden picnic bench on the sand',
'id' => '569368',
'thumb' => '/image/569368/thumb'
},
'193246' => {
'license' => 'F',
'position' => '5',
'title' => 'A wooden picnic bench on the sand',
'id' => '193246',
'thumb' => '/image/569368/thumb'
}
};

print Dumper ($ref);

my @sorted = ikeysort { $ref->{$_}{position} } keys %$ref;

print Dumper (\@sorted);



See https://metacpan.org/pod/Sort::Key for more info on that one.

- Alex

On 13 August 2014 10:33, Dermot  wrote:
> Hi
>
> Sorry for the OT post :)
>
> I am trying to transform the hash reference below so that the value of
> position is ordered from 1..4. The sorting works but I can't seem to modify
> the value of {position} inline. To achieve what I want I have to look
> through the @sorted array. I'd like to golf this if I can but I've hit a
> wall.
>
> Any suggestions?
> Thanks,
> Dermot.
>
>
>
>
> use strict;
> use warnings;
> use Data::Dumper;
>
> my $ref = {
>   '603927' => {
>  'title' => 'Light and healthy picnic food',
>  'position' => 2,
>  'license' => 'F',
>  'id' => '603927'
>},
>   '562734' => {
>  'license' => 'M',
>  'position' => '0',
>  'title' => 'Man and woman beside highland loch in
> rai',
>  'id' => '562734',
>},
>   '569368' => {
>  'license' => 'F',
>  'position' => '1',
>  'title' => 'A wooden picnic bench on the sand',
>  'id' => '569368',
>  'thumb' => '/image/569368/thumb'
>},
>'193246' => {
>  'license' => 'F',
>  'position' => '5',
>  'title' => 'A wooden picnic bench on the sand',
>  'id' => '193246',
>  'thumb' => '/image/569368/thumb'
>}
> };
>
> print Dumper ($ref);
>
> my @sorted =
> map $ref->{$_->[0]},
> #map { $ref->{ $_->[0] }->{position} => $count++ }
> sort { $a->[1] <=> $b->[1] }
> map [ $_, $ref->{$_}->{position} ],
> keys %{ $ref };
>
> print Dumper (\@sorted);
>
> my $count = 1;
> foreach my $hashref (@sorted) {
> $ref->{ $hashref->{id} }->{position} = $count++;
> }
> print Dumper ($ref);


Re: Schwartzian transform

2014-08-13 Thread Abigail
On Wed, Aug 13, 2014 at 10:33:50AM +0100, Dermot wrote:
> Hi
> 
> Sorry for the OT post :)
> 
> I am trying to transform the hash reference below so that the value of
> position is ordered from 1..4. The sorting works but I can't seem to modify
> the value of {position} inline. To achieve what I want I have to look
> through the @sorted array. I'd like to golf this if I can but I've hit a
> wall.
> 


If I run your program, the final Dump shows that 'position' has been
modified. Where you started off with positions 0, 1, 2, and 5, you
ended with positions 1, 2, 3, 4.

But perhaps I misunderstood your question?


Abigail


Schwartzian transform

2014-08-13 Thread Dermot
Hi

Sorry for the OT post :)

I am trying to transform the hash reference below so that the value of
position is ordered from 1..4. The sorting works but I can't seem to modify
the value of {position} inline. To achieve what I want I have to look
through the @sorted array. I'd like to golf this if I can but I've hit a
wall.

Any suggestions?
Thanks,
Dermot.




use strict;
use warnings;
use Data::Dumper;

my $ref = {
  '603927' => {
 'title' => 'Light and healthy picnic food',
 'position' => 2,
 'license' => 'F',
 'id' => '603927'
   },
  '562734' => {
 'license' => 'M',
 'position' => '0',
 'title' => 'Man and woman beside highland loch in
rai',
 'id' => '562734',
   },
  '569368' => {
 'license' => 'F',
 'position' => '1',
 'title' => 'A wooden picnic bench on the sand',
 'id' => '569368',
 'thumb' => '/image/569368/thumb'
   },
   '193246' => {
 'license' => 'F',
 'position' => '5',
 'title' => 'A wooden picnic bench on the sand',
 'id' => '193246',
 'thumb' => '/image/569368/thumb'
   }
};

print Dumper ($ref);

my @sorted =
map $ref->{$_->[0]},
#map { $ref->{ $_->[0] }->{position} => $count++ }
sort { $a->[1] <=> $b->[1] }
map [ $_, $ref->{$_}->{position} ],
keys %{ $ref };

print Dumper (\@sorted);

my $count = 1;
foreach my $hashref (@sorted) {
$ref->{ $hashref->{id} }->{position} = $count++;
}
print Dumper ($ref);


Fw: [dancer-users] Sad news regarding James Aitken (LoonyPandora), Dancer contributor and pluign author

2014-08-13 Thread David Precious

Hi all,

(Posted this to dancer-users first; it was suggested that it be posted
to london-pm too as several mongers had met/knew James.)


Sadly, my friend and colleague James Aitken (LoonyPandora/JAITKEN), who
contributed to Dancer and wrote several Dancer plugins, died
unexpectedly last week.

He was hit by a car back in June and suffered head injuries, but had
mostly recovered - but then took a sudden turn for the worse, and passed
away last week.  Details as to exactly what happened are still sketchy
at this point.

Due to how unexpected it all was and the fact he has no immediate
family / next of kin, he will receive a very very basic state-funded
"pauper's funeral" unless enough money is raised to cover the cost of a
proper funeral - so his ex-girlfriend set up a fundraising page to
accept donations towards the cost:

http://gogetfunding.com/project/james-aitken-s-funeral

If you used his code and found it useful, and have a couple of quid to
spare, any donations would be very much appreciated.  If you cannot,
but he or his code made a difference to you, you can still leave a
comment there if you'd like.


Dave P


-- 
David Precious ("bigpresh") 
http://www.preshweb.co.uk/ www.preshweb.co.uk/twitter
www.preshweb.co.uk/linkedinwww.preshweb.co.uk/facebook
www.preshweb.co.uk/cpanwww.preshweb.co.uk/github