My best purchases from Amazon, 2024 editions

Verbatim 43888 External Slimline Blu-Ray Burner

One of my last purchase in 2024 turned out to be one of the best. I wanted to rip my bluray collection for a while, for convenience, but has always been put off by selecting the right drive. I have no space for an internal drive, and not every drive can rip 4K bluray – you will need to flash firmware. Turned out there is one that just works out of the box. Pop out the drive, plug it in, and start ripping. Simple as that.

It is fairly quiet most of the time (depending on the disc), and it just works. Speed is a bit slow given size of the 4K bluray, and it is a slim, external drive, but I can’t really complain

https://amzn.to/4iH4oAn at around 1200kr (1300kr with 100kr coupon at check out at the time of writing)

OXO Good Grips Kitchen & Herb Scissors

This is my favorite kitchen scissors. Victorinox one is good also, but this feels more sturdy when holding. And boys it just cut through every thing – for example if you need to cut down a chicken. It does not shy to cut through bone. And it’s stainless steel so you can just throw it to the dish washing machine. It can be quickly dissembled and assembled in seconds. Nothing to complain about, just a terrific kitchen scissors

https://amzn.to/4fnpKjG at around 250kr

The runner is Victorinox one

https://amzn.to/4fFiNL3 at around 220kr

Nordic Ware 44671AMZ Prism Large and Half Sheet Set, Aluminum

The absolute best baking sheets by Nordic Ware, in thick aluminum, made in the USA. If you are a fan of baking cookies, they are a must. Sadly at this point of writing they are out of stock, but they were available for around 250kr for a long time. Make sure to snatch one when it’s available again, a steal at that price – one piece is more than that (250kr) in other stores, and here you get two

https://amzn.to/3ZMvcG

OXO Good Grips Y Peeler

There are many good peelers out there and my best performance on price would be from Victorinox – it can peel carrots like there is no tomorrow. and it’s that good. Sadly it is no longer available from Amazon themselves and you have to buy from 3rd party seller which means additional shipping fees.

https://amzn.to/3ZLz4bg at around kr54.30

I also have an OXO peeler which I bought a few years ago but did not use it that much, but a friend of mine visited recently and insist that I buy for her this (she is of course paying). It is a great peeler anyway and some might prefer it to the Victorinox one as the handle is more comfortable. I bought one for my friend and she is more than happy with it. Maybe you will, too.

https://amzn.to/3BNYI75 at around 125kr.

Neutrogena Concentrated unscented hand cream (50 ml)

In many positive things about Sweden, I suffer from the cold, dry winter, and my hands suffer the most. My collection of hand moisturizers could somewhat be comparable to my wife’s skincare collection. I had anything from O’Keefee’s to Cerave to Eucerin, they helped a little but nothing really solved my problem. Enter Neutrogena hand cream. Really a life saver. Wish I knew it 9 years ago.

https://amzn.to/4glZh7e at around 38kr

Best deals on Amazon.se week 51/2024

Fjallraven 87177-244 Vidda PRO Pants M Sports Pants Men’s Suede Brown Size 48/L

Easily 2000kr on other shops

https://amzn.to/3ZZemVB

Dreame L40 Ultra Robot Vacuum Cleaner with Removable and Liftable Mop, Extendable and Liftable Side Brush, 11000Pa Suction Power, 65°C Mop and Washboard Self-Cleaning, Automatic Draining, Automatic

Reduced to kr9,770.29

https://amzn.to/41w0sMW

Yes Max Power Dishwasher Liquid Pomegranate 650ml, Easy and smooth cleaning, even for your dirtiest pots and pots

Reduced to kr35.49

https://amzn.to/3VKNzL5

Dreame Z10 Station with auto empty station

Reduced to kr2,999.00

https://amzn.to/3DfWhdU

Philips SONICARE W2 Optimal White Standard Sonic Toothbrush Heads in Original Design – Pack of 8 Units in White 

Reduced to kr349.00

https://amzn.to/3VEUPrW

ECCO Men’s Track 25 Mid GtxClassic Boots

