Author Archives: Paul

Prime pair sets

I started playing around with Project Euler way back in November 2011, not least as an opportunity to hone my still nascent Python skills. And I’m still learning.

Problem 60 states:

The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.

Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.

This took a bit of thinking about but the approach I eventually came up with was to create a set of concetanatable primes for each prime (up to an arbitarily chosen value of 10000). Then all I would need to do is search each set for intersecting elements until I found five intersecting sets. Since the primes are generated in order, from lowest to highest, the first set of five intersecting sets will give me the answer.

Then for the implementation…

I already have a function that returns a list of primes, so that was easy, and using a dictionary keyed by prime was a no-brainer, but looking for set intersections was a bit of a struggle. Until I discovered that Python will do it for me. Using the set class it becomes remarkably easy to build a dictionary of sets and then work through them, checking intersections, until I find five sets that intersect.

My actual code is neither nice nor fast, and it isn’t going to scale at all – but I am quite pleased to have gained a handle on yet another iterable type.

flattr this!

The Fairphone has landed

Look what turned up in the post today

Not surprisingly, I have spent most of the evening playing around with my new toy and I have to say that I am very impressed indeed. The screen is beautifully large and clear and the fonts are gorgeous.

The phone has turned up a little (two months) later than originally expected but I have to admit that I have found this surprisingly un-annoying. I think much of this comes down to the fact that the Fairphone team have done an excellent job of communicating what problems they have faced, what they’re doing about them and when they think I will get my phone. This is a very refreshing changed from the closed-lip attempts at PR and damage limitation practiced by far too many firms.

By clearly seeking to meet their own high standards throughout every part of the process, the Fairphone team have managed to retain a lot of good will.

And the phone itself has proved to be well worth the wait.

flattr this!

Using the SQL with clause to group by calculated values

So here’s a question that cropped up recently: In an SQL Select statement, can you group by a calculated field (scalar function)?

The short answer is: No.

The longer answer is: Of course you can.

It did occur to me, last week, to simply post the script that I used to achieve this but there are a number of other things going on in there and I suspect that the unannotated code would be more confusing than clarifying. It is a useful, technique, however and one that I can see myself using again, so here is a simplified version of the problem along with the solution (file1 and field names have been changed for the sake of clarity).

So here’s the question: Can you provide a report showing the latest invoice number and invoice date for each customer (some selection criteria may apply)?

Since we have a sales file for which the sh_invoice_number field is updated when the transaction is invoiced, the first pass of this report is pretty simple:

select sh_sales_customer, max(sh_invoice_number), max(sh_invoice_date)
from sales_history
group by sh_sales_customer

Now for the wrinkle.

The sh_sales_customer field is the delivery point for the sales transaction. In many case, this is the same as the invoice account but there are cases where one invoice account encompasses several delivery points. Finance folk don’t care where goods are shipped, they just want to know where to send the invoice.

We have a file, account_numbers which maps the delivery point to the invoice account, if necessary. So the script needs to be changed so that it checks this file and uses either the retrieved value or the sales_customer, depending on the results of the lookup. The With clause is your friend.

You can’t Group By the calculated field, but you can use the With clause to factor the sh_sales_customer calculation into a subquery. And this is what we end up with:

with
 customer_accounts as 
   (select dp_delivery_point as ca_delivery_point,
           case 
              when an_invoice_account is not null then an_invoice_account 
              else dp_delivery_point
              end as ca_customer
    from delivery_points
    left outer join account_numbers on an_delivery_point = dp_delivery_point)
select ca_customer, max(sh_invoice_number), max(sh_invoice_date)
from sales_history
join customer_accounts on ca_delivery_point = sh_sales_customer
group by ca_customer

The delivery_points file contains all delivery points along with shipping information.

Footnotes

1 In case any of you youngsters are feeling confused by the terminology: a file (in this context) is a table, a record is a row and a field is a column. I am aware that I have the rather bad habit of using these terms interchangably, but I’m too lazy to go back and reword this post.

Addenda

The field and file names should be reasonably self explanatory, but if you are struggling with what belongs where, here are some definitions:

TABLE_NAME            COLUMN_NAME           DATA_TYPE         LENGTH   NUMERIC_SCALE 
SALES_HISTORY         SH_SALES_CUSTOMER     CHAR                   8                -
SALES_HISTORY         SH_INVOICE_NUMBER     INTEGER                4               0 
SALES_HISTORY         SH_INVOICE_DATE       DATE                   4                -

DELIVERY_POINTS       DP_DELIVERY_POINT     CHAR                   8                -

ACCOUNT_NUMBERS       AN_INVOICE_ACCOUNT    CHAR                   8                -
ACCOUNT_NUMBERS       AN_DELIVERY_POINT     CHAR                   8                -

The real files contain much more information, of course, but I have stripped these out in order to keep things reasonably simple.

flattr this!

Not annoying at all

It’s incredible how the most popular toys turn out to be the cheap impulse buy picked up by the grandparents on the way over for Christmas. So it is for Penguin Race II, in which three penguins noisily climb a set of stairs and then slide down the slope. Over, and over and over again.

In other news, HandBrake is proving to be a rather useful video transcoder. I still need to read up on web video formats, but I will apologise now in case this blog starts to become a bit noisier.

flattr this!

Pin-up Sunday: Car Hop Cutie by Erin Greener

By Day Erin Greener is a well-behaved digital illustrator for a small start up in Ohio. By night she becomes a crazy pin up artist and doodler of things!

Her Car Hop Cutie was drawn for the Girls Drawing Girls blog.

flattr this!

On the difference between Windows operating systems and Gnu/Linux distributions: An observation

I do like snappy post headings, but that isn’t the point of this post.

Over the Christmas period my parents came to visit and brought with them (among other things) an elderly scanner that had worked fine when attached to a Windows XP laptop but worked not at all with Windows 7. The scanner is a Visioneer 5800 and the problem is that there is no Windows 7 driver for this scanner.

I’d forgotten just how painful it could be to be dependent on proprietary drivers, but this isn’t the point of this post.

We eventually found a workaround over at Tom’s Hardware and the scanner is now scanning. We still have a problem, however, because the software appears to be losing the scanned image and then locking itself up. I suspect that the problem is a configuration issue and that the scanner software is looking for a hidden folder that doesn’t exist. And this brings me to the point of this post.

With the various Linux distributions I have used, configuration information is very easy to find and modify. The distribution works for me and the only limitations are my own ability and willingness to read the necessary documentation. Windows, on the other hand, works against me by hiding configurations here, there and everywhere and by making it pretty much impossible to poke around or to make any changes other than those explicitly permitted by both Microsoft and each and every device manufacturer.

My laptop runs Antergos and I do feel that I am in control of what this machine can and cannot do. A Windows user, on the other hand, is not in control of their machine and has, instead, been trained to accept that the way to solve issues is to buy more stuff.

flattr this!

The night before Christmas

flattr this!