lundi 21 janvier 2008

Starbucks discontinuing organic milk

Starbucks has announced that they will be discontinuing organic milk; of course some people are up-in-arms over it, but what does it mean for the customers and the company as a whole?

  • While organic milk is being discontinued, Starbucks has completed the process of ensuring all of the "normal" milk is rBST free, which I think is what most people are worried about anyway.

  • During my six or so years at Starbucks (at 7 different stores in 2 states), I personally made no more than 3 beverages using the certified organic milk (thats about 0.0001% of the total beverages I made during that time by my estimates).

  • The organic milk that Starbucks offered was asepticaly packaged (or as they call it here in Germany "H-Milk") which means it was ultra-super-insanely Pasturized then packaged into a sterile container so that it can sit on the shelf for a year, unrefridgerated (until you open it, then it lasts about a week in the fridge). This process makes milk that tastes, well, not as good.

  • One estimate I have read states that between 50-70% of the "normal" milk Starbucks uses is organic, it's just not certified as such (although this is probably impossible to actually prove).


There was possibly a bit of a chicken-and-egg problem in that the organic milk that Starbucks used tasted gross, so no one ordered it, which meant there was no demand for it, which meant there was no reason to move to non-asepticaly packaged organic milk which is WAY more expensive. And the cost of organic milk and low anticipated demand is why they chose to use asepticaly packaged milk in the first place.

Some people have asserted that Starbucks should go to using only organic milk then, and that rBST-free is not enough. It is my opinion, though, that most of these critics don't go to Starbucks anyway - it's usually the anti-Starbucks-no-matter-what-they-do crowd that says such things. For the people that do visit Starbucks, going all organic would probably mean (this is an educated guess here) a 10-20% price increase. Considering the state of the US economy at the moment I don't think anyone wants that.

Some argue that ${localCoffeeShop} can offer all organic milk, so Starbucks should be able to also. This kind of agility is what makes local coffee shops succeed (and even thrive) even when there is a Starbucks right next door; it's very difficult for a company to be both large and agile. Starbucks can be agile in some respects but in general its fairly slow to make changes - especially ones that impact such a core component of their business.

Additionally, many Starbucks simply do not have access to a reliable source of large quantities of fresh organic milk - a normal sized Starbucks can go through something like 100 gallons (380 liters) of milk a day. When you put 200 of them into one city the amount of milk required adds up really fast... In an ideal world, all Starbucks would use a local source of organic milk, but I do not at all believe the needed supply for this is available... it took, what, 5 years just to get all of the dairies Starbucks uses to commit to being rBST-free.

Ultimately, though, considering that Starbucks is currently entering a phase of getting rid of some of the least ordered products to trim the line-up a bit (Almond syrup and Creme Light beverages are going away too), organic milk, in its current form, is an obvious choice for this sort of cut.

If you really want and/or need organic milk, the soy milk that Starbucks uses (if I remember correctly) is certified organic. And if you can't and/or won't drink soy, then chances are there is a small coffee shop in your town that offers fresh organic milk, which is way better than the aseptic stuff anyway.

samedi 19 janvier 2008

Private implementation slots

Disclaimer: this article descrbes techiques that are not part of the public Qt API, using them may result in non-portable or version specific code. The example below was tested with version 4.3.3 on 64bit Linux.

Ok so, now that we have the disclaimer out of the way... If you are a Qt developer you are probably familiar with the concept of private implementation, or "pimpl" classes. If not, well, I won't get into that here, but if you look it up on Google or Wikipedia you should get the idea fairly easily.

Now, say you have a private class and you want it to have slots . One way is to add a slot to your public class then have it call the method you want in the private class, but this means you have to add a method to public API which means you break binary compatibility. Another is to have your private class extend QObject, but this adds overhead. Another way is to use the Q_PRIVATE_SLOT macro, which I will explain here.

First lets look at how to set up the private class.

file: slotTest_p.h

#ifndef SLOTTEST_P_H_
#define SLOTTEST_P_H_

#include "slotTest.h"

class slotTestPrivate
{
Q_DECLARE_PUBLIC(slotTest)
public:
slotTestPrivate(slotTest * qq) : q_ptr(qq) {}
private:
void bob() { qWarning("bob!"); }
slotTest * q_ptr;
};

#endif

The Q_DECLARE_PUBLIC(slotTest) macro definition is:

#define Q_DECLARE_PUBLIC(Class) \
inline Class* q_func() { return static_cast(q_ptr); } \
inline const Class* q_func() const { return static_cast(q_ptr); } \
friend class Class;

The main purpose of this is to define a q_func() method to make sure we can accesses it with the correct const-ness and ensure its cast to the correct type. In practice, when implementing methods of the private class you should virtually never use q_func() or q_ptr directly; instead you should place the Q_Q(Class) macro, which is defined as: #define Q_Q(Class) Class * const q = q_func(), at the beginning of the method implementation. From then on in the method you can use the pointer q to refer to the public class. For example:

void myClassPrivate::someMethod() {
Q_Q(myClass);
q->setText("hello world!");
}

Ok, so now we have our private class, lets create the public class.
file: slotTest.h

#ifndef SLOTTEST_H_
#define SLOTTEST_H_

#include <QtCore/QObject>

class slotTestPrivate;
class QTimer;

class slotTest : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(slotTest)
public:
slotTest();
private:
Q_PRIVATE_SLOT(d_func(),void bob())
QTimer * timer;
slotTestPrivate * d_ptr;
};

#endif

It's important that you don't include the actual private file here, otherwise you will get errors like:

slotTest_p.h:8: error: ISO C++ forbids declaration of ‘slotTest’ with no type
slotTest_p.h:8: error: ‘slotTest’ declared as an ‘inline’ field
slotTest_p.h:8: error: expected ‘;’ before ‘*’ token
slotTest_p.h:8: error: expected `;' before ‘inline’
slotTest_p.h:8: error: ISO C++ forbids declaration of ‘slotTest’ with no type
slotTest_p.h:8: error: ‘slotTest’ declared as an ‘inline’ field
slotTest_p.h:8: error: expected ‘;’ before ‘*’ token
slotTest_p.h:8: error: expected `;' before ‘friend’
make: *** [main.o] Error 1

We have to include the Q_OBJECT macro here even though this example class doesn't actually have any signals or slots of it's own because otherwise moc won't even look at it in the first place.

The Q_DECLARE_PRIVATE(Class) macro is just the counterpart to the Q_DECLARE_PUBLIC(Class) macro except it creates a method named d_func() to access the private class. Likewise, there is a Q_D macro for use inside method implementations so you can use d as a pointer to the private class.

The Q_PRIVATE_SLOT macro takes a pointer to your private class, and we will take advantage of the d_func() method to get it. Next is the signature of the private class' method to call. One interesting thing about this macro is that it directly expands to no actual code - it simply a trigger for moc.

We are also creating a QTimer to call this slot repetadly for the example.

Now our implementation:
file: slotTest.cpp

#include <QtCore/QObject>
#include "slotTest.h"
#include "slotTest_p.h"
#include "moc_slotTest.cpp"

slotTest::slotTest() : QObject()
{
d_ptr = new slotTestPrivate(this);
timer = new QTimer(this);
timer->setInterval(1000);
connect(timer,SIGNAL(timeout()),this,SLOT(bob()));
timer->start();
}

The most important thing to notice here is that we have listed the moc-generated moc_slotTest.cpp file as an include, doing this ensures that slotTestPrivate has been defined before the moc file is processed. If you were to not include of this file here, you may get an error like:

/home/kdab/workspace/prtst/slotTest.h:10: undefined reference to `vtable for slotTest'

Here, we just set up our private class, a timer, and connect the timer to call our slot. Notice that even though the method we are calling is inside our private class, we still use this in the connection because the slot is technically a slot of our public class, even though the implementation is in the private class.

Now lets make it runnable:
filename: main.cpp

#include <QtCore/QCoreApplication>
#include "slotTest.h"

int main(int argc,char* argv[])
{
QCoreApplication app(argc,argv);
slotTest bob;
app.exec();
}

And one final very important thing, the project file...

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += slotTest.h slotTest_p.h
SOURCES += main.cpp slotTest.cpp

It's very important that slotTest.h is listed before slotTest_p.h otherwise you will end up with the following error:

moc_slotTest.cpp: In member function ‘virtual int slotTest::qt_metacall(QMetaObject::Call, int, void**)’:
moc_slotTest.cpp:64: error: invalid use of undefined type ‘struct slotTestPrivate’
slotTest.h:5: error: forward declaration of ‘struct slotTestPrivate’

Once you have it built, you should see "bob!" printed to the screen every second from the bob() method in the private class.

lundi 14 janvier 2008

Multiple inheritance and Q_OBJECT

I found out today, while working on porting a Motif application to Qt, that when you are inheriting from more than one class and not all of them are derived from QObject, you should make sure the first one does inherit QObject if you want to use the Q_OBJECT macro. For instance:

class A : public QObject {};
class B {};

class C : public A, public B
{
Q_OBJECT
};

If you do it the other way, (class C : public B, public A) you will get errors inside the moc_C.cxx file saying that it couldn't find the QMetaObject members of class B (which it doesn't have) because moc only looks at the first base class listed.
There all sorts of other little things like this which you can read about in the Qt moc documentation (for instance, nested classes cannot have signals or slots).

dimanche 13 janvier 2008

Tall is small?

Lets start with one of the most universal questions in coffee, why at Starbucks (and thus many other coffee shops) is the small size called tall?

The answer is actually quite simple - it isn't (at least not at Starbucks where this strange cup size name thing started in the first place). The small size is called short, but a short cup is only 240ml(8oz.) which, in these times of excess, almost no one wants.

When Starkbucks first started serving brewed coffee (actually it was Il Giornale then, which later bought Starbucks and took over the name, but that is another story) the sizes were short, tall, and grande - which makes perfect sense. Thing is, almost no one was ordering the short, in fact more than 50% of sales were of the grande size - which is twice the size of a short, so seeing that people wanted bigger coffee, they added a larger size called Venti*, which means 20 in Italian (it's a 20oz.(591ml) cup.**) and eventually dropped short form the menu.

Starbucks does still carry the short cups, and all hot drinks are available in that size (there is no short cup for cold beverages) mostly because this is a handy size for things like double espressos, kid's hot chocolates, and the like. But with more than 50% of sales still being grande sized, there is little reason to advertise that.

* Starbucks has actually copyrighted this name, which is why at many other coffee shops tall and grande have the same name, but the largest size has a different one. I wont even go into the implications about copyrighting a number - but I guess the card game "Uno" did it to without destroying society.

** Actually only the hot Venti cup is 20oz., the cold version is 24oz.(710ml) which makes the name a bit silly.

First post

Well I decided to start another blog in addition to my personal blog. While my personal one is mostly about relationships, friends, and such, this blog will be about two of the most important things in the world - coffee and code. Ok then, lets start!