Reduced to kr1,287.17

https://amzn.to/41F35w4

Waterpik Ultra Professional Water Flosser, Mouth Shower With 7 Nozzles And Advanced Control Of Water Pressure With 10 Settings, Tool For Removing Plaque, White (WP-660EU)

reduced to kr599 (reduced 100kr at check out)

https://amzn.to/3ZZ9wJ3

Apple iPad Pro 11 tum (M4): Ultra Retina XDR-skärm, 512 GB, skärmkamera på långsidan med 12 MP/kamera på baksidan med 12 MP, wifi 6E + 5G, batteri som räcker hela dagen, Standardglas – silver

Reduced to kr14,882.81

https://amzn.to/3BEDaKg

Best deals on Amazon.se week 50/2024

Philips Sonicare Original W2 Optimal White HX6066/10

Reduced to kr289.99

https://amzn.to/3BlL4Io

Several UGREEN USB C Hub reduced to Black Friday prices

https://amzn.to/4g3ZUCo

Thermos Bottle + Tea/FRUIT Filter Infuser, Insulated Stainless Steel Water Bottle, BPA Free | Drink Bottle + Tea Infuser / Fruit Insert, 450ml To-Go Thermo Cup Thermo Flask: Office Sports School

Reduced to kr227.99

https://amzn.to/4iv5Oy7

Philips Hx9611/19 Sonicare Expertclean 7300 Elektrisk Tandborste, Vit, Paket med 2

Reduced to kr1,577.13

https://amzn.to/3D9AHI7

Noctua NF-A12x25 PWM chromax.black.swap, Silent Premium Fan, 4-Pin (120mm, Black)

Reduced to kr199

https://amzn.to/49M9HuF

Merrell Moab 3 GTX men trekking shoes

Reduced to kr850

https://amzn.to/4f7GdZb

LEGO Technic Koenigsegg Jesko Absolut Grey Hyper Car, Construction Set for Boys and Girls, Toy Car for Kids, Buildable Model Set, Gift Idea for Motor Enthusiasts 42173

Reduced to kr390

https://amzn.to/4g9UlCi

Produkt: Apple MacBook Air 15.3″ (2024) – M3 OC 10C GPU 16GB RAM 512GB SSD

Reduced to kr15,743.52

https://amzn.to/4iyzom7

Yes Platinum All In One Dishwasher Detergent, 94 Dishwasher Tablets

Reduced to kr138.89

https://amzn.to/4fiK7hM

TIMEMORE Coffee Scale Basic 2.0 Espresso Scale

Reduced to kr542.40

https://amzn.to/3PcEqaN

Technics EAH-AZ80E-K Wireless Headphones with Noise Cancellation, Multipoint Bluetooth 3 Devices, Comfortable In-Ear Headphones, Wireless Charging, Black

Reduced to kr2,413.60

https://amzn.to/3ZwlCI4

Eneloop Pro BK-3HCDE/4BE Batteries AA

Reduced to kr80

https://amzn.to/4iAKlUk

ESI U22 XT | Professional 24-bit USB Sound Card
Reduced to kr516.78. Can be combined with the Spend 600kr get 100kr discount

https://amzn.to/4gsi0Ou

BGS 32100 | U-Ring Wrench Set | Inch Sizes | 3/8″ – 11/16″ | 6 Pieces

Reduced to kr89.34

https://amzn.to/4gnjZDK

Swiffer mop wipes (12 pads)
Reduced to kr35.79

https://amzn.to/4iL6kbf

LEGO Technic NEOM McLaren Formula E Racing Car 42169

Reduced to kr413.99

https://amzn.to/41Lr9Nx

Gillette Fusion 5 Razor Blade Refills for Men, 8pcs

Reduced to kr250.39

https://amzn.to/41Nk4MO

Best Black Friday deals on Amazon.se

Black Friday is in full speed and here are the best deals you can buy now

Ninja air fryer MAX PRO, 6.2 litres, uses no oil, large square single box, family size, non-Stick, dishwasher safe basket and crisp plate, silicone tongs, black and copper, AF180EUCP

