SlideShare a Scribd company logo
1 of 42
Download to read offline
The Art of Readable
Code (Ch1~Ch4)
Jonghan Seo
Ch1. Code Should Be Easy to
Understand
● collected bunch of examples of “bad code”
● analyzed what made them bad
● found principles/techniques that can be used to make them better
● Key Idea: Code should be easy to
understand
What Makes Code “Better”?
● sometimes it is fairly obvious
What Makes Code “Better”?
● sometimes it is vague
more compact !!!
less intimidating !!!
The Fundamental Theorem of Readability
● Code should be written to minimize the time it would take for someone
else to understand
● to fully understand your code:
○ be able to make changes to it
○ be able to spot bugs
○ be able to understand how it interacts with the rest of your code
● ‘someone else’ would be you
Some Different Views
● The Smaller The Better?
○ It probably takes less time to understand fewer lines BUT it is not
always better!
○ the time-till-understanding is an even better goal
● What about other constraints?
○ code efficiency? well architectured? easy to test? …
○ making code easy to understand often leads to meet the other rules
● the rest of this book discusses how to apply ‘easy to read’ in different
circumstances
● There are four parts:
○ Part One: Surface-Level Improvements
○ Part Two: Simplifying Loops and Logic
○ Part Three: Reorganizing Your Code
○ Part Four: Selected Topics
● Surface-Level Improvements
○ picking good names
○ writing good comments
○ formatting your code neatly
Contents
Ch2. Packing Information into
Names
● Key Idea: Pack information into your names
● Six Specific Topics
1. Choosing specific words
2. Avoiding generic names (or knowing when to use them)
3. Using concrete names instead of abstract names
4. Attaching extra information to a name, by using a suffix or prefix
5. Deciding how long a name should be
6. Using name formatting to pack extra information
1. Choose Specific Words
● def GetPage(url): …
○ from a local cache? from a database? from the Internet?
○ FetchPage(), DownloadPage()
● class BinaryTree {
int size();
...
}
○ height of the tree? the number of codes? memory footprint of the tree?
○ Height(), NumNodes(), MemoryBytes()
1. Choose Specific Words
2. Avoid Generic Names
● ‘tmp’, ‘retval’, loop iterators
● retval
○ var euclidean_norm = function (v) {
var retval = 0.0;
for (var i = 0 ; i < v.length; i += 1)
retval += v[i] * v[i];
return Math.sqrt(retval);
};
○ reval → sum_squares
○ sum_squares += v[i]; → spot a bug!!
○ Advice: Use a name that describes the variable’s value
2. Avoid Generic Names
● tmp
○ if (right < left) {
tmp = right;
right = left;
left = tmp;
} // it is ok!
○ String tmp = user.name();
tmp += “ “ + user.phone_number();
…
template.set(“user_info”, tmp); // tmp → user_info
● Advice: ‘tmp’ should be used in cases when (1) being short-lived and (2)
temporary is the most important fact about the variable
2. Avoid Generic Names
● Loop Iterators
○ for (int i = 0; i < clubs.size(); i++)
for (int j = 0; j < clubs[i].members.size(); j++)
for (int k = 0; k < users.size(); k++)
if (clubs[i].members[k] == users[j])
cout << "user[" << j << "] is in club[" << i << "]" << endl;
○ (i, j, k) → (club_i, memeber_i, users_i) or (ci, mi, ui)
○ if (clubs[ci].members[ui] == users[mi]) // Bug! First letters don't match up.
3. Prefer Concrete Names Over
Abstract Names
● Example1) Google Code Guide for C++
○ #define DISALLOW_EVIL_CONSTRUCTORS(ClassName) 
ClassName(const ClassName&); 
void operator=(const ClassName&);
class ClassName {
private:
DISALLOW_EVIL_CONSTRUCTORS(ClassName);
};
○ ‘evil’ sounds too strong and more important, it isn’t clear what the
macro is disallowing
○ DISALLOW_COPY_AND_ASSIGN
3. Prefer Concrete Names Over
Abstract Names
● Example2) --run_locally
○ --run_locally
■ printing debugging information
■ used when testing on a local machine
○ What if we need...
■ to print debugging information while the program run remotely?
■ to run a performance test locally (so we do not want the logging
slowing it down)?
○ --run_locally → --extra_logging
4. Attaching Extra Information to a
Name
● string id; //Example: “af84ef845cd8”
→ string hex_id;
5. How Long Should a Name be?
● the implicit constraint: ‘the name shouldn’t be too long’
○ the longer a name, the harder it is to remember and the more space it
consumes on the screen
○ However, if we take the constraint too far it also would make someone
else difficult to understand the code
● There are some guidelines:
○ Shorter names are all right for shorter scope
○ Typing Long Names - Not a Problem Anymore
■ if ‘they’re harder to type’ mattered
■ Make full use of ‘word completion’ built in editors
○ Acronyms and Abbreviations
■ project-specific abbreviations: Bad Idea
■ common to programmers: OK!
● evaluation → eval, document → doc, string → str
○ Throwing out Unneeded Words
■ ConvertToString() → ToString()
■ DoServerLoop() → ServerLoop()
5. How Long Should a Name be?
6. Use Name Formatting to
Convey Meaning
● In C++:
static const int kMaxOpenFiles = 100;
class LogReader {
public:
void OpenFile(string local_file);
private:
int offset_;
DISALLOW_COPY_AND_ASSIGN(LogReader);
};
● In Javascript:
var x = new DatePicker(); // DatePicker() is a "constructor" function
var y = pageHeight(); // pageHeight() is an ordinary function
● in jQuery:
var $all_images = $("img"); // $all_images is a jQuery object
var height = 250; // height is not
● in HTML:
<div id=”middle_column” class=”main-content”>
6. Use Name Formatting to
Convey Meaning
Ch3. Names That Can’t Be
Misconstrued
● We have focused on how to put a lot of information into our names.
● We will do on a different topic: watching out for names that can be
misunderstood
● Key Idea: Actively scrutinize your names by asking yourself, “What other
meanings could someone interpret from this name?”
● example: filter()
○ results = Database.all_objects.filter("year <= 2011");
○ what does results now contain?
■ Objects whose year is <= 2011?
■ Objects whose year is not <= 2011?
Prefer min/max for (inclusive)
Limits
● CART_TOO_BIG_LIMIT = 10
if shopping_cart.num_items() >= CART_TOO_BIG_LIMIT:
Error("Too many items in cart.")
● MAX_ITEMS_IN_CART = 10
if shopping_cart.num_items() > MAX_ITEMS_IN_CART:
Error("Too many items in cart.")
Prefer first/last for inclusive
Ranges
Prefer begin and end for
inclusive/exclusive Ranges
Naming Booleans
● bool read_password = true;
○ We need to read the password: need_password
○ The password has already been read: user_is_authenticated
● adding words like is, has, can or should can make booleans more clear
○ SpaceLeft() → HasSpaceLeft()
● trying to avoid negated terms in a name
○ disable_ssl = false → use_ssl = true
Matching Expectations of Users
● Example: get*():
○ get: “lightweight accessors”
○ public double getMean() {
//Iterate through all samples and return total/num_samples
}
○ getMean() → computeMean()
● Example: list::size()
○ in C++, list::size() is an O(n) operation
○ size() → conuntSize(), countElements()
Matching Expectations of Users
● Example: Evaluating Multiple Name Candidates
○ experiment_id: 100
description: ‘increase font size to 14pt’
traffic_fraction: 5%
…
○ experient_id: 101
description: ‘increase font size to 13pt’
[other lines are identical to experiment_id 100]
...
○ ‘the_other_experiement_id_I_want_to_reuse: 100’ can be
renamed? If so, how?
● Candidates:
○ template
○ reuse
○ copy
○ inherit
● ‘template’
○ experiment_id: 101
template: 100
○ ‘i am a template’ vs ‘i am using this other template’
○ ‘template’ is generally something abstract that must be filled in
● ‘reuse’
○ ‘This experiment can be reused at most 100 times’
Matching Expectations of Users
● ‘copy’
○ ‘copy this experiment 100 times’ or ‘this is the 100th copy of
something’
● ‘inherit’
○ with inheritance
■ get all features from the inheritee
■ can modify inherited features
■ can add more own features
○ inherit_from_experiment_id might be the best
Matching Expectations of Users
Ch4. Aesthetics
● How good use of spacing, alignment, and ordering can make your code
easier to read
● 3 principles:
1. Use consistent layout
2. Make similar code look similar
3. Group related lines of code into blocks
Rearrange Line Breaks to be
Consistent and Compact
Rearrange Line Breaks to be
Consistent and Compact
Use Methods to Clean up
Irregularity
Use Methods to Clean up
Irregularity
Use Column Alignment When
Helpful
Pick a Meaningful Order, and Use
It Consistently
● details = request.POST.get('details')
location = request.POST.get('location')
phone = request.POST.get('phone')
email = request.POST.get('email')
url = request.POST.get('url')
● some meaningful orders:
○ the order of the <input> field on the corresponding HTML form
○ from ‘most important’ to ‘least important’
○ alphabetically
Organize Declarations into Blocks
class FrontendServer {
public:
FrontendServer();
void ViewProfile(HttpRequest* request);
void OpenDatabase(string location, string user);
void SaveProfile(HttpRequest* request);
string ExtractQueryParam(HttpRequest* request,
string param);
void ReplyOK(HttpRequest* request, string html);
void FindFriends(HttpRequest* request);
void ReplyNotFound(HttpRequest* request, string
error);
void CloseDatabase(string location);
~FrontendServer();
};
class FrontendServer {
public:
FrontendServer();
~FrontendServer();
// Handlers
void ViewProfile(HttpRequest* request);
void SaveProfile(HttpRequest* request);
void FindFriends(HttpRequest* request);
// Request/Reply Utilities
string ExtractQueryParam(HttpRequest* request, string
param);
void ReplyOK(HttpRequest* request, string html);
void ReplyNotFound(HttpRequest* request, string
error);
// Database Helpers
void OpenDatabase(string location, string user);
void CloseDatabase(string location);
def suggest_new_friends(user, email_password):
friends = user.friends()
friend_emails = set(f.email for f in friends)
contacts = import_contacts(user.email, email_password)
contact_emails = set(c.email for c in contacts)
non_friend_emails = contact_emails - friend_emails
suggested_friends = User.objects.select
(email__in=non_friend_emails)
display['user'] = user
display['friends'] = friends
display['suggested_friends'] = suggested_friends
return render("suggested_friends.html", display)
Break Code into Paragraphs
def suggest_new_friends(user, email_password):
# Get the user's friends' email addresses.
friends = user.friends()
friend_emails = set(f.email for f in friends)
# Import all email addresses from this user's email account.
contacts = import_contacts(user.email, email_password)
contact_emails = set(c.email for c in contacts)
# Find matching users that they aren't already friends with.
non_friend_emails = contact_emails - friend_emails
suggested_friends = User.objects.select(email__in=non_friend_emails)
# Display these lists on the page.
display['user'] = user
display['friends'] = friends
display['suggested_friends'] = suggested_friends
return render("suggested_friends.html", display)
Key Idea: Consistent style is more important than the
“right” style.
Personal Style vs. Consistency
Summary
● Ch2. Packing Information into your names
○ Use specific words
○ Avoid generic names
○ Use concrete names
○ Attach important details
○ Use longer names for larger scopes
○ Use capitalization, underscores, and so on in a meaningful way
● Ch3. Names That Can’t be Misconstrued
○ Use ‘max_/min_’ for an upper or lower limit for a value
○ Use ‘first/last’ for inclusive ranges
○ Use ‘begin/end’ for inclusive/exclusive ranges
○ Use words like is and has to make boolean variables clear
○ Avoid negated terms
Summary
● Ch4. Aesthetics
○ Try to give similar codes the similar silhouette
○ Align parts of the code into columns
○ Pick a meaningful order and stick with it
○ Break apart large blocks into logical paragraphs
Q&A
Any Questions?

More Related Content

What's hot

Mongodb 특징 분석
Mongodb 특징 분석Mongodb 특징 분석
Mongodb 특징 분석
Daeyong Shin
 
月間10億pvを支えるmongo db
月間10億pvを支えるmongo db月間10億pvを支えるmongo db
月間10億pvを支えるmongo db
Yuji Isobe
 
凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public
bonjin6770 Kurosawa
 

What's hot (20)

gRPC入門
gRPC入門gRPC入門
gRPC入門
 
Json in Postgres - the Roadmap
 Json in Postgres - the Roadmap Json in Postgres - the Roadmap
Json in Postgres - the Roadmap
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
Deep dark-side of git: How git works internally
Deep dark-side of git: How git works internallyDeep dark-side of git: How git works internally
Deep dark-side of git: How git works internally
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報
 
SQLite の暗号化
SQLite の暗号化SQLite の暗号化
SQLite の暗号化
 
Mongodb 특징 분석
Mongodb 특징 분석Mongodb 특징 분석
Mongodb 특징 분석
 
안정적인 서비스 운영 2014.03
안정적인 서비스 운영   2014.03안정적인 서비스 운영   2014.03
안정적인 서비스 운영 2014.03
 
rpm package 를 이용한 MySQL 설치자동화
rpm package 를 이용한 MySQL 설치자동화rpm package 를 이용한 MySQL 설치자동화
rpm package 를 이용한 MySQL 설치자동화
 
Alpine linuxを触ってみよう
Alpine linuxを触ってみようAlpine linuxを触ってみよう
Alpine linuxを触ってみよう
 
MariaDBとMroongaで作る全言語対応超高速全文検索システム
MariaDBとMroongaで作る全言語対応超高速全文検索システムMariaDBとMroongaで作る全言語対応超高速全文検索システム
MariaDBとMroongaで作る全言語対応超高速全文検索システム
 
SPARQLを利用した逆マッシュアップ-プログラミングを必要としないアプリ作成方法-
SPARQLを利用した逆マッシュアップ-プログラミングを必要としないアプリ作成方法-SPARQLを利用した逆マッシュアップ-プログラミングを必要としないアプリ作成方法-
SPARQLを利用した逆マッシュアップ-プログラミングを必要としないアプリ作成方法-
 
データベース12 - トランザクションと同時実行制御
データベース12 - トランザクションと同時実行制御データベース12 - トランザクションと同時実行制御
データベース12 - トランザクションと同時実行制御
 
120901fp key
120901fp key120901fp key
120901fp key
 
月間10億pvを支えるmongo db
月間10億pvを支えるmongo db月間10億pvを支えるmongo db
月間10億pvを支えるmongo db
 
AndroidとPCのみでスマート電球BLEハッキング
AndroidとPCのみでスマート電球BLEハッキングAndroidとPCのみでスマート電球BLEハッキング
AndroidとPCのみでスマート電球BLEハッキング
 
凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public
 
MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較MySQLとPostgreSQLの基本的な実行プラン比較
MySQLとPostgreSQLの基本的な実行プラン比較
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
오픈소스 개발을 위한 Git 사용법 실습
오픈소스 개발을 위한 Git 사용법 실습오픈소스 개발을 위한 Git 사용법 실습
오픈소스 개발을 위한 Git 사용법 실습
 

Similar to The art of readable code (ch1~ch4)

Stop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principlesStop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principles
Edorian
 
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptxINTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
DeepasCSE
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
cobyst
 
Clean code: meaningful Name
Clean code: meaningful NameClean code: meaningful Name
Clean code: meaningful Name
nahid035
 
Extreme Interview Questions
Extreme Interview QuestionsExtreme Interview Questions
Extreme Interview Questions
Ehtisham Ali
 

Similar to The art of readable code (ch1~ch4) (20)

Python for web security - beginner
Python for web security - beginnerPython for web security - beginner
Python for web security - beginner
 
Writing Readable Code
Writing Readable CodeWriting Readable Code
Writing Readable Code
 
C# coding standards, good programming principles & refactoring
C# coding standards, good programming principles & refactoringC# coding standards, good programming principles & refactoring
C# coding standards, good programming principles & refactoring
 
Stop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principlesStop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principles
 
Object Calisthenics in Objective-C
Object Calisthenics in Objective-CObject Calisthenics in Objective-C
Object Calisthenics in Objective-C
 
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptxINTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
 
What's in a name
What's in a nameWhat's in a name
What's in a name
 
Keep your repo clean
Keep your repo cleanKeep your repo clean
Keep your repo clean
 
Clean Code
Clean CodeClean Code
Clean Code
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLEAN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE
 
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE - CFObjective() 2017
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE - CFObjective() 2017AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE - CFObjective() 2017
AN EXERCISE IN CLEANER CODE - FROM LEGACY TO MAINTAINABLE - CFObjective() 2017
 
How MySQL can boost (or kill) your application v2
How MySQL can boost (or kill) your application v2How MySQL can boost (or kill) your application v2
How MySQL can boost (or kill) your application v2
 
Clean Code
Clean CodeClean Code
Clean Code
 
Unit testing in PHP
Unit testing in PHPUnit testing in PHP
Unit testing in PHP
 
Clean code: meaningful Name
Clean code: meaningful NameClean code: meaningful Name
Clean code: meaningful Name
 
C++primer
C++primerC++primer
C++primer
 
Extreme Interview Questions
Extreme Interview QuestionsExtreme Interview Questions
Extreme Interview Questions
 
Object Oriented Programming
Object Oriented ProgrammingObject Oriented Programming
Object Oriented Programming
 
Naming Standards, Clean Code
Naming Standards, Clean CodeNaming Standards, Clean Code
Naming Standards, Clean Code
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Recently uploaded (20)

Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Vancouver Psychic Readings, Attraction spells,Br...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 

The art of readable code (ch1~ch4)

