\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{Marco Santos (marconlsantos)} \pdfinfo{ /Title (pragmatic-programming.pdf) /Creator (Cheatography) /Author (Marco Santos (marconlsantos)) /Subject (Pragmatic Programming Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{A1A1A1} \definecolor{LightBackground}{HTML}{F3F3F3} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Pragmatic Programming Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{Marco Santos (marconlsantos)} via \textcolor{DarkBackground}{\uline{cheatography.com/39521/cs/12272/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}Marco Santos (marconlsantos) \\ \uline{cheatography.com/marconlsantos} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Published 12th September, 2018.\\ Updated 14th February, 2021.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{A Pragmatic Philosophy}} \tn % Row 0 \SetRowColor{LightBackground} Care About Your Craft & Why spend your life developing software unless you care about doing it well? \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} Think! About Your Work & Turn off the autopilot and take control. Constantly critique and appraise your work. \tn % Row Count 9 (+ 5) % Row 2 \SetRowColor{LightBackground} \{\{nobreak\}\}Provide Options, Don't Make Lame Excuses & Instead of excuses, provide options. Don't say it can't be done; explain what can be done to salvage the situation. \tn % Row Count 15 (+ 6) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Software Entropy}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Don't Live with Broken Windows & Don't mess up the carpet when fixing the broken window. \tn % Row Count 3 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{One broken window, left unrepaired for any substantial length of time, instills in the inhabitants of the building a sense of abandonment—a sense that the powers that be don't care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short space of time, the building becomes damaged beyond the owner's desire to fix it, and the sense of abandonment becomes reality.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.1169 cm} x{9.1531 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Stone Soup and Boiled Frogs}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Be a Catalyst for Change & Most software disasters start out too small to notice, and most project overruns happen a day at a time. If you take a frog and drop it into boiling water, it will jump straight back out again. However, if you place the frog in a pan of cold water, then gradually heat it, the frog won't notice the slow increase in temperature and will stay put until cooked. Don't be like the frog. Keep an eye on the big picture. \tn % Row Count 20 (+ 20) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{It's time to bring out the stones. Work out what you can reasonably ask for. Develop it well. Once you've got it, show people, and let them marvel. Then say "of course, it would be better if we added…." \newline \newline People find it easier to join an ongoing success.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Good enough soup}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Make Quality a Requirements Issue & Great software today is often preferable to perfect software tomorrow. Know when to stop. \tn % Row Count 5 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{The scope and quality of the system you produce should be specified as part of that system's requirements.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Your Knowledge Portfolio}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Invest Regularly in Your Knowledge Portfolio & Learn at least one new language every year. Read a technical book each quarter. Read nontechnical books, too. Take classes. Participate in local user groups. Experiment with different environments. Stay current. Get wired. \{\{nl\}\}\{\{nl\}\}An investment in knowledge always pays the best interest. \tn % Row Count 15 (+ 15) % Row 1 \SetRowColor{white} Critically Analyze What You Read and Hear & You need to ensure that the knowledge in your portfolio is accurate and unswayed by either vendor or media hype. \tn % Row Count 21 (+ 6) % Row 2 \SetRowColor{LightBackground} Building Your Portfolio & - Serious investors invest regularly, as a habit\{\{nl\}\}- Diversification is the key to long-term success\{\{nl\}\}- Smart investors balance their portfolios between conservative and high-risk,high-reward investments\{\{nl\}\}- Investors try to buy low and sell high for maximum return\{\{nl\}\}- Portfolios should be reviewed and rebalanced periodically\{\{nl\}\} \tn % Row Count 39 (+ 18) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{6.908 cm} x{10.362 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Communicate!}} \tn % Row 0 \SetRowColor{LightBackground} Know your audience (WISDOM) & What do they {\bf{Want}}?\{\{nl\}\}What is their {\bf{Interest}}?\{\{nl\}\}How {\bf{Sophisticated}} are they?\{\{nl\}\}How much {\bf{Detail}} do they want?\{\{nl\}\}Whom do you want to {\bf{Own}} the information?\{\{nl\}\}How can you {\bf{Motivate}} them to listen? \tn % Row Count 10 (+ 10) % Row 1 \SetRowColor{white} Choose your moment & Understanding when your audience needs to hear your information. \tn % Row Count 13 (+ 3) % Row 2 \SetRowColor{LightBackground} Choose a style & Just the facts, large bound reports, a simple memo. \tn % Row Count 16 (+ 3) % Row 3 \SetRowColor{white} Make it look good & Add good-looking vehicle to your important ideas and engage your audience. \tn % Row Count 20 (+ 4) % Row 4 \SetRowColor{LightBackground} Involve your audience & Get their feedback, and pick their brains. \tn % Row Count 22 (+ 2) % Row 5 \SetRowColor{white} Be a listener & Encourage people to talk by asking questions. \tn % Row Count 24 (+ 2) % Row 6 \SetRowColor{LightBackground} Get back to people & Keep people informed afterwards. \tn % Row Count 26 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Know what you want to say. Plan what you want to say. Write an outline. \newline {\bf{It's Both What You Say and the Way You Say It.}}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{A Pragmatic Approach}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Tips and tricks that apply at all levels of software development, ideas that are almost axiomatic.} \tn % Row Count 2 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.4623 cm} x{8.8077 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{The Evils of Duplication}} \tn % Row 0 \SetRowColor{LightBackground} DRY—Don't Repeat Yourself\{\{nobreak\}\} & The problem arises when you need to change a representation of things that are across all the code base. Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. \tn % Row Count 11 (+ 11) % Row 1 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Make it easy to reuse} \tn % Row Count 12 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{{\bf{Imposed duplication}} Developers feel they have no choice—the environment seems to require duplication. \newline {\bf{Inadvertent duplication}} Developers don't realize that they are duplicating information. \newline {\bf{Impatient duplication}} Developers get lazy and duplicate because it seems easier. \newline {\bf{Interdeveloper duplication}} Multiple people on a team (or on different teams) duplicate a piece of information.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Orthogonality}} \tn % Row 0 \SetRowColor{LightBackground} Eliminate Effects Between Unrelated Things & Two or more things are orthogonal if changes in one do not affect any of the others. Also called cohesion. Write "shy" code. \tn % Row Count 7 (+ 7) % Row 1 \SetRowColor{white} Project Teams & Functionality is divided. \tn % Row Count 9 (+ 2) % Row 2 \SetRowColor{LightBackground} Design & Easier to design a complete project through its components. \tn % Row Count 12 (+ 3) % Row 3 \SetRowColor{white} Toolkits and Libraries & Choose wisely to keep orthogonality. \tn % Row Count 14 (+ 2) % Row 4 \SetRowColor{LightBackground} Testing & Orthogonal systems are easier to test. \tn % Row Count 16 (+ 2) % Row 5 \SetRowColor{white} Documentation & Also gain quality \tn % Row Count 17 (+ 1) % Row 6 \SetRowColor{LightBackground} {\bf{Gain Productivity}} & Changes are localized\{\{nl\}\} Promotes reuse\{\{nl\}\} M x N orthogonal components do more than M x N non orthogonal components \tn % Row Count 24 (+ 7) % Row 7 \SetRowColor{white} {\bf{Reduce Risk}} & Diseased sections or code are isolated\{\{nl\}\} Are better tested\{\{nl\}\} Not tied to a product or platform \tn % Row Count 30 (+ 6) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Orthogonality (cont)}} \tn % Row 8 \SetRowColor{LightBackground} {\bf{Coding: In order to keep orthogonality when adding code do:}} & Keep your code decoupled\{\{nl\}\} Avoid global data\{\{nl\}\} Avoid similar functions \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Reversibility}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{There are no final decisions.} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Tracer Bullets}} \tn % Row 0 \SetRowColor{LightBackground} Use Tracer Bullets to Find the Target & Advantages:\{\{nl\}\}Users get to see something working early \{\{nl\}\}Developers build a structure to work in \{\{nl\}\}You have an integration platform \{\{nl\}\}You have something to demonstrate \{\{nl\}\}You have a better feel for progress \tn % Row Count 12 (+ 12) % Row 1 \SetRowColor{white} Tracer Bullets Don't Always Hit Their Target & Tracer bullets show what you're hitting. This may not always be the target. You then adjust your aim until they're on target. That's the point. \tn % Row Count 20 (+ 8) % Row 2 \SetRowColor{LightBackground} Tracer Code versus Prototyping & With a prototype, you're aiming to explore specific aspects of the final system. Tracer code is used to know how the application as a whole hangs together. \tn % Row Count 28 (+ 8) % Row 3 \SetRowColor{white} \{\{nobreak\}\}Prototyping generates disposable code & Tracer code is lean but complete, and forms part of the skeleton of the final system. \tn % Row Count 33 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{In new projects your users requirements may be vague. Use of new algorithms, techniques, languages, or libraries unknowns will come. And environment will change over time before you are done. \newline We're looking for something that gets us from a requirement to some aspect of the final system quickly, visibly, and repeatably.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.0807 cm} x{10.1893 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Prototypes and Post-it Notes}} \tn % Row 0 \SetRowColor{LightBackground} Things to Prototype & Architecture \{\{nl\}\}New functionality in an existing system \{\{nl\}\}Structure or contents of external data \{\{nl\}\}Third-party tools or components \{\{nl\}\}Performance issues \{\{nl\}\}User interface design \tn % Row Count 9 (+ 9) % Row 1 \SetRowColor{white} What details can you ignore? & Correctness \{\{nl\}\}Completeness \{\{nl\}\}Robustness \{\{nl\}\}Style \tn % Row Count 12 (+ 3) % Row 2 \SetRowColor{LightBackground} Prototyping Architecture: & Are the responsibilities of the major components well defined and appropriate? \{\{nl\}\}Are the collaborations between major components well defined? \{\{nl\}\}Is coupling minimized? \{\{nl\}\}Can you identify potential sources of duplication? \{\{nl\}\}Are interface definitions and constraints acceptable? \{\{nl\}\}Does every module have an access path to the data it needs during execution? \tn % Row Count 29 (+ 17) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{We build software prototypes to analyse and expose risk, and to offer chances for correction at a greatly reduced cost. \newline \newline Prototype anything that carries risk. Anything that hasn't been tried before, or that is absolutely critical to the final system. Anything unproven, experimental, or doubtful. Anything you aren't comfortable with. \newline \newline Prototype to learn, and never deploy the prototype.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Domain Languages}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Program close to the problem domain.} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.4623 cm} x{8.8077 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Estimating}} \tn % Row 0 \SetRowColor{LightBackground} Estimate to Avoid Surprises & {\bf{First:}} Do they need high accuracy, or are they looking for a ballpark figure?\{\{nl\}\}{\bf{Second:}} Scale time estimates properly \tn % Row Count 7 (+ 7) % Row 1 \SetRowColor{white} Where Do Estimates Come From? & Understand What's Being Asked\{\{nl\}\}Build a Model of the System\{\{nl\}\}Break the Model into Components\{\{nl\}\}Give Each Parameter a Value\{\{nl\}\}Calculate the Answers\{\{nl\}\}Keep Track of Your Estimating Prowess \tn % Row Count 18 (+ 11) % Row 2 \SetRowColor{LightBackground} Iterate the Schedule with the Code & Guess estimation\{\{nl\}\}Check requirements\{\{nl\}\}Analyze risk\{\{nl\}\}Design, implement, integrate\{\{nl\}\}Validate with the users\{\{nl\}\}Repeat \tn % Row Count 25 (+ 7) % Row 3 \SetRowColor{white} What to Say When Asked for an Estimate & "I'll get back to you." \tn % Row Count 27 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Quote estimate in \newline \newline 1-15 days - days \newline 3-8 weeks - weeks \newline 8-30 weeks - months \newline 30+ weeks - think hard before giving an estimate} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{The Basic Tools}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Every craftsman starts his or her journey with a basic set of good quality tools.} \tn % Row Count 2 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{5.181 cm} x{12.089 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{The Power of Plain Text}} \tn % Row 0 \SetRowColor{LightBackground} Drawbacks & More space\{\{nl\}\}Computationally more expensive \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} The Power of Text & Insurance against obsolescence\{\{nl\}\}Leverage\{\{nl\}\}Easier testing \tn % Row Count 5 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Keep knowledge in plain text.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Shell Games}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Use the power of command shells.} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Can't you do everything equally well by pointing and clicking in a GUI? {\bf{No}}. A benefit of GUIs is WYSIWYG - what you see is what you get. The disadvantage is WYSIAYG - what you see is all you get.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{4.6629 cm} x{12.6071 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Power Editing}} \tn % Row 0 \SetRowColor{LightBackground} Editor Features & Configurable\{\{nl\}\}Extensible\{\{nl\}\}Programmable\{\{nl\}\}Syntax highlighting\{\{nl\}\}Auto-completion\{\{nl\}\}Auto-indentation\{\{nl\}\}Initial code or document boilerplate\{\{nl\}\}Tie-in to help systems\{\{nl\}\}IDE-like features (compile, debug, and so on) \tn % Row Count 9 (+ 9) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Use a single editor well.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Source Code Control}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Always use source code control!} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.9442 cm} x{9.3258 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Debugging}} \tn % Row 0 \SetRowColor{LightBackground} A Debugging Mindset & Don't waste a single neuron on the train of thought that begins "but that can't happen" because quite clearly it can, and has. Try to discover the root cause of a problem, not just this particular appearance of it. \tn % Row Count 11 (+ 11) % Row 1 \SetRowColor{white} Where to Start & Before you start, check the warnings or better remove all of them. You first need to be accurate in your observations and data. \tn % Row Count 18 (+ 7) % Row 2 \SetRowColor{LightBackground} Bug Reproduction & The best way to start fixing a bug is to make it reproducible. The second best way is to make it reproducible with a single command. \tn % Row Count 25 (+ 7) % Row 3 \SetRowColor{white} Visualize Your Data & Use the tools that the debugger offers you. Pen and paper can also help. \tn % Row Count 29 (+ 4) % Row 4 \SetRowColor{LightBackground} Tracing & Know what happens before and after. \tn % Row Count 31 (+ 2) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.9442 cm} x{9.3258 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Debugging (cont)}} \tn % Row 5 \SetRowColor{LightBackground} Rubber Ducking & Explain the bug to someone else. \tn % Row Count 2 (+ 2) % Row 6 \SetRowColor{white} Process of Elimination & "select" Isn't Broken \tn % Row Count 4 (+ 2) % Row 7 \SetRowColor{LightBackground} \{\{nobreak\}\}The Element of Surprise & Don't Assume It—Prove It \tn % Row Count 6 (+ 2) % Row 8 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Fix the problem, not the blame. And don't panic.} \tn % Row Count 7 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{{\bf{Debugging Checklist}} \newline Is the problem being reported a direct result of the underlying bug, or merely a symptom? \newline Is the bug really in the compiler? Is it in the OS? Or is it in your code? \newline If you explained this problem in detail to a coworker, what would you say? \newline If the suspect code passes its unit tests, are the tests complete enough? What happens if you run the unit test with this data? \newline Do the conditions that caused this bug exist anywhere else in the system?} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Text Manipulation}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Learn a text manipulation language.} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Code Generators}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Code Generators Needn't Be Complex & Keep the input format simple, and the code generator becomes simple. \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} Code Generators Needn't Generate Code & You can use code generators to write just about any output: HTML, XML, plain text - any text that might be an input somewhere else in your project. \tn % Row Count 12 (+ 8) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{{\bf{Write Code That Writes Code}} \newline \newline {\bf{Passive code generators}} are run once to produce a result. They are basically parameterized templates, generating a given output from a set of inputs. \newline \newline {\bf{Active code generators}} are used each time their results are required. Take a single representation of some piece of knowledge and convert it into all the forms your application needs.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{A Pragmatic Paranoia}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{You can't write Perfect Software. No one in the brief history of computing has ever written a piece of perfect software. Pragmatic Programmers don't trust themselves, either.} \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.5988 cm} x{9.6712 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Design by Contract}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Design with Contracts & Write "lazy" code: be strict in what you will accept before you begin, and promise as little as possible in return. \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} Implementing DBC & Simply enumerating at design time:\{\{nl\}\}\{\{nl\}\}what the input domain range is\{\{nl\}\}what the boundary conditions are\{\{nl\}\}what the routine promises to deliver (and what it doesn't) \tn % Row Count 15 (+ 9) % Row 2 \SetRowColor{LightBackground} Assertions & You can use assertions to apply DBC in some range. (Assertions are not propagated in subclasses) \tn % Row Count 20 (+ 5) % Row 3 \SetRowColor{white} Invariants & Loop Invariants: Is true before and during the loop, therefore also when the loop finishes\{\{nl\}\}Semantic Invariants: ie the error should be on the side of not processing a transaction rather than processing a duplicate transaction. \tn % Row Count 31 (+ 11) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.5988 cm} x{9.6712 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Design by Contract (cont)}} \tn % Row 4 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{DBC enforces crashing early.} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{A correct program is one that does no more and no less than it claims to do. Use: \newline \newline Preconditions \newline Postconditions \newline Invariants} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{6.0445 cm} x{11.2255 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Dead Programs Tell No Lies}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Crash Early & A dead program normally does a lot less damage than a crippled one. When your code discovers that something that was supposed to be impossible just happened, your program is no longer viable. \tn % Row Count 8 (+ 8) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{All errors give you information. Pragmatic Programmers tell themselves that if there is an error, something very, very bad has happened.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Assertive Programming}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{If It can't happen, use Assertions to ensure that It won't.} \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{17.67cm}}{Assertions are also useful checks on an algorithm's operation.} \tn % Row Count 4 (+ 2) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Don't use assertions in place of real error handling.} \tn % Row Count 6 (+ 2) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{17.67cm}}{Leave assertions turned on, unless you have critical performance issues.} \tn % Row Count 8 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.1169 cm} x{9.1531 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{When to Use Exceptions}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Use exceptions for exceptional problems.} \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} {\bf{What Is Exceptional?}}\{\{nobreak\}\} & The program must run if all the exception handlers are removed. If your code tries to open a file for reading and that file does not exist, should an exception be raised?\{\{nl\}\}\{\{nl\}\}Yes: If the file should have been there\{\{nl\}\}No: If you have no idea whether the file should exist or not \tn % Row Count 15 (+ 14) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.7715 cm} x{9.4985 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{How to Balance Resources}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Finish What You Start & When managing resources: memory, transactions, threads, flies, timers—all kinds of things with limited availability, we have to close, finish, delete, deallocate them when we are done. \tn % Row Count 9 (+ 9) % Row 1 \SetRowColor{white} Nest Allocations & Deallocate resources in the opposite order to that in which you allocate them\{\{nl\}\}When allocating the same set of resources in different places in your code, always allocate them in the same order (prevent deadlocks) \tn % Row Count 19 (+ 10) % Row 2 \SetRowColor{LightBackground} Objects and Exceptions\{\{nobreak\}\} & Use finally to free resources. \tn % Row Count 21 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Bend, or Break}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{In order to keep up with today's near-frantic pace of change, we need to make every effort to write code that's as loose - as flexible - as possible.} \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Decoupling and the Law of Demeter}} \tn % Row 0 \SetRowColor{LightBackground} Minimize Coupling & Be careful about how many other modules you interact with and how you came to interact with them.\{\{nl\}\}\{\{nl\}\}Traversing relationships between objects directly can quickly lead to a combinatorial explosion.\{\{nl\}\}\{\{nl\}\}Symptoms:\{\{nl\}\}1.Large projects where the command to link a unit test is longer than the test program itself\{\{nl\}\}2."Simple" changes to one module that propagate through unrelated modules in the system\{\{nl\}\}3.Developers who are afraid to change code because they aren't sure what might be affected \tn % Row Count 26 (+ 26) % Row 1 \SetRowColor{white} The Law of Demeter for Functions\{\{nobreak\}\} & Any method of an object should call only methods belonging to:\{\{nl\}\}- itself\{\{nl\}\} - any parameters that were passed in to the method\{\{nl\}\}- any objects it created\{\{nl\}\}- any directly held component objects \tn % Row Count 37 (+ 11) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Decoupling and the Law of Demeter (cont)}} \tn % Row 2 \SetRowColor{LightBackground} {\bf{Does It Really Make a Difference?}} & Using The Law of Demeter will make your code more adaptable and robust, but at a cost: you will be writing a large number of wrapper methods that simply forward the request on to a delegate. imposing both a runtime cost and a space overhead.\{\{nl\}\}\{\{nl\}\}Balance the pros and cons for your particular application. \tn % Row Count 16 (+ 16) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Metaprogramming}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Put Abstractions in Code, Details in Metadata & We want to configure and drive the application via metadata as much as possible. Program for the general case, and put the specifics somewhere else —outside the compiled code base. \tn % Row Count 10 (+ 10) % Row 1 \SetRowColor{white} When to Configure & A flexible approach is to write programs that can reload their configuration while they're running.\{\{nl\}\}\{\{nl\}\}- long-running server process: provide some way to reread and apply metadata while the program is running.\{\{nl\}\}- small client GUI application: if restarts quickly no problem. \tn % Row Count 25 (+ 15) % Row 2 \SetRowColor{LightBackground} Benefits & - It forces you to decouple your design, which results in a more flexible and adaptable program.\{\{nl\}\}- It forces you to create a more robust, abstract design by deferring details—deferring them all the way out of the program.\{\{nl\}\}- You can customize the application without recompiling it.\{\{nl\}\}- Metadata can be expressed in a manner that's much closer to the problem domain than a general-purpose programming language might be.\{\{nl\}\}- You may even be able to implement several different projects using the same application engine, but with different metadata. \tn % Row Count 54 (+ 29) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Configure, don't integrate.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Temporal Coupling}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Two aspects of time:\{\{nl\}\}\{\{nl\}\} - Concurrency: things happening at the same time\{\{nl\}\} - Ordering: the relative positions of things in time \{\{nl\}\}\{\{nl\}\}We need to allow for concurrency and to think about decoupling any time or order dependencies. Reduce any time-based dependencies} \tn % Row Count 6 (+ 6) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Workflow}} \tn % Row 0 \SetRowColor{LightBackground} \{\{nobreak\}\}Analyze Workflow to Improve Concurrency & Use activity diagrams to maximize parallelism by identifying activities that could be performed in parallel, but aren't. \tn % Row Count 6 (+ 6) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Architecture}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Design using services.} \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{17.67cm}}{Balance load among multiple consumer processes: the hungry consumer model.} \tn % Row Count 3 (+ 2) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{In a hungry consumer model, you replace the central scheduler with a number of independent consumer tasks and a centralized work queue. Each consumer task grabs a piece from the work queue and goes on about the business of processing it. As each task finishes its work, it goes back to the queue for some more. This way, if any particular task gets bogged down, the others can pick up the slack, and each individual component can proceed at its own pace. Each component is temporally decoupled from the others.} \tn % Row Count 14 (+ 11) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Design for Concurrency}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Programming with threads imposes some design constraints—and that's a good thing.\{\{nl\}\}\{\{nl\}\} - Global or static variables must be protected from concurrent access \{\{nl\}\} - Check if you need a global variable in the first place. \{\{nl\}\} - Consistent state information, regardless of the order of calls \{\{nl\}\} - Objects must always be in a valid state when called, and they can be called at the most awkward times. Use class invariants, discussed in Design by Contract.\{\{nl\}\}\{\{nl\}\}Thinking about concurrency and time-ordered dependencies can lead you to design cleaner interfaces as well.} \tn % Row Count 12 (+ 12) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Deployment}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{You can be flexible as to how the application is deployed: standalone, client-server, or n-tier.\{\{nl\}\}\{\{nl\}\}If we design to allow for concurrency, we can more easily meet scalability or performance requirements when the time comes—and if the time never comes, we still have the benefit of a cleaner design.} \tn % Row Count 7 (+ 7) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.5988 cm} x{9.6712 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{It's Just a View}} \tn % Row 0 \SetRowColor{LightBackground} \seqsplit{Publish/Subscribe} & Objects should be able to register to receive only the events they need, and should never be sent events they don't need.\{\{nl\}\}\{\{nl\}\}Use this publish/subscribe mechanism to implement a very important design concept: the separation of a model from views of the model. \tn % Row Count 13 (+ 13) % Row 1 \SetRowColor{white} Model-View-Controller\{\{nobreak\}\} & Separates the model from both the GUI that represents it and the controls that manage the view.\{\{nl\}\}\{\{nl\}\}Advantage:\{\{nl\}\}\{\{nl\}\} - Support multiple views of the same data model.\{\{nl\}\} - Use common viewers on many different data models.\{\{nl\}\} - Support multiple controllers to provide nontraditional input mechanisms. \tn % Row Count 28 (+ 15) % Row 2 \SetRowColor{LightBackground} Beyond GUIs & The controller is more of a coordination mechanism, and doesn't have to be related to any sort of input device.\{\{nl\}\}\{\{nl\}\}{\bf{Model}} The abstract data model representing the target object. The model has no direct knowledge of any views or controllers.\{\{nl\}\}{\bf{View}} A way to interpret the model. It subscribes to changes in the model and logical events from the controller.\{\{nl\}\}{\bf{Controller}} A way to control the view and provide the model with new data. It publishes events to both the model and the view. \tn % Row Count 52 (+ 24) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Blackboards}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{A blackboard system lets us decouple our objects from each other completely, providing a forum where knowledge consumers and producers can exchange data anonymously and asynchronously.} \tn % Row Count 4 (+ 4) % Row 1 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{With Blackboard systems, you can store active objects - not just data - on the blackboard, and retrieve them by partial matching of fields (via templates and wildcards) or by subtypes.} \tn % Row Count 8 (+ 4) % Row 2 \SetRowColor{LightBackground} Functions that a Blackboard system should have & - {\bf{read}} Search for and retrieve data from the space. \{\{nl\}\}- {\bf{write}} Put an item into the space.\{\{nl\}\}- {\bf{take}} Similar to read, but removes the item from the space as well.\{\{nl\}\}- {\bf{notify}} Set up a notification to occur whenever an object is written that matches the template.\{\{nl\}\}\{\{nl\}\} Organize your Blackboard by partitioning it when working on large cases. \tn % Row Count 27 (+ 19) % Row 3 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Use blackboards to coordinate workflow} \tn % Row Count 28 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{While you are coding}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{We should avoid programming by coincidence—relying on luck and accidental successes— in favor of programming deliberately. {\bf{Don't program by coincidence.}}} \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{5.6991 cm} x{11.5709 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Program by Coincidence}} \tn % Row 0 \SetRowColor{LightBackground} Program Deliberately & Always be aware of what you are doing.\{\{nl\}\}Don't code blindfolded.\{\{nl\}\}Proceed from a plan.\{\{nl\}\}Rely only on reliable things.\{\{nl\}\}Document your assumptions.\{\{nl\}\}Don't just test your code, but test your assumptions as well. Don't guess\{\{nl\}\}Prioritize your effort.\{\{nl\}\}Don't be a slave to history. Don't let existing code dictate future code. \tn % Row Count 14 (+ 14) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.4623 cm} x{8.8077 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Algorithm Speed}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Pragmatic Programmers estimate the resources that algorithms use—time, processor, memory, and so on.} \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} {\bf{Use Big O Notation}} & {\bf{O(1)}}: Constant (access element in array, simple statements)\{\{nl\}\}{\bf{O(lg(n))}}: Logarithmic (binary search) lg(n) = lg2(n)\{\{nl\}\}{\bf{O(n)}}: Linear: Sequential search\{\{nl\}\}{\bf{O(n lg(n))}}: Worse than linear but not much worse(average runtime of quickshort, headsort)\{\{nl\}\}{\bf{O(n$^{\textrm{2}}$)}}: Square law (selection and insertion sorts)\{\{nl\}\}{\bf{O(n$^{\textrm{3}}$)}}: Cubic (multiplication of 2 n x n matrices)\{\{nl\}\}{\bf{O(Cⁿ)}}: Exponential (travelling salesman problem, set partitioning) \tn % Row Count 27 (+ 24) % Row 2 \SetRowColor{LightBackground} {\bf{Common Sense Estimation}}\{\{nobreak\}\} & - Simple loops: O(n)\{\{nl\}\}- Nested loops: O(n$^{\textrm{2}}$)\{\{nl\}\}- Binary chop: O(lg(n))\{\{nl\}\}- Divide and conquer: O(n lg(n)). Algorithms that partition their input, work on the two halves independently, and then combine the result.\{\{nl\}\}- Combinatoric: O(Cⁿ) \tn % Row Count 40 (+ 13) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.4623 cm} x{8.8077 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Algorithm Speed (cont)}} \tn % Row 3 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Estimate the Order of Your Algorithms} \tn % Row Count 1 (+ 1) % Row 4 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Test Your Estimates} \tn % Row Count 2 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.1169 cm} x{9.1531 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Refactoring}} \tn % Row 0 \SetRowColor{LightBackground} When Should You Refactor?\{\{nobreak\}\} & - Duplication. You've discovered a violation of the DRY principle.\{\{nl\}\}- Nonorthogonal design. You've discovered some code or design that could be made more orthogonal.\{\{nl\}\}- Outdated knowledge. Things change, requirements drift, and your knowledge of the problem increases. Code needs to keep up.\{\{nl\}\}- Performance. You need to move functionality from one area of the system to another to improve performance. \tn % Row Count 20 (+ 20) % Row 1 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Refactor Early, Refactor Often} \tn % Row Count 21 (+ 1) % Row 2 \SetRowColor{LightBackground} How Do You Refactor? & - Don't try to refactor and add functionality at the same time.\{\{nl\}\}- Make sure you have good tests before you begin refactoring.\{\{nl\}\}- Take short, deliberate steps. \tn % Row Count 29 (+ 8) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Code needs to evolve; it's not a static thing.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.1169 cm} x{9.1531 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Code That's Easy to Test}} \tn % Row 0 \SetRowColor{LightBackground} Unit Testing & Testing done on each module, in isolation, to verify its behavior. A software unit test is code that exercises a module. \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} Testing Against Contract\{\{nobreak\}\} & This will tell us two things:\{\{nl\}\}\{\{nl\}\}1.Whether the code meet the contract\{\{nl\}\}2.Whether the contract means what we think it means. \tn % Row Count 13 (+ 7) % Row 2 \SetRowColor{LightBackground} Design to Test & There's no better way to fix errors than by avoiding them in the first place. Build the tests before you implement the code. \tn % Row Count 19 (+ 6) % Row 3 \SetRowColor{white} Writing Unit Tests & By making the test code readily accessible, you are providing developers who may use your code with two invaluable resources:\{\{nl\}\}\{\{nl\}\}1.Examples of how to use all the functionality of your module\{\{nl\}\}2.A means to build regression tests to validate any future changes to the code\{\{nl\}\}\{\{nl\}\}You must run them, and run them often. \tn % Row Count 35 (+ 16) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.1169 cm} x{9.1531 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Code That's Easy to Test (cont)}} \tn % Row 4 \SetRowColor{LightBackground} Using Test Harnesses & Test harnesses should include the following capabilities:\{\{nl\}\}\{\{nl\}\}- A standard way to specify setup and cleanup\{\{nl\}\} - A method for selecting individual tests or all available tests\{\{nl\}\} - A means of analyzing output for expected (or unexpected) results\{\{nl\}\} - A standardized form of failure reporting\{\{nl\}\} \tn % Row Count 15 (+ 15) % Row 5 \SetRowColor{white} Build a Test Window & - Log files.\{\{nl\}\} - Hot-key sequence.\{\{nl\}\} - Built-in Web server. \tn % Row Count 19 (+ 4) % Row 6 \SetRowColor{LightBackground} A Culture of Testing & Test your Software, or your users will. \tn % Row Count 21 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Evil Wizards}} \tn % Row 0 \SetRowColor{LightBackground} Don't Use Wizard Code You Don't Understand \{\{nobreak\}\} & If you do use a wizard, and you don't understand all the code that it produces, you won't be in control of your own application. \tn % Row Count 7 (+ 7) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Before the project}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{With these critical issues sorted out before the project gets under way, you can be better positioned to avoid "analysis paralysis" and actually begin your successful project.} \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{The Requirements Pit}} \tn % Row 0 \SetRowColor{LightBackground} Don't Gather Requirements—Dig for Them\{\{nobreak\}\} & Policy may end up as metadata in the application. Gathering requirements in this way naturally leads you to a system that is well factored to support metadata. \tn % Row Count 8 (+ 8) % Row 1 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Work with a User to Think Like a User} \tn % Row Count 9 (+ 1) % Row 2 \SetRowColor{LightBackground} Documenting Requirements & Use "use cases" \tn % Row Count 11 (+ 2) % Row 3 \SetRowColor{white} Overspecifying & Requirements are not architecture. Requirements are not design, nor are they the user interface. Requirements are need. \tn % Row Count 17 (+ 6) % Row 4 \SetRowColor{LightBackground} Seeing Further & Abstractions live longer than details. \tn % Row Count 19 (+ 2) % Row 5 \SetRowColor{white} Just One More Wafer-Thin Mint… & What can we do to prevent requirements from creeping up on us? The key to managing growth of requirements is to point out each new feature's impact on the schedule to the project sponsors. \tn % Row Count 29 (+ 10) % Row 6 \SetRowColor{LightBackground} Use a Project Glossary & It's very hard to succeed on a project where the users and developers refer to the same thing by different names or, even worse, refer to different things by the same name. \tn % Row Count 38 (+ 9) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{The Requirements Pit (cont)}} \tn % Row 7 \SetRowColor{LightBackground} Get the Word Out & Publishing project documents to internal Web sites for easy access by all participants. \tn % Row Count 5 (+ 5) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Perfection is achieved, not when there is nothing left to add, but when there is nothing left to take away. . . . - Antoine de St. Exupery, Wind, Sand, and Stars, 1939} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Solving Impossible Puzzles}} \tn % Row 0 \SetRowColor{LightBackground} Don't Think Outside the Box—Find the Box & The key to solving puzzles is both to recognize the constraints placed on you and to recognize the degrees of freedom you do have, for in those you'll find your solution. \tn % Row Count 9 (+ 9) % Row 1 \SetRowColor{white} There Must Be an Easier Way! \{\{nobreak\}\} & If you can not find the solution, step back and ask yourself these questions:\{\{nl\}\}\{\{nl\}\}- Is there an easier way?\{\{nl\}\} - Are you trying to solve the right problem, or have you been distracted by a peripheral technicality?\{\{nl\}\} - Why is this thing a problem?\{\{nl\}\} - What is it that's making it so hard to solve?\{\{nl\}\} - Does it have to be done this way?\{\{nl\}\} - Does it have to be done at all?\{\{nl\}\} \tn % Row Count 30 (+ 21) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Not Until You're Ready}} \tn % Row 0 \SetRowColor{LightBackground} Listen to Nagging Doubts—Start When You're Ready & If you sit down to start typing and there's some nagging doubt in your mind, heed it. \tn % Row Count 5 (+ 5) % Row 1 \SetRowColor{white} Good Judgment or Procrastination? \{\{nobreak\}\} & Start prototyping. Choose an area that you feel will be difficult and begin producing some kind of proof of concept, and be sure to remember why you're doing it and that it is a prototype. \tn % Row Count 15 (+ 10) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{The Specification Trap}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Some things are better done than described.} \tn % Row Count 1 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Writing a specification is quite a responsibility. You should know when to stop: \newline \newline - Specification will never capture every detail of a system or its requirement. \newline - The expressive power of language itself might not be enough to describe a specification \newline - A design that leaves the coder no room for interpretation robs the programming effort of any skill and art.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Circles and Arrows}} \tn % Row 0 \SetRowColor{LightBackground} Don't Be a Slave to Formal Method\{\{nobreak\}\} & Formal methods have some serious shortcomings:\{\{nl\}\}\{\{nl\}\}- Diagrams are meaningless to the end users, show the user a prototype and let them play with it.\{\{nl\}\}- Formal methods seem to encourage specialization. It may not be possible to have an in-depth grasp of every aspect of a system.\{\{nl\}\}- We like to write adaptable, dynamic systems, using metadata to allow us to change the character of applications at runtime, but most current formal methods don't allow it. \tn % Row Count 24 (+ 24) % Row 1 \SetRowColor{white} Do Methods Pay Off? & Never underestimate the cost of adopting new tools and methods. \tn % Row Count 28 (+ 4) % Row 2 \SetRowColor{LightBackground} Should We Use Formal Methods? & Absolutely, but remember that is just one more tool in the toolbox. \tn % Row Count 32 (+ 4) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Circles and Arrows (cont)}} \tn % Row 3 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Expensive tools do not produce better designs.\{\{nobreak\}\}} \tn % Row Count 2 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Pragmatic Projects}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{} \tn % Row Count 0 (+ 0) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Pragmatic Teams}} \tn % Row 0 \SetRowColor{LightBackground} No Broken Windows\{\{nobreak\}\} & Quality is a team issue. Teams as a whole should not tolerate broken windows—those small imperfections that no one fixes. Quality can come only from the individual contributions of all team members. \tn % Row Count 10 (+ 10) % Row 1 \SetRowColor{white} Boiled Frogs & People assume that someone else is handling an issue, or that the team leader must have OK'd a change that your user is requesting. Fight this. \tn % Row Count 18 (+ 8) % Row 2 \SetRowColor{LightBackground} Communicate & The team as an entity needs to communicate clearly with the rest of the world. People look forward to meetings with them, because they know that they'll see a well-prepared performance that makes everyone feel good. There is a simple marketing trick that helps teams communicate as one: generate a brand. \tn % Row Count 34 (+ 16) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Pragmatic Teams (cont)}} \tn % Row 3 \SetRowColor{LightBackground} Don't Repeat Yourself & Appoint a member as the project librarian. \tn % Row Count 3 (+ 3) % Row 4 \SetRowColor{white} Orthogonality & It is a mistake to think that the activities of a project—analysis, design, coding, and testing—can happen in isolation. They can't. These are different views of the same problem, and artificially separating them can cause a boatload of trouble. \tn % Row Count 16 (+ 13) % Row 5 \SetRowColor{LightBackground} Organize Around Functionality, Not Job Functions & Split teams by functionally. Database, UI, API\{\{nl\}\} Let the teams organize themselves internally\{\{nl\}\} Each team has responsibilities to others in the project (defined by their agreed-upon commitments)\{\{nl\}\} We're looking for cohesive, largely self-contained teams of people\{\{nl\}\}\{\{nl\}\}Organize our resources using the same techniques we use to organize code, using techniques such as contracts (Design by Contract), decoupling (Decoupling and the Law of Demeter), and orthogonality (Orthogonality), and we help isolate the team as a whole from the effects of change. \tn % Row Count 45 (+ 29) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Pragmatic Teams (cont)}} \tn % Row 6 \SetRowColor{LightBackground} Automation & Automation is an essential component of every project team. \tn % Row Count 3 (+ 3) % Row 7 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Know when to stop adding paint.\{\{nobreak\}\}} \tn % Row Count 4 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.9442 cm} x{9.3258 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Ubiquitous Automation}} \tn % Row 0 \SetRowColor{LightBackground} All on Automatic & {\bf{Don't Use Manual Procedures.}} Using cron, we can schedule backups, nightly build, Web site... unattended, automatically. \tn % Row Count 6 (+ 6) % Row 1 \SetRowColor{white} Compiling the Project & We want to check out, build, test, and ship with a single command:\{\{nl\}\}\{\{nl\}\}- Generating Code\{\{nl\}\}- Regression Tests \tn % Row Count 12 (+ 6) % Row 2 \SetRowColor{LightBackground} Build Automation & A build is a procedure that takes an empty directory (and a known compilation environment) and builds the project from scratch, producing whatever you hope to produce as a final deliverable.\{\{nl\}\}\{\{nl\}\}1. Check out the source code from the repository\{\{nl\}\} 2. Build the project from scratch (marked with the version number).\{\{nl\}\} 3. Create a distributable image\{\{nl\}\} 4. Run specified tests\{\{nl\}\}\{\{nl\}\}When you don't run tests regularly, you may discover that the application broke due to a code change made three months ago. Good luck finding that one.\{\{nl\}\}\{\{nl\}\}{\bf{Nightly build}} run it every night.\{\{nl\}\}\{\{nl\}\}{\bf{Final builds}} (to ship as products), may have different requirements from the regular nightly build. \tn % Row Count 47 (+ 35) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.9442 cm} x{9.3258 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Ubiquitous Automation (cont)}} \tn % Row 3 \SetRowColor{LightBackground} Automatic Administrivia\{\{nobreak\}\} & Our goal is to maintain an automatic, unattended, content-driven workflow.\{\{nl\}\}\{\{nl\}\}Web Site Generation results of the build itself, regression tests, performance statistics, coding metrics... \{\{nl\}\}Approval Procedures get marks /{\emph{ Status: needs\_review }}/, send email... \tn % Row Count 13 (+ 13) % Row 4 \SetRowColor{white} The Cobbler's Children & Let the computer do the repetitious, the mundane—it will do a better job of it than we would. We've got more important and more difficult things to do. \tn % Row Count 21 (+ 8) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Ruthless testing}} \tn % Row 0 \SetRowColor{LightBackground} Test Early. Test Often. Test Automatically.\{\{nobreak\}\} & Tests that run with every build are the most effective. The earlier a bug is found, the cheaper it is to remedy. "Code a little, test a little". \tn % Row Count 8 (+ 8) % Row 1 \SetRowColor{white} What to Test & - Unit testing: code that exercises a module.\{\{nl\}\} - Integration testing: the major subsystems that make up the project work and play well with each other.\{\{nl\}\} - Validation and verification: test if you are delivering what users needs.\{\{nl\}\} - Resource exhaustion, errors, and recovery: discover how it will behave under real-world conditions. (Memory, Disk, CPU, Screen...)\{\{nl\}\} - Performance testing: meets the performance requirements under real-world conditions.\{\{nl\}\} - Usability testing: performed with real users, under real environmental conditions. \tn % Row Count 37 (+ 29) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Ruthless testing (cont)}} \tn % Row 2 \SetRowColor{LightBackground} How to Test & - Regression testing: compares the output of the current test with previous (or known) values. Most of the tests are regression tests.\{\{nl\}\} - Test data: there are only two kinds of data: real-world data and synthetic data.\{\{nl\}\} - Exercising GUI systems: requires specialised testing tools, based on a simple event capture/playback model.\{\{nl\}\} - Testing the tests: After you have written a test to detect a particular bug, cause the bug deliberately and make sure the test complains. Use Saboteurs to Test Your Testing\{\{nl\}\} - Testing thoroughly. Test State Coverage, Not Code Coverage \tn % Row Count 30 (+ 30) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.635 cm} x{8.635 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Ruthless testing (cont)}} \tn % Row 3 \SetRowColor{LightBackground} When to Test & As soon as any production code exists, it needs to be tested. Most testing should be done automatically. \tn % Row Count 6 (+ 6) % Row 4 \SetRowColor{white} Tightening the Net & If a bug slips through the net of existing tests, you need to add a new test to trap it next time. Find Bugs Once. \tn % Row Count 12 (+ 6) % Row 5 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Coding ain't done 'til all the tests run.} \tn % Row Count 13 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Pragmatic Programmers are driven to find our bugs now, so we don't have to endure the shame of others finding our bugs later.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.5988 cm} x{9.6712 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{It's All Writing}} \tn % Row 0 \SetRowColor{LightBackground} Comments in Code & In general, comments should discuss why something is done, its purpose and its goal. Remember that you (and others after you) will be reading the code many hundreds of times, but only writing it a few times. Even worse than meaningless names are misleading names. One of the most important pieces of information that should appear in the source file is the author's name—not necessarily who edited the file last, but the owner. \tn % Row Count 20 (+ 20) % Row 1 \SetRowColor{white} Executable Documents\{\{nobreak\}\} & Create documents that create schemas. The only way to change the schema is to change the document. \tn % Row Count 25 (+ 5) % Row 2 \SetRowColor{LightBackground} Technical Writers & We want the writers to embrace the same basic principles that a Pragmatic Programmer does—especially honoring the DRY principle, orthogonality, the model-view concept, and the use of automation and scripting. \tn % Row Count 35 (+ 10) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{7.5988 cm} x{9.6712 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{It's All Writing (cont)}} \tn % Row 3 \SetRowColor{LightBackground} Print It or Weave It & Paper documentation can become out of date as soon as it's printed. Publish it online, on the Web. Remember to put a date stamp or version number on each Web page. Using a markup system, you have the flexibility to implement as many different output formats as you need. \tn % Row Count 13 (+ 13) % Row 4 \SetRowColor{white} Markup Languages & Documentation and code are different views of the same underlying model, but the view is all that should be different. \tn % Row Count 19 (+ 6) % Row 5 \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{Treat English as just another programming language.} \tn % Row Count 21 (+ 2) % Row 6 \SetRowColor{white} \mymulticolumn{2}{x{17.67cm}}{Build documentation in, don't bolt it on.} \tn % Row Count 22 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{If there's a discrepancy, the code is what matters—for better or worse.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.2896 cm} x{8.9804 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Great Expectations}} \tn % Row 0 \SetRowColor{LightBackground} Communicating Expectations\{\{nobreak\}\} & Users initially come to you with some vision of what they want. You cannot just ignore it. Everyone should understand what's expected and how it will be built. \tn % Row Count 8 (+ 8) % Row 1 \SetRowColor{white} The Extra Mile & Give users that little bit more than they were expecting.\{\{nl\}\}\{\{nl\}\}- Balloon or ToolTip help\{\{nl\}\}- Keyboard shortcuts\{\{nl\}\}- A quick reference guide as a supplement to the user's manual Colorization\{\{nl\}\}- Log file analyzers\{\{nl\}\}- Automated installation\{\{nl\}\}- Tools for checking the integrity of the system\{\{nl\}\}- The ability to run multiple versions of the system for training\{\{nl\}\}- A splash screen customized for their organization\{\{nl\}\} \tn % Row Count 31 (+ 23) \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{x{8.2896 cm} x{8.9804 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{17.67cm}}{\bf\textcolor{white}{Great Expectations (cont)}} \tn % Row 2 \SetRowColor{LightBackground} Pride and Prejudice & Pragmatic Programmers don't shirk from responsibility. Instead, we rejoice in accepting challenges and in making our expertise well known. We want to see pride of ownership. "I wrote this, and I stand behind my work."\{\{nl\}\}\{\{nl\}\}{\bf{Sign Your Work.}} \tn % Row Count 13 (+ 13) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{17.67cm}}{The success of a project is measured by how well it meets the expectations of its users. \newline \newline {\bf{Gently Exceed Your Users' Expectations.}}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{17.67cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{17.67cm}}{\bf\textcolor{white}{Acknowledgements}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{17.67cm}}{Built from \{\{popup="https://github.com/HugoMatilla/The-Pragmatic-Programmer"\}\}Hugo Matilla's summary\{\{/popup\}\}. {\bf{You should still read the book, if you haven't already.}}} \tn % Row Count 4 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \end{document}