SlideShare a Scribd company logo
1 of 66
The Art of
Readable Code

                 pedro@morais.it
                   @pedromorais
                morais on app.net
Dustin Boswell
Trevor Foucher

      O’Reilly
     Nov 2011
code should be easy
   to understand
10
ideas
1. Pack information
  into your names
be specific


 X GetPage
 ✓ DownloadPage
avoid generic names


       X tmp
       X retval
var euclidean_norm = function (v) {
   var retval = 0.0;
   for (var i = 0; i < v.length; i += 1)
      retval += v[i] * v[i];
                                           X
   return Math.sqrt(retval);
};



var euclidean_norm = function (v) {
   var sum_squares = 0.0;
   for (var i = 0; i < v.length; i += 1)
      sum_squares += v[i] * v[i];
   return Math.sqrt(sum_squares);
                                           ✓
};
attach details

 X duration
 ✓ duration_ms

 X password
 ✓ plaintext_password
careful with
abbreviations

   X BEManager

   ✓ str
   ✓ eval
avoid ambiguous
     naming
X
.filter(“year <= 2000”)
CART_TOO_BIG_LIMIT = 10
STOP = 10                 X
CART_MAX_ITEMS = 10
LAST = 10                 ✓
read_password = True
                         X
                         ✓
needs_to_read_password
password_has_been_read
2. Aesthetics matter
be consistent
write code like text
# Import the user's email contacts,
# and match them to users in our system.
# Then display a list of those users that
                                                           X
# he/she isn't already friends with.
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)
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)
3. Comment wisely
// The class definition of Account



                          X
class Account {
! public:
! ! // Constructor
! ! Account();
! ! // Set the profit member
! ! void SetProfit(double profit);
! ! // Returns the profit
! ! double GetProfit();
};
✓
# remove everything after the second '*'
name = '*'.join(line.split('*')[:2])
fix bad names,
don’t explain them
X
// Enforce limits on the Reply as stated in the Request,
// such as the number of items returned, or total byte
// size, etc.
void CleanReply(Request request, Reply reply);
X
// Make sure 'reply' meets the count/byte/etc.
// limits from the 'request'
void EnforceRequestLimits(Request request, Reply reply);
include “director’s
   commentary”
//   Surprisingly, a binary tree was 40% faster
//   than a hash table for this data.
//   The cost of computing a hash was more
//   than the left/right comparisons.


// This heuristic might miss a few words.
// That's OK; solving this 100% is hard.
comment code flaws

       TODO
       FIXME
       HACK
        XXX
make comments
   compact
4. Make your control
 flow easy to follow
write expressions like
     you’d say it
 if (length > 10)
 while (bytes_received < bytes_expected)
                                           ✓
                                           X
 if (10 <= length)
 while (bytes_expected > bytes_received)
if/else ordering

if (a == b) {         if (a != b) {
    // Case One ...       // Case Two ...
} else {              } else {
    // Case Two ...       // Case One ...
}                     }
deal with positive first

                      ✓
if (debug) {
    // Case One ...
} else {
    // Case Two ...
}
deal with simpler first
if (!file) {



                          ✓
    // Log an error
} else {
   // Actually do stuff
   // ...
   // ...
   // ...
}
deal with interesting first
 if (url.HasQueryParameter("expand_all"))) {



                                               ✓
    // Interesting code
    // ...
    // ...
    // ...
 } else {
    // “Easy” case
 }
avoid
do...while
  loops
return early

public boolean Contains(String str, String substr) {
   if (str == null || substr == null) return false;
   if (substr.equals("")) return true;



                                                ✓
   ...
}
minimize nesting
if (user_result == SUCCESS) {
  if (permission_result != SUCCESS) {
    reply.WriteErrors("error reading permissions");
    reply.Done();
    return;
  }
  reply.WriteErrors("");
} else {
  reply.WriteErrors(user_result);



                                               X
}
reply.Done();
5. Break down giant
    expressions
explain with vars

if line.split(':')[0].strip() == "root":
   ...                                     X
                                           ✓
username = line.split(':')[0].strip()
if username == "root":
   ...
summarize with vars

if (request.user.id == document.owner_id) {
    // user can edit this document...
                             if (request.user.id != document.owner_id) { // document is read-only...
                             }


}
...
if (request.user.id != document.owner_id) {
  // document is read-only...
}


                                                                               X
