-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #776 from alexwlchan/port-all-tils
Bring across all the existing TIL files
- Loading branch information
Showing
66 changed files
with
2,428 additions
and
1 deletion.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
layout: til | ||
title: Calley-ope (calliope) Syndrome is pronouncing a word wrong because you’ve only ever read it on the page | ||
date: 2021-12-27 08:45:38 +0000 | ||
tags: | ||
- interesting-words | ||
--- | ||
This is a phrase that goes around the Internet every once in a while, but there's no definitive reference page for it. | ||
|
||
## Where does it come from? | ||
|
||
Several sources on the Internet point to Judith Wynn Halsted's book *Some of My Best Friends Are Books: Guiding Gifted Readers*. | ||
The Internet Archive has digitised the second edition from 2002, and the relevant passage is [on page 207](https://archive.org/details/someofmybestfrie00hals/page/206/mode/2up?q=syndrome): | ||
|
||
> Books that contain pronunciation guides are helpful for gifted readers (though they are rare, and a pleasant surprise when found), since so many avid readers know words only from reading and therefore mispronounce them. One excellent teacher of gifted high school students calls this “The Calley-ope (calliope) Syndrome.” | ||
An almost-identical passage appears in one of her earlier books, *Guiding Gifted Readers*, published in 1988. | ||
(The two books have a very similar structure, so I think this is a "first edition" of *Some of My Best Friends* – but of course, not described that way at time of publication.) | ||
It's been digitised by the Internet Archive and the passage is [on page 126](https://archive.org/details/guidinggiftedrea0000hals/page/126/mode/2up?q=calliope): | ||
|
||
> Pronunciation guides are helpful for gifted readers (though they are rare, and a pleasant surprise when found), since so many of them know words only from reading and therefore mispronounce them. One excellent teacher of gifted high school students calls this “The Calley-ope (calliope) Syndrome.” | ||
But this doesn't tell me which teacher coined the phrase! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
--- | ||
layout: til | ||
date: 2023-05-23 21:05:27 +0000 | ||
title: How to profile Swift code | ||
tags: | ||
- swift | ||
--- | ||
[Stack Overflow coughed up a snippet which I've adapted](https://stackoverflow.com/a/24755958/1558022): | ||
|
||
```swift | ||
let start = DispatchTime.now() | ||
var elapsed = start | ||
|
||
func printElapsed(_ label: String) -> Void { | ||
let now = DispatchTime.now() | ||
|
||
let totalInterval = Double(now.uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000_000 | ||
let elapsedInterval = Double(now.uptimeNanoseconds - elapsed.uptimeNanoseconds) / 1_000_000_000 | ||
|
||
elapsed = DispatchTime.now() | ||
|
||
print("Time to \(label):\n \(elapsedInterval) seconds (\(totalInterval) total)") | ||
} | ||
``` | ||
|
||
e.g. in this profiling: | ||
|
||
```console | ||
$ time swift actions/run_action.swift 934BD809-D6D9-4147-AE7E-E1701C82AADD/L0/001 toggle-rejected | ||
Time to waking up: | ||
1.3583e-05 seconds | ||
Time to get photo: | ||
0.110328541 seconds | ||
Time to enter switch: | ||
0.1103705 seconds | ||
Time to toggle needs action: | ||
0.159904833 seconds | ||
Time to all done: | ||
0.211530583 seconds | ||
|
||
________________________________________________________ | ||
Executed in 523.46 millis fish external | ||
usr time 136.72 millis 60.00 micros 136.66 millis | ||
sys time 52.85 millis 683.00 micros 52.17 millis | ||
``` | ||
|
||
it's pretty obvious the "time to get photo" step is the slow one | ||
|
||
The Stack Overflow answer suggests using `ContinuousClock`; that was in a newer version of Swift than I had available when I wrote this snippet – for now I'm sticking with what I've got and which I know works. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
--- | ||
layout: til | ||
title: Use concurrency gates to prevent concurrent deployments | ||
date: 2023-06-01 20:37:05 +0000 | ||
tags: | ||
- buildkite | ||
--- | ||
Concurrency gates are a Buildkite feature you can use to "lock" certain tasks, e.g. ensure that you're only deploying one copy of an app at a time. | ||
The pattern is described [in a Buildkite blog post](https://buildkite.com/blog/concurrency-gates), but it took actually implementing it [in Wellcome's front-end builds](https://github.com/wellcomecollection/wellcomecollection.org/pull/9884) to wrap my head around it. | ||
|
||
Here's a simplified version of the Buildkite YAML from that PR, with my comments intact -- which are what helped me understand it. | ||
|
||
```yaml | ||
steps: | ||
- label: "Deploy to prod environment" | ||
command: "deploy_to_prod_environment.sh" | ||
|
||
# These three lines create a "lock" around this pipeline. | ||
# | ||
# This means that once a deployment starts to an environment, | ||
# no other builds will deploy to that environment until this | ||
# deployment is complete and has run the end-to-end tests. | ||
# | ||
# == How it works == | ||
# | ||
# This uses the "concurrency gate" pattern described in the Buildkite blog | ||
# here: https://buildkite.com/blog/concurrency-gates | ||
# | ||
# Once this job starts running, this build has to either: | ||
# | ||
# 1) fail, or | ||
# 2) complete all the other tasks in this concurrency group -- which is | ||
# just the "Complete!" task at the end of the pipeline | ||
# | ||
# before any other build is allowed to run tasks in this concurrency group. | ||
# This means no other build can start a new deployment until this deployment | ||
# is complete. | ||
concurrency_group: "front-end-deployment-gate" | ||
concurrency: 1 | ||
|
||
- wait | ||
|
||
- label: "Run end-to-end tests on the new deployment" | ||
command: "run_e2e_tests.sh" | ||
|
||
- wait | ||
|
||
- label: "Complete the deployment" | ||
command: echo "Deployment complete!" | ||
|
||
# This is the second half of the concurrency gate described above. | ||
# | ||
# Buildkite won't let any other pipelines run in this concurrency group until | ||
# this step has run (or the entire deployment has failed). | ||
# | ||
# When this step completes, it "unlocks" the deployment and allows other | ||
# deployments to begin. | ||
concurrency_group: "front-end-deployment-${BUILDKITE_GITHUB_DEPLOYMENT_ENVIRONMENT}-gate" | ||
concurrency: 1 | ||
``` |
32 changes: 32 additions & 0 deletions
32
src/_til/2023/2023-09-06-use-unicode-property-escapes-to-find-emoji.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
--- | ||
layout: til | ||
title: Use Unicode property escapes to detect emoji in JavaScript | ||
date: 2023-09-06 23:46:15 +0000 | ||
tags: | ||
- javascript | ||
- unicode | ||
--- | ||
From [how to detect emoji using JavaScript](https://stackoverflow.com/a/64007175/1558022) on Stack Overflow: | ||
|
||
> The answers might work but are terrible because they rely on unicode ranges that are unreadable and somewhat "magic" because it's not always clear where do they come from and why they work, not to mention they're not resilient to new emojis being added to the spec. | ||
> | ||
> Major browsers now support [unicode property escape](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes) which allows for matching emojis based on their belonging in the `Emoji` unicode category: `\p{Emoji}` matches an emoji, `\P{Emoji}` matches a non-emoji. | ||
which includes some example code: | ||
|
||
```javascript | ||
console.log( | ||
/\p{Emoji}/u.test('flowers'), // false :) | ||
/\p{Emoji}/u.test('flowers 🌼🌺🌸'), // true :) | ||
/\p{Emoji}/u.test('flowers 123'), // true :( | ||
) | ||
console.log( | ||
/\p{Extended_Pictographic}/u.test('flowers'), // false :) | ||
/\p{Extended_Pictographic}/u.test('flowers 🌼🌺🌸'), // true :) | ||
/\p{Extended_Pictographic}/u.test('flowers 123'), // false :) | ||
) | ||
``` | ||
|
||
But this doesn't just apply to emoji – the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) explains you can also use this for different chunks of the Unicode spectrum, e.g. `\P{Script_Extensions=Latin}` or `\p{Letter}`. | ||
|
||
I used this to detect emoji [as part of enhanced spam detection](https://github.com/wellcomecollection/wellcomecollection.org/pull/10181) in Wellcome Collection's catalogue search. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
layout: til | ||
title: "The acronym \"woe\" in the Flickr API stands for \"Where On Earth\"" | ||
date: 2023-10-02 17:29:30 +0000 | ||
tags: | ||
- flickr | ||
- naming-things | ||
--- | ||
For example, the parameter in the [flickr.places.placesForContacts API][api]: | ||
|
||
> <dl> | ||
> <dt><code>woe_id</code> (Optional)</dl> | ||
> <dd>A Where on Earth identifier to use to filter photo clusters. For example all the photos clustered by <strong>locality</strong> in the United States (WOE ID <strong>23424977</strong>).</dd> | ||
> </dl> | ||
[api]: https://www.flickr.com/services/api/flickr.places.placesForContacts.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
layout: til | ||
date: 2023-10-10 15:42:27 +0000 | ||
title: Why the term "snak" keeps appearing in the Wikidata API | ||
tags: | ||
- wikimedia-commons | ||
- naming-things | ||
--- | ||
This is one of those terms I kept seeing in API responses and documentation, but it wasn't immediately obvious to me what it means. | ||
I found an explanation in the [Wikibase/DataModel](https://www.mediawiki.org/wiki/Wikibase/DataModel#Overview_of_the_data_model) docs: | ||
|
||
> For lack of a better name, any such basic assertion that one can make in Wikidata is called a **Snak** (which is small, but more than a byte). This term will not be relevant for using Wikidata (editors will not encounter it), but it is relevant for developers to avoid confusion with Statements or other claims. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
layout: til | ||
date: 2023-10-16 16:45:35 +0000 | ||
title: Find files that use a particular SDC field | ||
tags: | ||
- wikimedia-commons | ||
- sparql | ||
--- | ||
## Using Special:MediaSearch | ||
|
||
You can do structured data queries using [Special:MediaSearch](https://www.mediawiki.org/wiki/Help:MediaSearch#Statements_and_structured_data). | ||
Here are a couple of examples: | ||
|
||
* To find uses of a particular statement: | ||
|
||
* Videos with property P1651 (YouTube video ID): <https://commons.wikimedia.org/wiki/Special:MediaSearch?type=video&search=haswbstatement%3AP1651> | ||
* Images with property P12120 (Flickr photo ID): <https://commons.wikimedia.org/wiki/Special:MediaSearch?type=image&search=haswbstatement%3AP12120> | ||
|
||
* To find a statement with a particular value: | ||
|
||
* Images with P7482=Q66458942 (source of file is original creation by uploader): <https://commons.wikimedia.org/wiki/Special:MediaSearch?search=haswbstatement%3AP7482%3DQ66458942&type=image> | ||
|
||
## Using the Commons Query Service | ||
|
||
You can run SPARQL queries with the [Commons Query Service](https://commons.wikimedia.org/wiki/Commons:SPARQL_query_service). | ||
I'm not super experienced with SPARQL, but I'll use this as a place to gather queries I've been able to get working. | ||
|
||
* This is a query that finds files which have a P7482=Q74228490, P137=Q420747, and one of two Flickr URLs in the P973 field. | ||
|
||
```sparql | ||
SELECT ?item ?described_url WHERE { | ||
?item wdt:P7482 wd:Q74228490 . # P7482 (source of file) = Q74228490 (file available on the internet) | ||
?item p:P7482 ?statement . | ||
?statement pq:P137 wd:Q103204. # P137 (operator) = Q420747 (National Library of Finland) | ||
?statement pq:P973 ?described_url. | ||
VALUES (?described_url) { (<https://www.flickr.com/photos/sunrise/29916169/>) (<https://www.flickr.com/photos/sunrise/29916169>) } | ||
} LIMIT 1 | ||
``` | ||
[Link to query in WCQS](https://commons-query.wikimedia.org/#SELECT%20%3Fitem%20%3Fdescribed_url%20WHERE%20%7B%0A%20%20%3Fitem%20wdt%3AP7482%20wd%3AQ74228490%20.%20%20%20%20%20%20%20%23%20P7482%20%28source%20of%20file%29%20%3D%20Q74228490%20%28file%20available%20on%20the%20internet%29%0A%20%20%3Fitem%20p%3AP7482%20%3Fstatement%20.%0A%20%20%3Fstatement%20pq%3AP137%20wd%3AQ103204.%20%20%20%20%20%20%20%23%20P137%20%28operator%29%20%3D%20Q420747%20%28National%20Library%20of%20Finland%29%0A%20%20%3Fstatement%20pq%3AP973%20%3Fdescribed_url.%0A%20%20VALUES%20%28%3Fdescribed_url%29%20%7B%20%28%3Chttps%3A%2F%2Fwww.flickr.com%2Fphotos%2Fsunrise%2F29916169%2F%3E%29%20%28%3Chttps%3A%2F%2Fwww.flickr.com%2Fphotos%2Fsunrise%2F29916169%3E%29%20%7D%0A%7D%20LIMIT%201), which returns a single result. | ||
* This is a query that finds users with a particular value in the Flickr User ID field: | ||
```sparql | ||
SELECT ?image WHERE { | ||
# P170 (creator) / P3267 (Flickr user ID) = specified ID | ||
?file p:P170 ?creator . | ||
?creator pq:P3267 "52498302@N08" . | ||
# Retrieve the image URL to display as a link | ||
?file schema:url ?image . | ||
} | ||
``` | ||
[Link to query in WCQS](https://commons-query.wikimedia.org/#SELECT%20%3Fimage%20WHERE%20%7B%0A%20%20%23%20P170%20%28creator%29%20%2F%20P3267%20%28Flickr%20user%20ID%29%20%3D%20specified%20ID%0A%20%20%3Ffile%20p%3AP170%20%3Fcreator%20.%0A%20%20%3Fcreator%20pq%3AP3267%20%2252498302%40N08%22%20.%0A%20%20%0A%20%20%23%20Retrieve%20the%20image%20URL%20to%20display%20as%20a%20link%0A%20%20%3Ffile%20schema%3Aurl%20%3Fimage%20.%0A%7D%0A) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
layout: til | ||
title: How to do resumable downloads with curl | ||
date: 2023-10-17 20:10:10 +0000 | ||
tags: | ||
- curl | ||
--- | ||
The flag you want is [`--continue-at -`](https://curl.se/docs/manpage.html#-C), which will resume the transfer from the size of the already-downloaded file. | ||
|
||
Here's an example of using it in practice. | ||
|
||
```bash | ||
curl \ | ||
--location \ | ||
--remote-name \ | ||
--continue-at - \ | ||
https://dumps.wikimedia.org/other/wikibase/commonswiki/20231009/commons-20231009-mediainfo.json.bz2 | ||
``` | ||
|
||
It behaves in a "sensible" way at the beginning and end of the download: | ||
|
||
* If you haven't downloaded anything yet, it starts downloading from the first byte of the remote file. | ||
* If you've already downloaded the complete file, it stops as soon as it checks the byte count with the remote server. |
54 changes: 54 additions & 0 deletions
54
src/_til/2023/2023-12-08-convert-between-m-ids-and-filenames.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
layout: til | ||
date: 2023-12-08 20:58:33 +0000 | ||
title: Go between M-IDs and filenames on Wikimedia Commons | ||
tags: | ||
- wikimedia-commons | ||
--- | ||
Every file on Wikimedia Commons has two identifiers: | ||
|
||
* A filename, e.g. `File:Herestraat Groningen.JPG`. | ||
This always starts with `File:` because these are pages in the [File namespace][namespaces] | ||
* A numeric identifier, e.g. `M128`. | ||
This is a unique dientifier for each file on Commons, similar to Q IDs for entities on Wikidata. | ||
|
||
The APIs for searching/updating Wikimedia Commons typically accept both forms; sometimes it's convenient to go between the two. | ||
|
||
1. To go from filename to numeric ID, you can use the [Query API][query] and do a search with the `titles` parameter. | ||
The M ID is included in the response. | ||
|
||
For example: | ||
|
||
```console | ||
$ curl 'https://commons.wikimedia.org/w/api.php?action=query&format=xml&titles=File:Herestraat%20Groningen.JPG' | ||
<?xml version="1.0"?> | ||
<api batchcomplete=""> | ||
<query> | ||
<pages> | ||
<page _idx="128" pageid="128" ns="6" title="File:Herestraat Groningen.JPG"/> | ||
</pages> | ||
</query> | ||
</api> | ||
``` | ||
|
||
2. To go from numeric ID to filename, go to `https://commons.wikimedia.org/?curid=[ID]`. | ||
|
||
For example, <https://commons.wikimedia.org/?curid=128>. | ||
|
||
Alternatively, you can use the Query API with the `pageids` parameter. | ||
For example: | ||
|
||
```console | ||
$ curl 'https://commons.wikimedia.org/w/api.php?action=query&format=xml&pageids=128' | ||
<?xml version="1.0"?> | ||
<api batchcomplete=""> | ||
<query> | ||
<pages> | ||
<page _idx="128" pageid="128" ns="6" title="File:Herestraat Groningen.JPG"/> | ||
</pages> | ||
</query> | ||
</api> | ||
``` | ||
|
||
[query]: https://www.mediawiki.org/wiki/API:Query | ||
[namespaces]: https://commons.wikimedia.org/wiki/Help:Namespaces |
Oops, something went wrong.
48b4b5b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Published on https://alexwlchan.net as production
🚀 Deployed on https://6613e2dadac15e10d782c677--alexwlchan.netlify.app