Trying out (and liking!) MeetingBar for macOS

My GitHub colleague @joelhawksley recommended a macOS app called MeetingBar.

I installed it today and it looks like this:

If you click on it, it shows another view of other (next) upcoming events and other all-day events going on.

Converting Celsius to Fahrenheit round-up

July 22, 20240 commentsGo, Node, Python, Bun, Ruby, Rust, JavaScript

In the last couple of days, I've created variations of a simple algorithm to demonstrate how Celcius and Fahrenheit seem to relate to each other if you "mirror the number".
It wasn't supposed to be about the programming language. Still, I used Python in the first one and I noticed that since the code is simple, it could be fun to write variants of it in other languages.

It was a fun exercise.

And speaking of fun, I couldn't help but to throw in a benchmark using `hyperfine` that measures, essentially, how fast these CLIs can start up. The results look like this:

``````
Summary
./conversion-rs ran
1.31 ± 1.30 times faster than ./conversion-go
1.88 ± 1.33 times faster than ./conversion-cr
7.15 ± 4.64 times faster than bun run conversion.ts
14.27 ± 9.48 times faster than python3.12 conversion.py
18.10 ± 12.35 times faster than node conversion.js
67.75 ± 43.80 times faster than ruby conversion.rb
``````

It doesn't prove much, that you didn't expect. But it's fun to see how fast Python 3.12 has become at starting up.

Head on over to https://github.com/peterbe/temperature-conversion to play along. Perhaps you can see some easy optimizations (speed and style).

Node watch mode and TypeScript

You might have heard that Node now has watch mode. It watches the files you're saving and re-runs the `node` command automatically. Example:

``````
// example.js

function c2f(c) {
return (c * 9) / 5 + 32;
}
console.log(c2f(0));
``````

Now, run it like this:

```❯ node --watch example.js
32
Completed running 'example.js'```

Edit that `example.js` and the terminal will look like this:

```Restarting 'example.js'
32
Completed running 'example.js'```

(even if the file didn't change. I.e. you just hit Cmd-S to save)

Now, `node` doesn't understand TypeScript natively, yet. So what are you to do: Use `@swc-node/register`! (see npmjs here)
You'll need to have a `package.json` already or else use globally installed versions.

Example, using `npm`:

``````
npm init -y
npm install -D typescript @swc-node/register
npx tsc --init
``````

Now, using:

``````
// example.ts

function c2f(c: number) {
return (c * 9) / 5 + 32;
}
console.log(c2f(123));
``````

You can run it like this:

``````
❯ node --watch --require @swc-node/register example.ts
253.4
Completed running 'example.ts'
``````

Converting Celsius to Fahrenheit with Rust

Previously in this series:

This time, in Rust:

``````
fn c2f(c: i8) -> f32 {
let c = c as f32;
c * 9.0 / 5.0 + 32.0
}

fn is_mirror(a: i8, b: i8) -> bool {
let a = massage(a);
let b = reverse_string(massage(b));
a == b
}

fn massage(n: i8) -> String {
if n < 10 {
return format!("0{}", n);
} else if n >= 100 {
return massage(n - 100);
} else {
return format!("{}", n);
}
}

fn reverse_string(s: String) -> String {
s.chars().rev().collect()
}

fn print_conversion(c: i8, f: i8) {
println!("{}°C ~= {}°F", c, f);
}

fn main() {
let mut c = 4;
while c < 100 {
let f = c2f(c);
if is_mirror(c, f.ceil() as i8) {
print_conversion(c, f.ceil() as i8)
} else if is_mirror(c, f.floor() as i8) {
print_conversion(c, f.floor() as i8)
} else {
break;
}
c += 12;
}
}
``````

Run it like this:

``````
rustc -o conversion-rs conversion.rs && ./conversion-rs
``````

and the output becomes:

```4°C ~= 40°F
16°C ~= 61°F
28°C ~= 82°F
40°C ~= 104°F
52°C ~= 125°F```

Converting Celsius to Fahrenheit with Crystal

Previously in this series:

Crystal?

Crystal is a general-purpose, object-oriented programming language. With syntax inspired by Ruby, it's a compiled language with static type-checking.

``````
def c2f(c)
c * 9.0 / 5 + 32;
end

def is_mirror(a, b)
massage(a).reverse == massage(b)
end

def massage(n)
if n < 10
"0#{n}"
elsif n >= 100
massage(n - 100)
else
n.to_s
end
end

def print_conv(c, f)
puts "#{c}°C ~= #{f}°F"
end

(4...100).step(12).each do |c|
f = c2f(c)
if is_mirror(c, f.ceil.to_i)
print_conv(c, f.ceil.to_i)
elsif is_mirror(c, f.floor.to_i)
print_conv(c, f.floor.to_i)
else
break
end
end
``````

And this is its diff with the Ruby version:

``````
<     if is_mirror(c, f.ceil)
<         print_conv(c, f.ceil)
<     elsif is_mirror(c, f.floor)
<         print_conv(c, f.floor)
---
>     if is_mirror(c, f.ceil.to_i)
>         print_conv(c, f.ceil.to_i)
>     elsif is_mirror(c, f.floor.to_i)
>         print_conv(c, f.floor.to_i)
``````

Run it like this:

``````
crystal conversion.cr
``````

or build and run:

``````
crystal build -o conversion-cr conversion.cr
./conversion-cr
``````

and the output becomes:

```4°C ~= 40°F
16°C ~= 61°F
28°C ~= 82°F
40°C ~= 104°F
52°C ~= 125°F```

Converting Celsius to Fahrenheit with Ruby

This is a continuation of Converting Celsius to Fahrenheit with Python, and TypeScript, and Go but in Ruby:

``````
def c2f(c)
c * 9.0 / 5 + 32;
end

def is_mirror(a, b)
def massage(n)
if n < 10
"0#{n}"
elsif n >= 100
massage(n - 100)
else
n.to_s
end
end
massage(a).reverse == massage(b)
end

def print_conv(c, f)
puts "#{c}°C ~= #{f}°F"
end

(4...100).step(12).each do |c|
f = c2f(c)
if is_mirror(c, f.ceil)
print_conv(c, f.ceil)
elsif is_mirror(c, f.floor)
print_conv(c, f.floor)
else
break
end
end
``````

Run it like this:

``````
ruby conversion.rb
``````

and the output becomes:

```4°C ~= 40°F
16°C ~= 61°F
28°C ~= 82°F
40°C ~= 104°F
52°C ~= 125°F```