  • 1. The Art of Readable Code (Ch1~Ch4) Jonghan Seo
  • 2. Ch1. Code Should Be Easy to Understand ● collected bunch of examples of “bad code” ● analyzed what made them bad ● found principles/techniques that can be used to make them better ● Key Idea: Code should be easy to understand
  • 3. What Makes Code “Better”? ● sometimes it is fairly obvious
  • 4. What Makes Code “Better”? ● sometimes it is vague more compact !!! less intimidating !!!
  • 5. The Fundamental Theorem of Readability ● Code should be written to minimize the time it would take for someone else to understand ● to fully understand your code: ○ be able to make changes to it ○ be able to spot bugs ○ be able to understand how it interacts with the rest of your code ● ‘someone else’ would be you
  • 6. Some Different Views ● The Smaller The Better? ○ It probably takes less time to understand fewer lines BUT it is not always better! ○ the time-till-understanding is an even better goal ● What about other constraints? ○ code efficiency? well architectured? easy to test? … ○ making code easy to understand often leads to meet the other rules ● the rest of this book discusses how to apply ‘easy to read’ in different circumstances
  • 7. ● There are four parts: ○ Part One: Surface-Level Improvements ○ Part Two: Simplifying Loops and Logic ○ Part Three: Reorganizing Your Code ○ Part Four: Selected Topics ● Surface-Level Improvements ○ picking good names ○ writing good comments ○ formatting your code neatly Contents
  • 8. Ch2. Packing Information into Names ● Key Idea: Pack information into your names ● Six Specific Topics 1. Choosing specific words 2. Avoiding generic names (or knowing when to use them) 3. Using concrete names instead of abstract names 4. Attaching extra information to a name, by using a suffix or prefix 5. Deciding how long a name should be 6. Using name formatting to pack extra information
  • 9. 1. Choose Specific Words ● def GetPage(url): … ○ from a local cache? from a database? from the Internet? ○ FetchPage(), DownloadPage() ● class BinaryTree { int size(); ... } ○ height of the tree? the number of codes? memory footprint of the tree? ○ Height(), NumNodes(), MemoryBytes()
  • 11. 2. Avoid Generic Names ● ‘tmp’, ‘retval’, loop iterators ● retval ○ var euclidean_norm = function (v) { var retval = 0.0; for (var i = 0 ; i < v.length; i += 1) retval += v[i] * v[i]; return Math.sqrt(retval); }; ○ reval → sum_squares ○ sum_squares += v[i]; → spot a bug!! ○ Advice: Use a name that describes the variable’s value
  • 12. 2. Avoid Generic Names ● tmp ○ if (right < left) { tmp = right; right = left; left = tmp; } // it is ok! ○ String tmp = user.name(); tmp += “ “ + user.phone_number(); … template.set(“user_info”, tmp); // tmp → user_info ● Advice: ‘tmp’ should be used in cases when (1) being short-lived and (2) temporary is the most important fact about the variable
  • 13. 2. Avoid Generic Names ● Loop Iterators ○ for (int i = 0; i < clubs.size(); i++) for (int j = 0; j < clubs[i].members.size(); j++) for (int k = 0; k < users.size(); k++) if (clubs[i].members[k] == users[j]) cout << "user[" << j << "] is in club[" << i << "]" << endl; ○ (i, j, k) → (club_i, memeber_i, users_i) or (ci, mi, ui) ○ if (clubs[ci].members[ui] == users[mi]) // Bug! First letters don't match up.
  • 14. 3. Prefer Concrete Names Over Abstract Names ● Example1) Google Code Guide for C++ ○ #define DISALLOW_EVIL_CONSTRUCTORS(ClassName) ClassName(const ClassName&); void operator=(const ClassName&); class ClassName { private: DISALLOW_EVIL_CONSTRUCTORS(ClassName); }; ○ ‘evil’ sounds too strong and more important, it isn’t clear what the macro is disallowing ○ DISALLOW_COPY_AND_ASSIGN
  • 15. 3. Prefer Concrete Names Over Abstract Names ● Example2) --run_locally ○ --run_locally ■ printing debugging information ■ used when testing on a local machine ○ What if we need... ■ to print debugging information while the program run remotely? ■ to run a performance test locally (so we do not want the logging slowing it down)? ○ --run_locally → --extra_logging
  • 16. 4. Attaching Extra Information to a Name ● string id; //Example: “af84ef845cd8” → string hex_id;
  • 17. 5. How Long Should a Name be? ● the implicit constraint: ‘the name shouldn’t be too long’ ○ the longer a name, the harder it is to remember and the more space it consumes on the screen ○ However, if we take the constraint too far it also would make someone else difficult to understand the code
  • 18. ● There are some guidelines: ○ Shorter names are all right for shorter scope ○ Typing Long Names - Not a Problem Anymore ■ if ‘they’re harder to type’ mattered ■ Make full use of ‘word completion’ built in editors ○ Acronyms and Abbreviations ■ project-specific abbreviations: Bad Idea ■ common to programmers: OK! ● evaluation → eval, document → doc, string → str ○ Throwing out Unneeded Words ■ ConvertToString() → ToString() ■ DoServerLoop() → ServerLoop() 5. How Long Should a Name be?
  • 19. 6. Use Name Formatting to Convey Meaning ● In C++: static const int kMaxOpenFiles = 100; class LogReader { public: void OpenFile(string local_file); private: int offset_; DISALLOW_COPY_AND_ASSIGN(LogReader); };
  • 20. ● In Javascript: var x = new DatePicker(); // DatePicker() is a "constructor" function var y = pageHeight(); // pageHeight() is an ordinary function ● in jQuery: var $all_images = $("img"); // $all_images is a jQuery object var height = 250; // height is not ● in HTML: <div id=”middle_column” class=”main-content”> 6. Use Name Formatting to Convey Meaning
  • 21. Ch3. Names That Can’t Be Misconstrued ● We have focused on how to put a lot of information into our names. ● We will do on a different topic: watching out for names that can be misunderstood ● Key Idea: Actively scrutinize your names by asking yourself, “What other meanings could someone interpret from this name?” ● example: filter() ○ results = Database.all_objects.filter("year <= 2011"); ○ what does results now contain? ■ Objects whose year is <= 2011? ■ Objects whose year is not <= 2011?
  • 22. Prefer min/max for (inclusive) Limits ● CART_TOO_BIG_LIMIT = 10 if shopping_cart.num_items() >= CART_TOO_BIG_LIMIT: Error("Too many items in cart.") ● MAX_ITEMS_IN_CART = 10 if shopping_cart.num_items() > MAX_ITEMS_IN_CART: Error("Too many items in cart.")
  • 23. Prefer first/last for inclusive Ranges
  • 24. Prefer begin and end for inclusive/exclusive Ranges
  • 25. Naming Booleans ● bool read_password = true; ○ We need to read the password: need_password ○ The password has already been read: user_is_authenticated ● adding words like is, has, can or should can make booleans more clear ○ SpaceLeft() → HasSpaceLeft() ● trying to avoid negated terms in a name ○ disable_ssl = false → use_ssl = true
  • 26. Matching Expectations of Users ● Example: get*(): ○ get: “lightweight accessors” ○ public double getMean() { //Iterate through all samples and return total/num_samples } ○ getMean() → computeMean() ● Example: list::size() ○ in C++, list::size() is an O(n) operation ○ size() → conuntSize(), countElements()
  • 27. Matching Expectations of Users ● Example: Evaluating Multiple Name Candidates ○ experiment_id: 100 description: ‘increase font size to 14pt’ traffic_fraction: 5% … ○ experient_id: 101 description: ‘increase font size to 13pt’ [other lines are identical to experiment_id 100] ... ○ ‘the_other_experiement_id_I_want_to_reuse: 100’ can be renamed? If so, how?
  • 28. ● Candidates: ○ template ○ reuse ○ copy ○ inherit ● ‘template’ ○ experiment_id: 101 template: 100 ○ ‘i am a template’ vs ‘i am using this other template’ ○ ‘template’ is generally something abstract that must be filled in ● ‘reuse’ ○ ‘This experiment can be reused at most 100 times’ Matching Expectations of Users
  • 29. ● ‘copy’ ○ ‘copy this experiment 100 times’ or ‘this is the 100th copy of something’ ● ‘inherit’ ○ with inheritance ■ get all features from the inheritee ■ can modify inherited features ■ can add more own features ○ inherit_from_experiment_id might be the best Matching Expectations of Users
  • 30. Ch4. Aesthetics ● How good use of spacing, alignment, and ordering can make your code easier to read ● 3 principles: 1. Use consistent layout 2. Make similar code look similar 3. Group related lines of code into blocks
  • 31. Rearrange Line Breaks to be Consistent and Compact
  • 32. Rearrange Line Breaks to be Consistent and Compact
  • 33. Use Methods to Clean up Irregularity
  • 34. Use Methods to Clean up Irregularity
  • 35. Use Column Alignment When Helpful
  • 36. Pick a Meaningful Order, and Use It Consistently ● details = request.POST.get('details') location = request.POST.get('location') phone = request.POST.get('phone') email = request.POST.get('email') url = request.POST.get('url') ● some meaningful orders: ○ the order of the <input> field on the corresponding HTML form ○ from ‘most important’ to ‘least important’ ○ alphabetically
  • 37. Organize Declarations into Blocks class FrontendServer { public: FrontendServer(); void ViewProfile(HttpRequest* request); void OpenDatabase(string location, string user); void SaveProfile(HttpRequest* request); string ExtractQueryParam(HttpRequest* request, string param); void ReplyOK(HttpRequest* request, string html); void FindFriends(HttpRequest* request); void ReplyNotFound(HttpRequest* request, string error); void CloseDatabase(string location); ~FrontendServer(); }; class FrontendServer { public: FrontendServer(); ~FrontendServer(); // Handlers void ViewProfile(HttpRequest* request); void SaveProfile(HttpRequest* request); void FindFriends(HttpRequest* request); // Request/Reply Utilities string ExtractQueryParam(HttpRequest* request, string param); void ReplyOK(HttpRequest* request, string html); void ReplyNotFound(HttpRequest* request, string error); // Database Helpers void OpenDatabase(string location, string user); void CloseDatabase(string location);
  • 38. def suggest_new_friends(user, email_password): friends = user.friends() friend_emails = set(f.email for f in friends) contacts = import_contacts(user.email, email_password) contact_emails = set(c.email for c in contacts) non_friend_emails = contact_emails - friend_emails suggested_friends = User.objects.select (email__in=non_friend_emails) display['user'] = user display['friends'] = friends display['suggested_friends'] = suggested_friends return render("suggested_friends.html", display) Break Code into Paragraphs def suggest_new_friends(user, email_password): # Get the user's friends' email addresses. friends = user.friends() friend_emails = set(f.email for f in friends) # Import all email addresses from this user's email account. contacts = import_contacts(user.email, email_password) contact_emails = set(c.email for c in contacts) # Find matching users that they aren't already friends with. non_friend_emails = contact_emails - friend_emails suggested_friends = User.objects.select(email__in=non_friend_emails) # Display these lists on the page. display['user'] = user display['friends'] = friends display['suggested_friends'] = suggested_friends return render("suggested_friends.html", display)
  • 39. Key Idea: Consistent style is more important than the “right” style. Personal Style vs. Consistency
  • 40. Summary ● Ch2. Packing Information into your names ○ Use specific words ○ Avoid generic names ○ Use concrete names ○ Attach important details ○ Use longer names for larger scopes ○ Use capitalization, underscores, and so on in a meaningful way ● Ch3. Names That Can’t be Misconstrued ○ Use ‘max_/min_’ for an upper or lower limit for a value ○ Use ‘first/last’ for inclusive ranges ○ Use ‘begin/end’ for inclusive/exclusive ranges ○ Use words like is and has to make boolean variables clear ○ Avoid negated terms
  • 41. Summary ● Ch4. Aesthetics ○ Try to give similar codes the similar silhouette ○ Align parts of the code into columns ○ Pick a meaningful order and stick with it ○ Break apart large blocks into logical paragraphs