https://amzn.to/3D3ASEC

Ninja Foodi MAX Dual Zone Digital Air Fryer, 2 Drawers, 9.5L, 6-in-1, Usually No Oil, Air Fryer, Maximize Crisp, Roast, Bake, Dry, 8 Serves, Nonstick Dishwasher Safe Baskets, Black AF400EU

https://amzn.to/4g6wumN

TP-Link Tapo P115 Smart Plug, White

https://amzn.to/4eWTQdz

Corsair SP120 ELITE, 120mm PWM Hydraulic Stored Fan For Housing With CORSAIR AirGuide Technology – Low Noise, 24.7dBA, Fan Speeds From 300 RPM – 1300 RPM, 45.4 CFM, Single Pack – Black

https://amzn.to/4gdMYJF

The tale of three puck screens

Puck screen is the common recommended tool to people starting their espresso journey. It is said to improve water distribution at to the puck, which promotes even extraction which means better tasting espresso. To my best of effort, I can’t detect any change in flavor with or without the puck screen. The benefit of using puck screen – is to keep your group head clean. When you stop the pump, some of the coffee ground will be suck up to the

Normcore

Thickness: 1.7mm

This is a mesh puck screen, which means it has several levels pressed together with a laser etching. It is the thickest and also the heaviest (but not by much). It used to cost around 250kr on amazon.se but it is now 185kr.

Pros: It is probably the one that works best.

Cons: it feels bulky. It probably works the best but it is also the hardest to clean. I had to soak it in puly caff from time to time to clean it even after putting it in disk washing machine. There could be concern that it will cold the water down more than it should, but given its thermal mass compared to the group head it should be very negligible.

3MHW-Bomber

Thickness: 0.8mm

It is a hybrid puck screen, with a plate with bigger holes and a net with smaller holes. Price is around 140kr on Aliexpress but I bought 5 for 330kr.

Pros: Of all three, this one is the best looking, not as bulky as the normcore but not as slimy as the Temu one. It also seems to work great – on par with Normcore, while much easier to clean.

Cons: it’s asymmetric so if you put it in the puck up side down, it is not as beautiful.

No name Temu puck screen

I had I hope for this but it turn out to be quite a disappointment. It is by far the cheapest, for around 2 pieces/35kr. It is simply a very thin metal place with holes

Pros: It is the thinnest (0.2mm), and also the lightest (2.7gr), so virtually no impact on thermality. It is also the easiest to clean.

Cons: it is too thin it is easy to bend, harder to hold as well. When you store 2 or more of them, they are easy stuck together. Performs the worst as the holes are big enough for grounds to get through.

All in all, my favorite is the 3MHW-Bomber. It has the best craftmanship, it has a nice balanced between size and function. After some trials I decided to put away my Normcore and Temu, and use it exclusively.

This blog is now ads-free

As with most things in life, if it is not illegal, or immoral, or not prohibitively expensive, I want to try it. Life is so short that we need to experience more. When we still can.

Adverting is one of them. You probably noticed that my blog has plenty of ads (in some cases, a lot). I wanted to see two things

  • How Google ads works
  • If I can make money out of it

The answer to the second question is yes, I can. Just … not a lot. In the last few years I have been making less than 1 SEK per day from ads revenue. Just barely enough to cover the cost for the domain name renewal. I’m lucky enough that my employer is sponsoring the hosting cost, so ads is not making me rich. Not fast enough at least. I’ll likely not live to the day I can buy myself a serious roaster from ads revenue. (And if you want to sponsor me, this is the roaster I want to buy )

And ads can be annoying and sometimes, intrusive, I decided to turn off ads from this blog. I will add a button so you can donate/sponsor me some money if you think the blog is helpful to you (or you just want to be nice and toss a coin to your witcher, I meant, blogger)

I promise I will use those money on weed, I meant, green coffee beans. I started coffee roasting recently, and stay true to my philosophy, I want to test as many coffee as I can. Some are reasonable priced, some are pretty expensive.

