$$T_T = \text{initial tea temperature}$$

$$T_M = \text{milk temperature}$$

$$T_R = \text{room temperature}$$

$$C_T = \text{heat capacity of tea} = \text{mass} \cdot \text{specific heat capacity}$$

$$C_M = \text{heat capacity of milk} = \text{mass} \cdot \text{shc}$$

$$t = \text{time}$$

$$T_M < T_R$$

$$C_M, C_T > 0$$

$$k > 0$$

Temperature of mixture of 2 liquids:

$$M(T_1, T_2) = \frac{T_1 C_1 + T_2 C_2}{C_1 + C_2}$$

Temperature of object against time:

$$C(T_T, t) = T_R + (T_T – T_R)e^{-kt}$$

When is \(M(C(T_T, t), T_M) \leq C(M(T_T, T_M), t)\)?

$$\frac{( T_R + (T_T – T_R)e^{-kt} ) C_T + T_M C_M}{C_T + C_M} \leq T_R + \left ( \frac{T_T C_T + T_M C_M}{C_T + C_M} – T_R \right ) e^{-kt}$$

$$(T_R + (T_T – T_R)e^{-kt}) C_T + T_M C_M \leq T_R(C_T + C_M) + (T_T C_T + T_M C_M – T_R(C_T + C_M) ) e^{-kt}$$

$$T_R C_T + (T_T – T_R)e^{-kt} C_T + T_M C_M \leq T_R(C_T + C_M) + (T_T C_T + T_M C_M – T_R(C_T + C_M) ) e^{-kt}$$

$$e^{-kt}((T_T – T_R) C_T – (T_T C_T + T_M C_M – T_R(C_T + C_M)) \leq T_R(C_T + C_M) – T_M C_M – T_R C_T $$

$$e^{-kt}(T_T C_T – T_R C_T – T_T C_T – T_M C_M + T_R C_T + T_R C_M) \leq T_R C_T + T_R C_M – T_M C_M – T_R C_T $$

$$e^{-kt}(- T_M C_M + T_R C_M) \leq C_M (T_R – T_M)$$

$$e^{-kt} \cdot C_M (T_R – T_M) \leq C_M (T_R – T_M)$$

Division is allowed because \(C_M > 0, T_R > T_M \therefore T_R – T_M > 0\)

$$e^{-kt} \leq 1$$

$$-kt \leq \ln(1)$$

$$kt \geq 0$$

$$k \gt 0 \therefore$$

$$t \geq 0$$

Thus, as long as the milk is colder than room temperature, your tea will always cool quicker if you add milk after letting it cool rather than adding milk and then waiting for it to cool. This result also means that if you want to keep a cup of tea warmer for longer (and you are going to add milk), you should add milk as soon as possible (whilst also factoring in optimum tea extraction temperature).

Now all this result shows is that it will be cooler, but without any knowledge of the variables, it’s impossible to say whether the difference is perceptible or even measurable. So I did the experiment.

I made two cups of tea, removing the teabag then measuring the temperature over 5 minutes using a cheap digital thermometer from Amazon connected to an Arduino. In one I added milk immediately while with the other I added it at the end. The raw data can be found here. I found that there was about a 3°C difference – definitely measurable but not particularly noticeable.

So, if you need your tea to cool down faster, put the milk in later. However, I’ve found the inverse much more useful – keep tea warmer for longer by adding milk sooner.

]]>"terminal-plus": ansiColors: normal: black: red: 7 green: 54 blue: 66 alpha: 1 blue: red: 38 green: 139 blue: 210 alpha: 1 cyan: red: 42 green: 161 blue: 152 alpha: 1 green: red: 133 green: 153 blue: 0 alpha: 1 magenta: red: 211 green: 54 blue: 130 alpha: 1 red: red: 220 green: 50 blue: 47 alpha: 1 white: red: 238 green: 232 blue: 213 alpha: 1 yellow: red: 181 green: 137 blue: 0 alpha: 1 zBright: brightBlack: red: 0 green: 43 blue: 54 alpha: 1 brightMagenta: red: 108 green: 113 blue: 196 alpha: 1 brightGreen: red: 88 green: 110 blue: 117 alpha: 1 brightYellow: red: 101 green: 123 blue: 131 alpha: 1 brightBlue: red: 131 green: 148 blue: 150 alpha: 1 brightCyan: red: 147 green: 161 blue: 161 alpha: 1 brightWhite: red: 253 green: 246 blue: 227 alpha: 1 brightRed: red: 203 green: 75 blue: 22 alpha: 1]]>

