Top Banner
Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University http:// softuni.bg High-Quality Code
50

Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Jan 13, 2016

Download

Documents

Elijah Russell
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Control Flow, Conditional Statements and Loops

Organizing the Control Flow Correctly

SoftUni TeamTechnical TrainersSoftware Universityhttp://softuni.bg

High-QualityCode

Page 2: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Table of ContentsOrganizing Straight-Line CodeUsing Conditional StatementsUsing LoopsOther Control Flow Structures

2

Page 3: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Organizing Straight-Line CodeOrder and Separate Your Dependencies Correctly

Page 4: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

4

When statement order matters

Make dependencies obvious Name methods according to dependencies Use method parameters

Document the control flow if needed

Straight-Line Code

data = GetData();groupedData = GroupData(data);PrintGroupedData(groupedData);

GetData();GroupData();Print();

Page 5: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

5

When statements’ order does not matter Make code read from top to bottom like a newspaper Group related statements together Make clear boundaries for dependencies

Use blank lines to separate dependencies User separate method

Straight-Line Code (2)

Page 6: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

6

Straight-Line Code – ExamplesReportFooter CreateReportFooter(Report report){ // …}

ReportHeader CreateReportHeader(Report report){ // …}

Report CreateReport(){ var report = new Report(); report.Footer = CreateReportFooter(report); report.Content = CreateReportContent(report);

report.Header = CraeteReportHeader(report); return report;}

ReportContent CreateReportContent(Report report){ // …}

Page 7: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

7

Straight-Line Code – Examples (2)Report CreateReport(){ var report = new Report();

report.Header = CreateReportHeader(report); report.Content = CreateReportContent(report); report.Footer = CreateReportFooter(report);

return report;}

ReportHeader CraeteReportHeader(Report report){ // …}

ReportContent CreateReportContent(Report report){ // …}

ReportFooter CreateReportFooter(Report report){ // …}

Page 8: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

8

The most important thing to consider when organizingstraight-line code is Ordering dependencies

Dependencies should be made obvious Through the use of good routine names, parameter lists and

comments

If code doesn’t have order dependencies Keep related statements together

Straight-Line Code – Summary

Page 9: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Using Conditional StatementsUsing Control Structures

Page 10: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

10

Always use { and } for the conditional statements body, even when it is a single line:

Why omitting the brackets could be harmful?

This is misleading code + misleading formatting

Using Conditional Statements

if (condition){ DoSometing();}

if (condition) DoSomething(); DoAnotherThing();DoDifferentThing();

Page 11: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

11

Always put the normal (expected) condition first after the if-clause

Start from most common cases first, then go to the unusual ones

Using Conditional Statements (2)

var response = GetHttpWebResponse();if (response.Code == Code.OK){ // ...}else{ if (response.Code == Code.NotFound) { // ... }}

var response = GetHttpWebResponse();if (response.Code == Code.NotFound){ // ...}else{ if (response.Code == Code.OK) { // ... }}

Page 12: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

12

Avoid comparing to true or false:

Always consider the else case If needed, document why the else isn’t necessary

Using Conditional Statements (3)

if (HasErrors){ ...}

if (HasErrors == true){ ...}

if (parserState != States.Finished){ // …}else{ // Ignore all content once the parser has finished}

Page 13: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

13

Avoid double negation

Write if-clause with a meaningful statement

Use meaningful boolean expressions, which read like a sentence

Using Conditional Statements (4)

if (HasErrors){ DoSometing();}

if (!HasNoError){ DoSomething();}

if (HasErrors){ DoSometing();}

if (!HasError);else{ DoSometing(); }

Page 14: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

14

Be aware of copy/paste problems in if-else bodies

Using Conditional Statements (5)

Person p = null;if (SomeCondition){ p = GetSomePerson();}else{ p = GetOtherPerson();}

p.SendMail();p.SendSms();

if (SomeCondition){ var p = GetSomePerson(); p.SendMail(); p.SendSms();}else{ var p = GetOtherPerson(); p.SendMail(); p.SendSms();}

Page 15: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

15

Do not use complex if-conditions You can always simplify them by introducing boolean variables or

boolean methods Incorrect example:

Complex boolean expressions can be harmful How you will find the problem if you get IndexOutOfRangeException?

Use Simple Conditions

if (x > 0 && y > 0 && x < Width-1 && y < Height-1 && matrix[x, y] == 0 && matrix[x-1, y] == 0 && matrix[x+1, y] == 0 && matrix[x, y-1] == 0 && matrix[x, y+1] == 0 && !visited[x, y]) …

Page 16: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

16

The last example can be easily refactored into self-documenting code:

Now the code is: Easy to read – the logic of the condition is clear Easy to debug – breakpoint can be put at the if

Simplifying Boolean Conditions

bool inRange = x > 0 && y > 0 && x < Width-1 && y < Height-1;if (inRange){ bool emptyCellAndNeighbours = matrix[x, y] == 0 && matrix[x-1, y] == 0 && matrix[x+1, y] == 0 && matrix[x, y-1] == 0 && matrix[x, y+1] == 0; if (emptyCellAndNeighbours && !visited[x, y]) …}

Page 17: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

17

Use object-oriented approachSimplifying Boolean Conditions (2)

class Maze{ Cell CurrentCell { get; set; } IList<Cell> VisitedCells { get; } IList<Cell> NeighbourCells { get; } Size Size { get; } bool IsCurrentCellInRange() { return Size.Contains(CurrentCell); } bool IsCurrentCellVisited() { return VisitedCells.Contains(CurrentCell); } (continues on the next slide)

Page 18: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

18

Now the code: Models the real scenario Stays close to the problem domain

Simplifying Boolean Conditions (3) bool AreNeighbourCellsEmpty() { … }

bool ShouldVisitCurrentCell() { return IsCurrentCellInRange() && CurrentCell.IsEmpty() && AreNeighbourCellsEmpty() && !IsCurrentCellVisited() }}

Page 19: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

19

Sometimes a decision table can be used for simplicity

Use Decision Tables

var table = new Hashtable();table.Add("A", new AWorker());table.Add("B", new BWorker());table.Add("C", new CWorker());

string key = GetWorkerKey();

var worker = table[key];if (worker != null){ ... worker.Work(); ...}

Page 20: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

20

Starting with a positive expression improves readability

Use De Morgan’s laws for negative checks

Positive Boolean Expressions

if (IsValid){ DoSometing();}else{ DoSometingElse();}

if (!IsValid){ DoSometingElse();}else{ DoSomething();}

if (!(IsValid && IsVisible))

if (!IsValid || !IsVisible)

Page 21: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

21

Avoid complex boolean conditions without parenthesis

Using parenthesis helps readability as well as ensure correctness

Too many parenthesis have to be avoided as well Consider separate Boolean methods or variables in those cases

Use Parentheses for Simplification

if (a < b && b < c || c == d)

if ((a < b && b < c) || c == d)

Page 22: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

22

Most languages evaluate from left to right Stop evaluation as soon as some of the boolean operands is satisfied

Some languages do not follow this "short-circuit" rule

Useful when checking for null

TODO: check if index is in range before value check DO NOT evaluate methods inside if-condition / for-loop initialization

Boolean Expression Evaluation

if (FalseCondition && OtherCondition)

if (TrueCondition || OtherCondition) = true

= false

if (list != null && list.Count > 0) …

Page 23: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

23

Write numeric boolean expressions as they are presented on a number line Contained in an interval

Outside of an interval

Numeric Expressions as Operands

if (x > a && b > x)

if (a < x && x < b) a bx

if (a > x || x > b)

if (x < a || b < x) a bx x

Page 24: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

24

Deep nesting of conditional statements and loops makesthe code unclear More than 2-3 levels is too deep Deeply nested code is complex and hard to read and understand Usually you can extract portions of the code in separate methods

This simplifies the logic of the code Using good method names makes the code self-documenting

Avoid Deep Nesting of Blocks

Page 25: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

if (maxElem != Int32.MaxValue){ if (arr[i] < arr[i + 1]) { if (arr[i + 1] < arr[i + 2]) { if (arr[i + 2] < arr[i + 3]) { maxElem = arr[i + 3]; } else { maxElem = arr[i + 2]; } } else { if (arr[i + 1] < arr[i + 3]) { maxElem = arr[i + 3]; } else { maxElem = arr[i + 1]; } } }

25

Deep Nesting – Example

(continues on the next slide)

Page 26: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

26

Deep Nesting – Example (2) else { if (arr[i] < arr[i + 2]) { if (arr[i + 2] < arr[i + 3]) { maxElem = arr[i + 3]; } else { maxElem = arr[i + 2]; } } else { if (arr[i] < arr[i + 3]) { maxElem = arr[i + 3]; } else { maxElem = arr[i]; } } }}

Page 27: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

27

private static int Max(int i, int j){ if (i < j) { return j; } else { return i; }}

private static int Max(int i, int j, int k){ if (i < j) { int maxElem = Max(j, k); return maxElem; } else { int maxElem = Max(i, k); return maxElem; }} (continues on the next slide)

Avoiding Deep Nesting – Example (2)

Page 28: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

28

Avoiding Deep Nesting – Example (2)private static int FindMax(int[] arr, int i){ if (arr[i] < arr[i + 1]) { int maxElem = Max(arr[i + 1], arr[i + 2], arr[i + 3]); return maxElem; } else { int maxElem = Max(arr[i], arr[i + 2], arr[i + 3]); return maxElem; }}

if (maxElem != Int32.MaxValue) { maxElem = FindMax(arr, i);}

Page 29: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

29

Choose the most effective ordering of cases Put the normal (usual) case first Order cases by frequency Put the most unusual (exceptional) case last Order cases alphabetically or numerically

Keep the actions of each case simple Extract complex logic in separate methods

Use the default clause in a case statement or the last else in a chain of if-else to trap errors

Using case Statement

Page 30: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

30

Incorrect case Statementvoid ProcessNextChar(char ch){ switch (parseState) { case InTag: if (ch == ">") { Console.WriteLine("Found tag: {0}", tag); text = ""; parseState = ParseState.OutOfTag; } else { tag = tag + ch; } break; case OutOfTag: … }}

Page 31: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

31

Improved case Statement

void ProcessNextChar(char ch){ switch (parseState) { case InTag: ProcessCharacterInTag(ch); break; case OutOfTag: ProcessCharacterOutOfTag(ch); break; default: throw new InvalidOperationException( "Invalid parse state: " + parseState); }}

Page 32: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

32

Avoid using fallthroughs (and goto case) When you do use them, document them well

Case – Best Practices

switch (c) { case 1: case 2: DoSomething(); // FALLTHROUGH case 17: DoSomethingElse(); break; case 5: case 43: DoOtherThings(); break; }

Page 33: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

33

For simple if-else-s, pay attention to the order of the if and else clauses Make sure the nominal case is clear

For if-then-else chains and case statements, choose the most readable order

Optimize boolean statements to improve readability Use the default clause in a case statement or the last else in

a chain of if-s to trap errors

Control Statements – Summary

Page 34: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Using LoopsChoosing the Appropriate Loop Type

Page 35: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

35

Choosing the correct type of loop: Use for loop to repeat some block of code a certain number of

times Use foreach loop to process each element of an array or a

collection Use while / do-while loop when you don't know how many

times a block should be repeated

Avoid deep nesting of loops You can extract the loop body in a new method

Using Loops

Page 36: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

36

Keep loops simple This helps people who read your code

Treat the inside of the loop as it were a routine Don’t make the reader look inside the loop to understand the loop control

Think of a loop as a black box:

Loops: Best Practices

while (!inputFile.EndOfFile() && !hasErrors){

}

(black box code)

Page 37: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

37

Keep loop housekeeping at the start or at the end of the loop block

Use meaningful variable names to make loops readable

Loops: Best Practices (2)

while (index < 10){ ... ... index += 2;}

while (index < 10){ ... index += 2; ...}

for(i = 2000, i < 2011, i++){ for(j = 1, j <= 12, j++) ...}

for (year = 2000, year < 2011, year++){ for(month = 1, month <= 12, month++) ...}

Page 38: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

38

Avoid empty loops

Be aware of your language loop semantics C# – access to modified closure

Loops: Best Practices (3)

do { inputChar = Console.Read();} while (inputChar != '\n');

while ((inputChar = Console.Read()) != '\n') {}

Page 39: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

39

Don’t explicitly change the index value to force the loop to stop Use while-loop with break instead

Put only the controlling statements in the loop header

Loops: Tips on for-Loop

for (i = 0, sum = 0; i < length; sum += arr[i], i++){ ;}

sum = 0;for (i = 0; i < length; i++){ sum += arr[i];}

Page 40: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

40

Avoid code that depends on the loop index’s final value

Loops: Tips on for-Loop (2)

for (i = 0; i < length; i++){ if (array[i].Id == key) { break; }}

// Lots of code...

return (i < length);

bool found = false;for (i = 0; i < length; i++){ if (array[i].Id == key) { found = true; break; }}

// Lots of code...

return found;

Page 41: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

41

Use continue for tests at the top of a loop to avoid nested if-s

Avoid loops with lots of break-s scattered trough it Use break and continue only with caution

Loops: break and continue

Page 42: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

42

Try to make the loops short enough to view it all at once (one screen)

Use methods to shorten the loop body Make long loops especially clear Avoid deep nesting in loops

How Long Should a Loop Be?

Page 43: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Other Control Flow Structuresreturn, goto

Page 44: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

44

Use return when it enhances readability Use return to avoid deep nesting

Avoid multiple return-s in long methods

The return Statement

void ParseString(string str){ if (string != null) { // Lots of code }}

void ParseString(string str){ if (string == null) { return; }

// Lots of code}

Page 45: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

45

Avoid goto-s, because they have a tendency to introduce spaghetti code

“A Case Against theGO TO Statement” by Edsger Dijkstra

Use goto-s as a last resort If they make the code

more maintainable

C# supports goto with labels, but avoid it!

GOTO

Page 46: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Using Control Flow StructuresExercises in Class

Page 47: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

47

1. Straight-Line Code Order methods by their dependencies

2. Conditional Statements and Loops Order the cases by frequency or natural order Keep expressions and statements simple Use the appropriate control flow structures Don’t use GOTO

Summary

Page 49: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

License

This course (slides, examples, demos, videos, homework, etc.)is licensed under the "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International" license

49

Attribution: this work may contain portions from "Fundamentals of Computer Programming with C#" book by Svetlin Nakov & Co. under CC-BY-SA license

"C# Part I" course by Telerik Academy under CC-BY-NC-SA license

Page 50: Control Flow, Conditional Statements and Loops Organizing the Control Flow Correctly SoftUni Team Technical Trainers Software University .

Free Trainings @ Software University Software University Foundation – softuni.org Software University – High-Quality Education,

Profession and Job for Software Developers softuni.bg

Software University @ Facebook facebook.com/SoftwareUniversity

Software University @ YouTube youtube.com/SoftwareUniversity

Software University Forums – forum.softuni.bg