In any cases, thank you for visiting my blog. I hope it is helpful to you, and I wish you a wonderful day!

Don’t let the execution plan fools you

Don’t get me wrong, execution plan is one of the best tools at your disposal if you want to optimize a SQL query. No, it is the must have tool. It is not the only tool you will need, but if you have to pick only one, pick it.

But it is important to know that execution plan can be misleading. It is very useful to see where is the bottleneck is within a statement. It is not exactly useful when you need to compare two statements.

Let’s compare these two queries that I am working to optimize

SELECT	OG.OrderGroupId
		FROM	OrderGroup OG
		INNER JOIN	OrderGroup_PurchaseOrder PO ON OG.OrderGroupId = PO.ObjectId WHERE 1 = 1  AND OG.Status IN(SELECT Item FROM ecf_splitlist('Cancelled')) ORDER BY OG.OrderGroupId DESC
        OFFSET 0  ROWS 
        FETCH NEXT 50 ROWS ONLY

versus

SELECT	OG.OrderGroupId
		FROM	OrderGroup OG
		INNER JOIN	OrderGroup_PurchaseOrder PO ON OG.OrderGroupId = PO.ObjectId  WHERE 1 = 1  AND OG.Status IN('Cancelled') ORDER BY OG.OrderGroupId DESC
        OFFSET 0  ROWS 
        FETCH NEXT 50 ROWS ONLY

These are 99% similar, except for the statement OG.Status IN ..., with and without calling the split function.

If you look at the execution plan only, it seems the former is much faster than the latter. It takes only 14% of the time, while the latter takes 86%, so if based on those figures only, we might think the first one is ~6 times faster than the second one.

Except it is not. If we turn on the IO statistics, it is a very different story

The first query has significantly more IO operations than the second

(50 rows affected)
Table 'OrderGroup_PurchaseOrder'. Scan count 0, logical reads 162, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table '#BA76F977'. Scan count 1, logical reads 8386, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'OrderGroup'. Scan count 1, logical reads 356, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

versus

(50 rows affected)
Table 'OrderGroup'. Scan count 1, logical reads 356, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'OrderGroup_PurchaseOrder'. Scan count 1, logical reads 143, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

The first has slightly more logical reads on OrderGroup and OrderGroup_PurchaseOrder, but significantly more in a temp table (which is, inside the ecf_splitlist function).

The moral of the story? Execution plan is helpful, but not to compare query to query. In most cases, IO statistics are much more useful.

Migrate Catalog content properties

A colleague asked me yesterday – how do we migrate properties of catalog content. There is, unfortunately, no official way to do it. There are several unofficial ways to do it, however. Today we will explore the way I personally recommend – for its safety and backward compatible.

Let’s say we have FashionProduct with a MSRP property with type of Money, now we would want to change it to Decimal . There are a some hacky ways to do this, but all of them require direct database manipulation which we should try to avoid – if possible.

First we will need this piece of code. it was “stolen” from a colleague of mine and has been used for countless times. You probably want to bookmark it as it’ll likely be useful in the future (I should probably do so myself as I have to find it every time I need). It is a snippet to traverse the catalog structure based on the content type you’d want.

public virtual IEnumerable<T> GetEntriesRecursive<T>(ContentReference parentLink, CultureInfo defaultCulture) where T : EntryContentBase
    {
        foreach (var nodeContent in LoadChildrenBatched<NodeContent>(parentLink, defaultCulture))
        {
            foreach (var entry in GetEntriesRecursive<T>(nodeContent.ContentLink, defaultCulture))
            {
                yield return entry;
            }
        }

        foreach (var entry in LoadChildrenBatched<T>(parentLink, defaultCulture))
        {
            yield return entry;
        }
    }

    private IEnumerable<T> LoadChildrenBatched<T>(ContentReference parentLink, CultureInfo defaultCulture) where T : IContent
    {
        var start = 0;

        while (true)
        {
            var batch = _contentLoader.GetChildren<T>(parentLink, defaultCulture, start, 50);
            if (!batch.Any())
            {
                yield break;
            }

            foreach (var content in batch)
            {
                // Don't include linked products to avoid including them multiple times when traversing the catalog
                if (!parentLink.CompareToIgnoreWorkID(content.ParentLink))
                {
                    continue;
                }

                yield return content;
            }
            start += 50;
        }
    }