In order to free those who are stuck pixel hunting, I’ve created a table of where the items can be found as a kind of mini walkthrough. [U] means that the item is unlocked on completing a puzzle for that location. Curved brackets indicate the item is placed there.

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |

Letters /3 | (-) | 1 | - | - | 1 | - | - | - | 1 | - | - | - | - |

Switch /10 | 1 | - | 1 | 1 | - | - | 1 | 1 | (2) | 1 | - | - | 2 |

Tooth /7 | 1 | 1 | - | 1 | - | - | 1 | - | - | (-) | 1 | 1 | 1 |

Tongue /8 | - | - | 1 | - | 1 | - | 1 | - | 1 | - | 2 | (-) | 2 |

Ball /4 | - | - | - | - | - | (-) | - | 1 | - | - | - | - | 3 |

Sun Symbol /6 | [U] | - | - | - | - | [U] | - | ([U]) | 1 | 1 | - | - | 1 |

Keys /4 | - | - | - | - | - | - | - | [U] | [U] | [U] | - | [U] | (-) |

Here it is in C++:

#include <iostream> #include <math.h> #include <cstdio> int toGraphNum(double x) { if(x < 1) { return 1; } if(x < 2) { return 2; } if(x < 5) { return 5; } if(x > 5) { return 10; } } int graphScaler(double largest, double smallest, int squares); int graphScaler(double difference, int squares); int main() { double largest; double smallest; int bigSquares; std::cout << "Please enter the largest number:"; std::cin >> largest; std::cout << "Please enter the smallest number:"; std::cin >> smallest; double difference = abs(largest - smallest); std::cout << "Please enter the number of big squares:"; std::cin >> bigSquares; int bigSquareVal = graphScaler(difference, bigSquares); std::cout << "Each big square is worth: " << bigSquareVal << std::endl; //Utilisation = {plotted data range}/{total axis range = amount per square * count(squares)} std::cout << "Graph utilisation percentage = " << difference / (bigSquareVal * bigSquares) * 100 << std::endl; std::cout << "Press enter to continue..."; std::cin.get(); return 0; } int graphScaler(double largest, double smallest, int squares) { graphScaler((static_cast(abs(largest - smallest)), squares); } int graphScaler(double difference, int squares) { double nastyGradation = (difference/squares); int ngOrder = pow(10,floor(log10(nastyGradation))); return toGraphNum(nastyGradation/ngOrder) * ngOrder; }

Here it is in Ruby (you could run it on your phone with Ruboto IRB):

def toNN(num) return 1 if(num < 1) return 2 if(num < 2) return 4 if(num < 4) return 5 if(num < 5) return 10 if(num > 5) end def graphScaler(difference, squares) ng = difference/squares ngOrder = 10 ** Math.log(ng).floor return toNN(ng/ngOrder) * ngOrder end #Shortcut def gs(d,s) return graphScaler(d,s); end]]>

Change “/etc/dovecot-sql.conf” to “/etc/dovecot/dovecot-sql.conf” (in your /etc/dovecot/dovecot.conf file) then restart Dovecot.

Alas, 4 days later I get the news that no one can log in to Roundcube. After a long time, the message “Connection to imap server failed.” would be shown. I tried to telnet into the Dovecot IMAP server, using “telnet localhost 143“. The response was

* OK Waiting for authentication process to respond..

when I hadn’t even entered any login details.

After a while I got a:

* BYE Disconnected for inactivity. Connection closed by foreign host.

I found this confusing but it seemed to point at the authentication process.

Checking the error logs confirmed this:

May 25 11:10:43 server dovecot: auth: Error: Can't open configuration file /etc/dovecot-sql.conf: No such file or directory May 25 11:10:43 server dovecot: master: Error: service(auth): command startup failed, throttling May 25 11:10:43 server dovecot: log: Error: service(auth): child 24452 returned error 89 (Fatal failure)

I checked /etc/dovecot/dovecot-sql.conf (obviously I wasn’t reading carefully enough) and everything seemed fine.

Naturally I Googled “Error: Can’t open configuration file /etc/dovecot-sql.conf” with the quotes. This lead me to the ISPConfig installation guide comments.

A commenter points out the discrepancy between “/etc/dovecot-sql.conf” and “/etc/dovecot/dovecot-sql.conf”. After a quick change in the /etc/dovecot.conf file and a “service dovecot restart”, it worked perfectly.

#/etc/dovecot/dovecot.conf passdb { ## args = /etc/dovecot-sql.conf args = /etc/dovecot/dovecot-sql.conf driver = sql } userdb { ## args = /etc/dovecot-sql.conf args = /etc/dovecot/dovecot-sql.conf driver = sql }

I hope this post helps anyone with the same issue.

]]>