Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions _posts/2026-08-15-book-review-animal-farm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
layout: post
title: "Book review 'Animal Farm'"
date: "2026-08-15 12:08:25 +0530"
tags:
- books
---


![Street mural of a pig in a business suit, painted below the words Animal
Farm]({{ site.url }}{{ site.baseurl }}/assets/images/animal_farm_bookreview/title.jpg)


### Introduction


Animal Farm is the best book I read in 2017. George Orwell published it in
1945, and it remains one of his best known and most influential works. He is
remembered for turning political argument into plain, sharp storytelling, and
for handing English the vocabulary we still reach for when power lies to us.
In 2008 The Times ranked him second on its list of "The 50 greatest British
writers since 1945".

The sentences are short and plain, and that plainness is doing real work. The
book never tells you what to feel about the farm. It reports what happens,
calmly, until the reporting itself becomes the argument. It runs to fewer than
100 pages and I finished it in two sittings.


### Plot summary

A group of animals lives on a farm under the rule of its owner. One night Old
Major, an old pig, calls everyone to a meeting. He explains what freedom would
mean and points out that the animals of that farm choose neither their work nor
their food. He urges them to rebel, and names humans as the enemy. Old Major
dies a few nights later, and that lecture becomes his last words. The animals
unite against their master and succeed in driving him off his own farm.

One group of pigs declares itself the educated class and asks to be allowed to
make every decision for the farm. Under the leadership of two pigs the animals
are happy, because for the first time they are working for fellow animals
rather than for people. The owner returns with a group of men to take revenge,
and it is a pleasure to read how the animals fight them off. They win the
battle, and afterwards they add an amendment declaring humans their greatest
enemy.

The story takes many tragic turns from there. The pigs in leadership spend
their effort on making their own lives more comfortable and pay no attention to
anyone else. Because they read better than the rest, they can describe growth
that never happened to animals who are barely literate or not literate at all,
and that imaginary growth is enough to keep the others believing. Meanwhile a
small dispute between the two leaders grows. Fearing for his control, one of
them drives the other off the farm with a pack of dogs he has raised in secret.
The democracy becomes a dictatorship.

The dictator announces that he will improve the farm, and convinces every
animal to pour its effort into building a windmill — effort that used to go
into growing the animals' own food. A few more battles with humans follow, and
they wreck the mill and break the animals' morale. It is shocking to read how
the leader sells off the best of the farm's animals to fund his own comforts,
until the independent farm depends on humans again and then goes bankrupt. The
animals keep faith that whatever their captain decided was in their favour. The
struggle drags on, and in the end the humans simply buy him, with a large
bribe, to supply whatever the farm produces.


### Closing thoughts