To make sure we don’t load to many content at once, the batch is set size 50 but that is of course configurable (up to you)!

Now the fun part, where it actually does the work. Once we have the content, we will need to actually migrate the data, it is can be simple as this

private void MigrateProperty<T>(IEnumerable<T> contents) where T: EntryContentBase
{
      var batch = new List<T>();
      foreach(var content in contents)
      {
           var writeableClone = content.CreateWriteableClone<T>();
           Transform(writeableClone);
           batch.Add(writeableClone);
      }
      _contentRepository.Publish(batch, PublishAction.SyncDraft);
}

With the Transform method you can do whatever you want with the property value. As you might just want to rename it – it can do nothing except assign value to the new property. Or in the case we mentioned at the beginning, convert Money to Decimal is an easy task (Money is the less precision version of Decimal). Note that if you convert between data types, for example from double to int , there are potential data loss, but you are probably aware of that already.

The final step is to publish the change. For performance reasons, it is probably the best that you the Publish extension method of IContentRepository and save multiple content in one batch – may of of size 50 or 100. Those will skip things like creating new versions for optimal performance. You can read it about here New simple batch saving API for Commerce | Optimizely Developer C

The remaining question is where to put it. In a perfect world, I’d say in a migration step (i.e. a class that implement IMigrationStep ), so you ensure that your data will be properly migrated before anything else run, for example your new code that access the new property, or indexing of your content after migration. But if you have a sizeable catalog, this will take time and it might not be a good idea to let your users wait for it to complete. For that, it makes senses to do this in a schedule job and when it completes, you make a switch.

Migrating properties is not an easy or quick task, but it can be done with relative ease. It also reminds us about modeling – try to get it right from beginning so we don’t have to migrate. In the end, the fastest code is the code that does not need to be run!

Green coffee bean suppliers in EU

Why the criteria

FOB Price: one of the important aspect of specialty coffee is fair trade – farmers produce high quality coffee, and they should get fair price for what they harvest. FOB Price is basically what the importer (in many cases, the supplier themselves) pays for the coffee. It’s a great deal of transparency. And while it’s not required, I would be happy to know what the farmers are getting.

Cupping score: Coffee that is rated as specialty has to at least 80 cupping score by SCA (it’s not the only criteria, but an important one). If you are paying 200/20 EUR or more per kg for green coffee beans, you should know what you get. While a higher cupping score is not necessarily more expensive, it depends a lot on the supply-demand balance, but I’d be happier to pay more money for higher cupping score.

Year of harvest: Green coffee beans have much longer shelf life than roasted coffee ones. While for roasted, you should finish your bag within 2 months (and some purists might say just 1 month), green beans can be keep for 12 months in proper storage conditions, if not more. But they do not last forever, the fresher the beans = the better, which is why it’s important for the supplier to disclose the year of harvest (or even, month of harvest)

Suppliers in Sweden

I started with Whileelkcoffee and Rawcoffee. Too early to tell about the bean’s quality, but I must say I really like Whiteelkcoffee’s packaging. They are a branch/subsidiary of Kafferosteriet Koppar AB, which has some great coffees.

It is told that almost any roasters will sell your raw coffee if you ask nicely, so you probably ask your favorite roaster if they have green beans to sell. The commonly accepted “rule” is green coffee is 1/2 price of roasted ones, so you might offer that to the roasters.

I would recommend to buy from suppliers that focus on coffee beans – they usually know more about their stuffs – than the suppliers that sell general groceries. But you can always try your luck, maybe there is a hidden gem somewhere.