summarize with vars
final boolean user_owns_document =
     (request.user.id == document.owner_id);

if (user_owns_document) {
    // user can edit this document...
}



                                        ✓
...
if (!user_owns_document) {
    // document is read-only...
}
use De Morgan’s laws
if (!(file_exists && !is_protected))
   Error("Sorry, could not read file.");
                                           X
                                           ✓
if (!file_exists || is_protected)
   Error("Sorry, could not read file.");
6. Tame your
  variables
X
  many variables
   broad scope
changing frequently
remove unnecessary vars
now = datetime.datetime.now()
root_message.last_view_time = now
                                              X
root_message.last_view_time = datetime.datetime.now()




                                              ✓
make your variable
visible by as few lines
 of code as possible
prefer write-once
    variables
7. Extract unrelated
    subproblems
factor out
 lines that are working
towards a subproblem
separate the
generic code from the
project- specific code
create a lot of
general-purpose code
8. Do one thing at a
       time
1.
figure out what tasks
 your code is doing
2.
separate those tasks into
  functions or sections
X
void UpdateCounts(HttpDownload hd) {
   // Figure out the Exit State, if available.
   if (!hd.has_event_log() || !hd.event_log().has_exit_state()) {
      counts["Exit State"]["unknown"]++;
   } else {
      string state_str = ExitStateTypeName(hd.event_log().exit_state());
      counts["Exit State"][state_str]++;
   }

    // If there are no HTTP headers at all, use "unknown" for the remaining elements.
    if (!hd.has_http_headers()) {
       counts["Http Response"]["unknown"]++;
       counts["Content-Type"]["unknown"]++;
       return;
    }

    HttpHeaders headers = hd.http_headers();

    // Log the HTTP response, if known, otherwise log "unknown"
    if (!headers.has_response_code()) {
       counts["Http Response"]["unknown"]++;
    } else {
       string code = StringPrintf("%d", headers.response_code());
       counts["Http Response"][code]++;
    }

    // Log the Content-Type if known, otherwise log "unknown"
    if (!headers.has_content_type()) {
       counts["Content-Type"]["unknown"]++;
    } else {
       string content_type = ContentTypeMime(headers.content_type());
       counts["Content-Type"][content_type]++;
    }
}
void UpdateCounts(HttpDownload hd) {
   // Task: define default values for each of the values we want to extract
   string exit_state = "unknown";
   string http_response = "unknown";
   string content_type = "unknown";

    // Task: try to extract each value from HttpDownload, one by one
    if (hd.has_event_log() && hd.event_log().has_exit_state()) {
       exit_state = ExitStateTypeName(hd.event_log().exit_state());
    }
    if (hd.has_http_headers() && hd.http_headers().has_response_code()) {
       http_response = StringPrintf("%d", hd.http_headers().response_code());
    }
    if (hd.has_http_headers() && hd.http_headers().has_content_type()) {
       content_type = ContentTypeMime(hd.http_headers().content_type());
    }




                                                                ✓
    // Task: update counts[]
    counts["Exit State"][exit_state]++;
    counts["Http Response"][http_response]++;
    counts["Content-Type"][content_type]++;
}
9. Don’t write it
question your
requirements
don’t over engineer
be familiar with
 your libraries
10. Break the rules
10. Break the rules
  when you have a
good reason to do it
code should be easy
   to understand
Thanks!



           pedro@morais.it
             @pedromorais
          morais on app.net

More Related Content