The book has left a deep impression on me. The effect is strong enough that I
now weigh every sentence I hear from people in power. From now on I will not
follow any political leader blindly. I am thankful to my guru [Xitij
Shukla](https://www.linkedin.com/in/xitijshukla/), who encouraged me to read
this book. Orwell's writing impressed me so much that I bought another of his
books, [1984](https://www.goodreads.com/book/show/40961427-1984). I hope you
are enjoying my blog posts. Please share your views with me at
[jaysinhp@gmail.com](mailto:jaysinhp@gmail.com). It would be a great
opportunity for me to improve.


### Links

* [Goodreads](https://www.goodreads.com/book/show/170448.Animal_Farm)

* [Amazon worldwide](https://www.amazon.com/Animal-Farm-George-Orwell/dp/0451526341)

* [Amazon India](https://www.amazon.in/Animal-Farm-George-Orwell/dp/8193387643)


###### Proofreaders: [jesusinadidas](https://github.com/jesusinadidas)
Binary file added assets/images/animal_farm_bookreview/title.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 73 additions & 11 deletions scripts/optimize-images
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ set -euo pipefail
cd "$(dirname "$0")/.."

# Budgets, in bytes. A photo is displayed at roughly 800px, so 1600px covers
# high-density screens with room to spare; 300 KB is comfortably above the
# largest photo once it has been through the pipeline below.
# high-density screens with room to spare.
readonly MAX_PHOTO_BYTES=307200 # 300 KB — jpg, png
readonly MAX_PHOTO_EDGE=1600

# 1600px is where photos start, not where they have to end up. A busy photo can
# still miss the budget there: the Animal Farm mural lands at 403 KB, and no
# amount of re-running helps because the result is stable. So the encoder walks
# this ladder and keeps the widest size that fits. Narrowing beats lowering
# quality — at the sizes that do fit, 1200px/q80 holds edges that 1600px/q65
# smears, for about the same bytes.
readonly PHOTO_EDGES="1600 1400 1200 1000"
readonly PHOTO_QUALITY=80

# Animated screencasts cost far more because they carry hundreds of frames.
# Resizing is the only lever that helps them: palette reduction and lossy LZW
Expand Down Expand Up @@ -79,14 +86,53 @@ require() {
}
}

# Write "$1" into "$2" at the widest ladder size that fits "$3" bytes, falling
# through to the narrowest if none do. Every attempt re-reads the untouched
# original, so a narrow attempt never stacks its loss on top of a wider one.
#
# sips resizes well but writes bulky JPEGs — on a 2048px photo its encoder
# produced 452 KB where cjpeg produces 262 KB from the same pixels. So sips only
# resizes, and cjpeg does the encoding.
encode_jpeg() {
local src=$1 dest=$2 budget=$3 edge base png
# sips picks its output format from the extension, so the scratch file needs
# one. mktemp owns the name without it; both get cleaned up below.
base=$(mktemp -t optimize-images)
png="$base.png"

for edge in $PHOTO_EDGES; do
sips -Z "$edge" -s format png "$src" --out "$png" >/dev/null
cjpeg -quality "$PHOTO_QUALITY" -optimize -progressive "$png" > "$dest"
if [ "$(file_size "$dest")" -le "$budget" ]; then
break
fi
done

rm -f "$base" "$png"
}

# Same ladder for PNGs, which sips resizes in place without a separate encoder.
encode_png() {
local src=$1 dest=$2 budget=$3 edge

for edge in $PHOTO_EDGES; do
cp "$src" "$dest"
sips -Z "$edge" "$dest" >/dev/null
if [ "$(file_size "$dest")" -le "$budget" ]; then
break
fi
done
}

optimize() {
require sips "It ships with macOS."
require cjpeg "Install with: brew install jpeg-turbo"
require gifsicle "Install with: brew install gifsicle"

local file size budget tmp before after
local file size budget tmp before after stubborn
before=0
after=0
stubborn=""

while IFS= read -r file; do
size=$(file_size "$file")
Expand All @@ -108,28 +154,44 @@ optimize() {
mv "$tmp" "$file"
;;
png|PNG)
sips -Z "$MAX_PHOTO_EDGE" "$file" >/dev/null
tmp=$(mktemp -t optimize-images)
encode_png "$file" "$tmp" "$budget"
mv "$tmp" "$file"
;;
*)
# sips resizes well but writes bulky JPEGs — on a 2048px photo its
# encoder produced 452 KB where cjpeg produces 262 KB from the same
# pixels. So sips only resizes, and cjpeg does the encoding.
tmp=$(mktemp -t optimize-images)
sips -Z "$MAX_PHOTO_EDGE" -s format png "$file" --out "$tmp.png" >/dev/null
cjpeg -quality 80 -optimize -progressive "$tmp.png" > "$tmp"
encode_jpeg "$file" "$tmp" "$budget"
mv "$tmp" "$file"
rm -f "$tmp.png"
;;
esac

size=$(file_size "$file")
after=$((after + size))
printf ' %-58s -> %8s\n' "$file" "$(human "$size")"

if [ "$size" -gt "$budget" ]; then
stubborn="$stubborn $file — $(human "$size") (budget $(human "$budget"))
"
fi
done < <(find "$IMAGE_DIR" -type f \
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.gif' \) \
| sort)

printf '\n%s -> %s\n' "$(human "$before")" "$(human "$after")"

# The ladder bottoms out, and some images will still not fit. Say so and fail.
# Exiting 0 here would be worse than useless: --check rejects the file anyway,
# and its advice is to run this script, which has already done all it can.
if [ -n "$stubborn" ]; then
cat >&2 <<EOF

Still over budget after every size available:

$stubborn
Crop these, or replace them with a lighter image.
EOF
return 1
fi
}

case "${1:-}" in
Expand Down
Loading