SiteUrlFree shipping thresholdBag sizeFOB priceCupping ScoreYear of HarvestNote
White elk coffeeButik: Råkaffe – White Elk Coffee350kr1, 10kgNoNoNo10% for order over 1000kr
Raw coffeeKaffebönor – RawCoffee350kr1kgNoYesYes10% coupon code for next order
Drop coffeeBuy Coffee – scroll down to buy your coffee – Drop Coffee300kr1kgYesNot specific, 86+YesSelect unroasted coffee from drop downlist
Muttley & Jack’sUrsprungskaffe – Muttley & Jack’s (muttleyandjacks.se)No free shipping, 69kr regardless of order value1kgNoYesNo
BaristashoppenRÅKAFFE – ROSTA SJÄLV – Baristashopen350kr250gr, 1kgNoNoNo
MoccazinoHuvudkategori 3 (moccazino.se)No free shipping, min 229kr, shipping cost increased with weight0,75kgNoNoYes
Humle gårdenGreen coffee for those who roast their own coffee – Humlegårdens EkolagerNo free shipping, 99kr shipping, increased with weight500grNoNoYesReduced price for 10 bags

Suppliers outside Sweden

Of course I would prefer buying from Sweden for obvious reasons. But I can’t resist the urge to try some exotic beans, so I have been looking around to see where I can source my green beans from EU.

This is inspired by EU Green Coffee Sources List 2023 (home-barista.com), but with more information you can find in one place. Sadly many of them are are not shipping to Sweden, but you probably can arrange some shipping if you ask nicely.

SiteUrlCountryShip to SwedenShipping costFOB priceCupping scoreBag sizesYear of harvest
fleurdecafeUnroasted coffee beans – Green coffee beans | Fleur de café (fleurdecafe.nl)NetherlandsNoN/ANoNo
groenekoffiewinkelUnroasted Coffee Beans | Up To 15% Discount At Green Coffee Shop (groenekoffiewinkel.nl)NetherlandsNoN/A
fascino-coffeeGreen Coffee Beans | Coffee roasting company Fascino (fascino-coffee.com)NetherlandsNoN/A
godincoffeeUnroasted coffee beans – Green coffee beans | Fleur de café (fleurdecafe.nl)NetherlandsNo
roastrebelsBuy green coffee in small quantities (1kg / 5kg / 15kg) | Roast RebelsGermany/SwizerlandYes9.9EUR, free if order value is 120EUR or moreNoNo1, 5, 15kgYes
rohebohnenGreen Coffee | Rohebohnen.deGermanyYes13.9EURNoNo500gr, 1kgNo
hoofdkwartierUnroasted Coffee Beans Archives – Headquarters Coffee Roasting (hoofdkwartier-koffiebranderij.nl)NetherlandsNo
ShokuninGreen coffee – ShokuninNetherlandsYes22 EUR, free if order value is 200 EUR or moreNoNo
RoestartRohkaffee (roestart.de)GermanyYes15.9 EURNoNo500gr, 1kgNo
goodkarmacoffeeRohkaffee – Good Karma CoffeeGermanyNo
docklandsRohkaffee kaufen und selber rösten (docklands-coffee.de)GermanyYes16EURNoNo1,5 and 10kgYes
rjavitukanSurova kava Archives – Rjavi tukanSlovakiaYes21.9EURNoNo1,3,5, and 10kgNo
koffiebranderijdekoepoortGROENE ONGEBRANDE KOFFIEBONEN – Koffiebranderij de KoepoortNetherlandsYesFlat rate 24.5 EURNoNo1kgNo
Falcon-microShop Europe – Falcon Micro (falcon-micro.com)UK (EU warehouse)Yes246kr for minimum 5kg, increased with weightNoYes5 and 10kgNo
88 grainsShop | 88 GrainesFranceYes6.9EUR minimum, increased with weight, free for 300 EUR+NoYes1kgYes (Month/year)
kaffeboxKaffeabonnement med Skandinavias topp mikrobrennerier – KaffeBox.noNorwayYesMinimum 62.5NOK, increased with weightNoNo250grNo
risterietGrønne/Rå kaffebønner – Risteriet.dk WebshopDenmarkYesNo, 350DKKNoNo1kg, 5kgNo