Featured

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Featured (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

The Art of Readable Code

  • 1. The Art of Readable Code pedro@morais.it @pedromorais morais on app.net
  • 2. Dustin Boswell Trevor Foucher O’Reilly Nov 2011
  • 3. code should be easy to understand
  • 5. 1. Pack information into your names
  • 6. be specific X GetPage ✓ DownloadPage
  • 7. avoid generic names X tmp X retval
  • 8. var euclidean_norm = function (v) { var retval = 0.0; for (var i = 0; i < v.length; i += 1) retval += v[i] * v[i]; X return Math.sqrt(retval); }; var euclidean_norm = function (v) { var sum_squares = 0.0; for (var i = 0; i < v.length; i += 1) sum_squares += v[i] * v[i]; return Math.sqrt(sum_squares); ✓ };
  • 9. attach details X duration ✓ duration_ms X password ✓ plaintext_password
  • 10. careful with abbreviations X BEManager ✓ str ✓ eval
  • 11. avoid ambiguous naming
  • 13. CART_TOO_BIG_LIMIT = 10 STOP = 10 X CART_MAX_ITEMS = 10 LAST = 10 ✓
  • 14. read_password = True X ✓ needs_to_read_password password_has_been_read
  • 16.
  • 19. # Import the user's email contacts, # and match them to users in our system. # Then display a list of those users that X # he/she isn't already friends with. 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)
  • 20. 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)
  • 22. // The class definition of Account X class Account { ! public: ! ! // Constructor ! ! Account(); ! ! // Set the profit member ! ! void SetProfit(double profit); ! ! // Returns the profit ! ! double GetProfit(); };
  • 23. ✓ # remove everything after the second '*' name = '*'.join(line.split('*')[:2])
  • 24. fix bad names, don’t explain them
  • 25. X // Enforce limits on the Reply as stated in the Request, // such as the number of items returned, or total byte // size, etc. void CleanReply(Request request, Reply reply);
  • 26. X // Make sure 'reply' meets the count/byte/etc. // limits from the 'request' void EnforceRequestLimits(Request request, Reply reply);
  • 27. include “director’s commentary” // Surprisingly, a binary tree was 40% faster // than a hash table for this data. // The cost of computing a hash was more // than the left/right comparisons. // This heuristic might miss a few words. // That's OK; solving this 100% is hard.
  • 28. comment code flaws TODO FIXME HACK XXX
  • 29. make comments compact
  • 30. 4. Make your control flow easy to follow
  • 31. write expressions like you’d say it if (length > 10) while (bytes_received < bytes_expected) ✓ X if (10 <= length) while (bytes_expected > bytes_received)
  • 32. if/else ordering if (a == b) { if (a != b) { // Case One ... // Case Two ... } else { } else { // Case Two ... // Case One ... } }
  • 33. deal with positive first ✓ if (debug) { // Case One ... } else { // Case Two ... }
  • 34. deal with simpler first if (!file) { ✓ // Log an error } else { // Actually do stuff // ... // ... // ... }
  • 35. deal with interesting first if (url.HasQueryParameter("expand_all"))) { ✓ // Interesting code // ... // ... // ... } else { // “Easy” case }
  • 37. return early public boolean Contains(String str, String substr) { if (str == null || substr == null) return false; if (substr.equals("")) return true; ✓ ... }
  • 38. minimize nesting if (user_result == SUCCESS) { if (permission_result != SUCCESS) { reply.WriteErrors("error reading permissions"); reply.Done(); return; } reply.WriteErrors(""); } else { reply.WriteErrors(user_result); X } reply.Done();
  • 39. 5. Break down giant expressions
  • 40. explain with vars if line.split(':')[0].strip() == "root": ... X ✓ username = line.split(':')[0].strip() if username == "root": ...
  • 41. summarize with vars if (request.user.id == document.owner_id) { // user can edit this document... if (request.user.id != document.owner_id) { // document is read-only... } } ... if (request.user.id != document.owner_id) { // document is read-only... } X
  • 42. summarize with vars final boolean user_owns_document = (request.user.id == document.owner_id); if (user_owns_document) { // user can edit this document... } ✓ ... if (!user_owns_document) { // document is read-only... }
  • 43. use De Morgan’s laws if (!(file_exists && !is_protected)) Error("Sorry, could not read file."); X ✓ if (!file_exists || is_protected) Error("Sorry, could not read file.");
  • 44. 6. Tame your variables
  • 45. X many variables broad scope changing frequently
  • 46. remove unnecessary vars now = datetime.datetime.now() root_message.last_view_time = now X root_message.last_view_time = datetime.datetime.now() ✓
  • 47. make your variable visible by as few lines of code as possible
  • 48. prefer write-once variables
  • 49. 7. Extract unrelated subproblems
  • 50. factor out lines that are working towards a subproblem
  • 51. separate the generic code from the project- specific code
  • 52. create a lot of general-purpose code
  • 53. 8. Do one thing at a time
  • 54. 1. figure out what tasks your code is doing
  • 55. 2. separate those tasks into functions or sections
  • 56.
  • 57. X void UpdateCounts(HttpDownload hd) { // Figure out the Exit State, if available. if (!hd.has_event_log() || !hd.event_log().has_exit_state()) { counts["Exit State"]["unknown"]++; } else { string state_str = ExitStateTypeName(hd.event_log().exit_state()); counts["Exit State"][state_str]++; } // If there are no HTTP headers at all, use "unknown" for the remaining elements. if (!hd.has_http_headers()) { counts["Http Response"]["unknown"]++; counts["Content-Type"]["unknown"]++; return; } HttpHeaders headers = hd.http_headers(); // Log the HTTP response, if known, otherwise log "unknown" if (!headers.has_response_code()) { counts["Http Response"]["unknown"]++; } else { string code = StringPrintf("%d", headers.response_code()); counts["Http Response"][code]++; } // Log the Content-Type if known, otherwise log "unknown" if (!headers.has_content_type()) { counts["Content-Type"]["unknown"]++; } else { string content_type = ContentTypeMime(headers.content_type()); counts["Content-Type"][content_type]++; } }
  • 58. void UpdateCounts(HttpDownload hd) { // Task: define default values for each of the values we want to extract string exit_state = "unknown"; string http_response = "unknown"; string content_type = "unknown"; // Task: try to extract each value from HttpDownload, one by one if (hd.has_event_log() && hd.event_log().has_exit_state()) { exit_state = ExitStateTypeName(hd.event_log().exit_state()); } if (hd.has_http_headers() && hd.http_headers().has_response_code()) { http_response = StringPrintf("%d", hd.http_headers().response_code()); } if (hd.has_http_headers() && hd.http_headers().has_content_type()) { content_type = ContentTypeMime(hd.http_headers().content_type()); } ✓ // Task: update counts[] counts["Exit State"][exit_state]++; counts["Http Response"][http_response]++; counts["Content-Type"][content_type]++; }
  • 62. be familiar with your libraries
  • 63. 10. Break the rules
  • 64. 10. Break the rules when you have a good reason to do it
  • 65. code should be easy to understand
  • 66. Thanks! pedro@morais.it @pedromorais morais on app.net

Editor's Notes

  1. \n
  2. This book was released a year ago by O&amp;#x2019;Reilly - go buy it with a discount now at the stand.\nI&amp;#x2019;ve read it, and I&amp;#x2019;ve mostly agreed with the guys.\nIf you enjoy this talk, the book is far better, so read it.\n
  3. The central concept of the book.\nhave you asked &amp;#x201C;Who was the idiot that wrote this code?&amp;#x201D;, and found out it was yourself, 3 months ago\n\nCode should be written to minimize the time it would take for someone else to understand it.\n\n
  4. Today, I&amp;#x2019;ve choosen 10 topics, 10 ideas for the book, I&amp;#x2019;d like to share with you\n
  5. Starting with the basics: naming.\n
  6. \n
  7. Names like tmp, retval, and foo are usually cop-outs that mean &amp;#x201C;I can&amp;#x2019;t think of a name.&amp;#x201D; Instead of using an empty name like this, pick a name that describes the entity&amp;#x2019;s value or purpose.\n\nThe name retval doesn&amp;#x2019;t pack much information. Instead, use a name that describes the variable&amp;#x2019;s value.\n\n
  8. \n
  9. \n
  10. Would a new team member understand it?\n
  11. You need to ask yourself: what other meanings could someone interpret from this name?\nPlay devil&amp;#x2019;s advocate!\n
  12. What does this mean? Include only stuff before 2000? or remove stuff before 2000?.\nWhat if was called &amp;#x201C;includeOnlyIf&amp;#x201D;?\n
  13. What does limit mean? Up to 10? is 10 allowed? MAX is much better.\nPlay devil&amp;#x2019;s advocate!\n
  14. Booleans.\nPlay devil&amp;#x2019;s advocate!\n
  15. \n
  16. Not getting into where you should put your brackets. That&amp;#x2019;s asking for trouble.\n(anyway, the solution is - use Python)\n
  17. Consistent style is more important than the &amp;#x201C;right&amp;#x201D; style.\n\n
  18. Written text is broken into paragraphs for a number of reasons:\nIt&amp;#x2019;s a way to group similar ideas together and set them apart from other ideas. \nIt provides a visual &amp;#x201C;stepping stone&amp;#x201D;&amp;#x2014;without it, it&amp;#x2019;s easy to lose your place on the page. \nIt facilitates navigation from one paragraph to another. \n\n
  19. \n
  20. \n
  21. Comments are meant to help the reader know as much as the writer did.\n
  22. Don&amp;#x2019;t comment on facts that can be quickly derived from the code itself\n
  23. *quickly* derived from the code\n
  24. CleanReply vs. EnforceRequestLimits\n
  25. \n
  26. \n
  27. why is it this way?\nantecipate likely questions\nput yourself in the readers shoes\nbig picture comments\nadvertise pitfalls\n
  28. \n
  29. \n
  30. \n
  31. it&amp;#x2019;s unnatural to say if 18 is less or equal to your age, you say if you&amp;#x2019;re at least 18 year old\n
  32. \n
  33. \n
  34. \n
  35. \n
  36. What&amp;#x2019;s weird about a do/while loop is that a block of code may or may not be reexecuted based on a condition underneath it. Typically, logical conditions are above the code they guard&amp;#x2014;this is the way it works with if, while, and for statements. Because you typically read code from top to bottom, this makes do/while a bit unnatural. Many readers end up reading the code twice.\n\n
  37. One of the motivations for wanting a single exit point is so that all the cleanup code at the bottom of the function is guaranteed to be called. But modern languages offer more sophisticated ways to achieve this guarantee (java&amp;#x2019;s finally, for instance).\n\n
  38. When you see that first closing brace, you have to think to yourself, Oh, permission_result != SUCCESS has just ended, so now permission_result == SUCCESS, and this is still inside the block where user_result == SUCCESS.\n\n
  39. \n
  40. The simplest way to break down an expression is to introduce an extra variable that captures a smaller subexpression. This extra variable is sometimes called an &amp;#x201C;explaining variable&amp;#x201D; because it helps explain what the subexpression means.\n\n
  41. Even if an expression doesn&amp;#x2019;t need explaining (because you can figure out what it means),it can still be useful to capture that expression in a new variable. We call this a summary variable if its purpose is simply to replace a larger chunk of code with a smaller name that can be managed and thought about more easily.\n\n\n
  42. \n
  43. \n
  44. Some guy from Microsoft has talked about how a great interview question should involve at least three variables.\nBut do you want your coworkers to feel like they&amp;#x2019;re in an interview while they&amp;#x2019;re reading your code?\n\n
  45. \n
  46. not breaking now a complex expression\ndoesn&amp;#x2019;t add clarification\nno redundant code removed\n
  47. you know globals? you know you should avoid them. well, apply that to all scopes. if it can be just inside a method, don&amp;#x2019;t make it a class variable\nyou can mark methods as static to let the reader know their scope is reduced\n
  48. a constant is easier to reason with; the closer to a constant your variable is, the easier it is to understand it\n
  49. \n
  50. 1. Look at a given function or block of code, and ask yourself, &amp;#x201C;What is the high-level goal of this code?&amp;#x201D;\n2. For each line of code, ask, &amp;#x201C;Is it working directly to that goal? Or is it solving an unrelated subproblem needed to meet it?&amp;#x201D;\n3. If enough lines are solving an unrelated subproblem, extract that code into a separate function.\n\n
  51. one advantage: it&amp;#x2019;s easier to improve factored out code (for instance, a format_pretty function)\n
  52. General-purpose code is great because it&amp;#x2019;s completely decoupled from the rest of your project. Code like this is easier to develop, easier to test, and easier to understand. If only all of your code could be like this!\n\n
  53. \n
  54. General-purpose code is great because it&amp;#x2019;s completely decoupled from the rest of your project. Code like this is easier to develop, easier to test, and easier to understand. If only all of your code could be like this!\n\n
  55. General-purpose code is great because it&amp;#x2019;s completely decoupled from the rest of your project. Code like this is easier to develop, easier to test, and easier to understand. If only all of your code could be like this!\n\n
  56. You should defrag your code.\n
  57. 1. Using &quot;unknown&quot; as the default value for each key2. Detecting whether members of HttpDownload are missing \n3. Extracting the value and converting it to a string4. Updating counts[]\n\n
  58. not breaking now a complex expression\ndoesn&amp;#x2019;t add clarification\nno redundant code removed\n
  59. \n
  60. store locator; does it need to handle curvature or near north/south pole?\n
  61. just the essential stuff; lots of features go unused and just complicate the code. don&amp;#x2019;t do it just because it&amp;#x2019;s cool\n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n