Correct Use of Variables, Data, Expressions and Constants Correctly Organizing Data and Expressions Svetlin Nakov Technical Trainer www.nakov.com Telerik Software Academy academy.telerik.com
Table of Contents  Principles for Initialization  Scope, Lifetime, Span  Using Variables  Variables Naming  Naming convention  Standard Prefixes  Using Expressions  Using Constants 2
Principles for Initialization Best Practices
Initially Assigned Variables in C#  Static variables  Instance variables of class instances  Instance variables of initially assigned struct variables  Array elements  Value parameters  Reference parameters  Variablesdeclared in a catch clause or a foreach statement 4
Initially Unassigned Variables in C#  Instance variables of initially unassigned struct variables  Output parameters  Including the this variable of struct instance constructors  Local variables  Except those declared in a catch clause or a foreach statement 5
Guidelines for Initializing Variables  When the problems can happen?  The variable has never been assigned a value  The value in the variable is outdated  Part of the variable has been assigned a value and a part has not  E.g. Student class has initialized name, but faculty number is left unassigned  Developing effective techniques for avoiding initialization problems can save a lot of time 6
Variable Initialization  Initialize all variables before their first usage  Local variables should be manually initialized  Declare and define each variable close to where it is used  This C# code will result in compiler error: int value; Console.WriteLine(value);  We can initialize the variable at its declaration: int value = 0; Console.WriteLine(value); 7
Variable Initialization (2)  Pay special attention to counters and accumulators  A common error is forgetting to reset a counter or an accumulator int sum = 0; for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) { sum = sum + array[i, j]; The sum must be reset after } the end of the inner for loop Console.WriteLine( "The sum of the elements in row {0} is {1}", sum); } 8
Variable Initialization (3)  Check the need for reinitialization  Make sure that the initialization statement is inside the part of the code that’s repeated  Check input parameters for validity  Before you assign input values to anything, make sure the values are reasonable int input; bool validInput = int.TryParse(Console.ReadLine(), out input); if (validInput) { … 9
Partially Initialized Objects  Ensure objects cannot get into partially initialized state  Make all fields private and require valid values for all mandatory fields in all constructors  Example: Student object is invalid unless it has Name and FacultyNumber class Student { private string name, facultyNumber; public Student(string name, string facultyNumber) { … } } 10
Variables – Other Suggestions  Don't define unused variables  Compilers usually issues warnings  Don't use variables with hidden purpose  Incorrect example: int mode = 1; … if (mode == 1) …; // Read if (mode == 2) …; // Write if (mode == 3) …; // Read and write  Use enumeration instead: enum ResourceAccessMode { Read, Write, ReadWrite } 11
Retuning Result from a Method  Always assign the result of a method in some variable before returning it. Benefits:  Improved code readability  The returned value has self-documenting name  Simplified debugging The intent of the  Example: formula is obvious int salary = days * hoursPerDay * ratePerHour; return salary; We can put a breakpoint at this line  Incorrect example: and check if the result is correct return days * hoursPerDay * ratePerHour; 12
Scope, Lifetime, Span
Scope of Variables  Scope – a way of thinking about a variable’s celebrity status  How famous is the variable?  Global (static), member variable, local  Most famous variables can be used anywhere, less famous variables are much more restricted  The scope is often combined with visibility  In C# and Java, a variable can also be visible to a package or a namespace 14
Visibility of Variables  Variables' visibility is explicitly set restriction regarding the access to the variable  public, protected, internal, private  Always tryto reduce maximally the variables scope and visibility  This reduces potential coupling  Avoid public fields (exception: readonly / const in C# / static final in Java)  Access all fields through properties / methods 15
Exceeded Scope – Example public class Globals { public static int state = 0; } public class ConsolePrinter { public static void PrintSomething() { if (Globals.state == 0) { Console.WriteLine("Hello."); } else { Console.WriteLine("Good bye."); } } } 16
Span of Variables  Variable span  The of lines of code (LOC) between variable usages  Average span can be calculated for all usages  Variable span should be kept as low as possible  Define variables at their first usage, not earlier  Initialize variables as late as possible  Try to keep together lines using the same variable Always define and initialize variables just before their first use! 17
Calculating Span of Variable 1 a = 1; 2 b = 1; 3 c = 1; span = 1 4 b = a + 1; 5 b = b / c; span = 0  One line between the first reference to b and the second  There are no lines between the second reference to b and the third  The average span for b is (1+0)/2 = 0.5 18
Variable Live Time  Variable live time  The number of lines of code (LOC) between the first and the last variable usage in a block  Live time should be kept as low as possible  The same rules apply as for minimizing span:  Define variables at their first usage  Initialize variables just before their first use  Try to keep together lines using the same variable 19
Measuring the Live Time of a recordIndex Variable ( line 28-line 25 + 1 ) = 4 25 recordIndex = 0; 26 while (recordIndex < recordCount) { 27 ... 28 recordIndex = recordIndex + 1; ... 62 total = 0; total 63 done = false; ( line 69-line 62 + 1 ) = 8 64 while ( !done ) { ... 69 if ( total > projectedTotal ) { done 70 done = true; ( line 70-line 63 + 1 ) = 8  Average live time for all variables:  (4+8+8)/3≈7 20
Unneeded Large Variable Span and Live Time 1 int count; 2 int[] numbers = new int[100]; 3 for (int i = 0; i < numbers.Length; i++) 4 { 5 numbers[i] = i; 6 } 7 count = 0; live time 8 for (int i = 0; i < numbers.Length / 2; i++) = 19 9 { 10 numbers[i] = numbers[i] * numbers[i]; 11 } 12 for (int i = 0; i < numbers.Length; i++) span = 13 { (5+8+2) 14 if (numbers[i] % 3 == 0) /3=5 15 { 16 count++; 17 } 18 } 19 Console.WriteLine(count); 21
Reduced Span and Live Time 1 int[] numbers = new int[100]; 2 for (int i = 0; i < numbers.Length; i++) 3 { 4 numbers[i] = i; 5 } 6 for (int i = 0; i < numbers.Length / 2; i++) 7 { 8 numbers[i] = numbers[i] * numbers[i]; 9 } 10 int count = 0; 11 for (int i = 0; i < numbers.Length; i++) 12 { 13 if (numbers[i] % 3 == 0) live time = 9 14 { 15 count++; span= 16 } (4+2) / 3 = 2 17 } 18 Console.WriteLine(count); 22
Keep Variables Live The best case As Short a Time  Advantages of short time and short span  Gives you an accurate picture of your code  Reduces the chance of initialization errors  Makes your code more readable 23
Best Practices  Initialize variables used in a loop immediately before the loop  Don’t assigna value to a variable until just before the value is used  Never follow the old C / Pascal style of declaring variables in the beginning of each method  Begin with the most restricted visibility  Expand the visibility only when necessary  Group related statements together 24
Group Related Statements – Example You have to keep track of void SummarizeData(…) oldData, newData, { numOldData, numNewData, … totalOldData and GetOldData(oldData, numOldData); totalNewData GetNewData(newData, numNewData); totalOldData = Sum(oldData, numOldData); totalNewData = Sum(newData, numNewData); PrintOldDataSummary(oldData, totalOldData); PrintNewDataSummary(newData, totalNewData); SaveOldDataSummary(totalOldData, numOldData); SaveNewDataSummary(totalNewData, numNewData); … }  Six variables for just this short fragment 25
Better Grouping– Example The two blocks are void SummarizeDaily( … ) each shorter and { individually contain GetOldData(oldData, numOldData); fewer variables totalOldData = Sum(oldData, numOldData); PrintOldDataSummary(oldData, totalOldData); SaveOldDataSummary(totalOldData, numOldData); … GetNewData(newData, numNewData); totalNewData = Sum(newData, numNewData); PrintNewDataSummary(newData, totalNewData); SaveNewDataSummary(totalNewData, numNewData); … }  Easier to understand, right? 26
Using Variables Best Practices
Single Purpose  Variables should have single purpose  Never use a single variable for multiple purposes!  Economizing memory is not an excuse  Can you choose a good name for variable that is used for several purposes?  Example: variable used to count students or to keep the average of their grades  Proposed name: studentsCountOrAvgGrade 28
Variables Naming  The name should describe the object clearly and accurately, which the variable represents  Bad names: r18pq, __hip, rcfd, val1, val2  Good names: account, blockSize, customerDiscount  Address the problem, which the variable solves – "what" instead of "how"  Good names: employeeSalary, employees  Bad names: myArray, customerFile, customerHashTable 29
Poor and Good Variable Names x = x - xx; xxx = aretha + SalesTax(aretha); x = x + LateFee(x1, x) + xxx; x = x + Interest(x1, x);  What do x1, xx, and xxx mean?  What does aretha mean ? balance = balance - lastPayment; monthlyTotal = NewPurchases + SalesTax(newPurchases); balance = balance + LateFee(customerID, balance) + monthlyTotal; balance = balance + Interest(customerID, balance); 30
Naming Considerations  Naming depends on the scope and visibility  Bigger scope, visibility, longer lifetime  longer and more descriptive name: protected Account[] mCustomerAccounts;  Variables with smaller scope and shorter lifetime can be shorter: for (int i=0; i<customers.Length; i++) { … }  The enclosing type gives a context for naming: class Account { Name: string { get; set; } } // not AccountName 31
Optimum Name Length  Somewhere between the lengths of x and maximumNumberOfPointsInModernOlympics  Optimal length – 10 to 16 symbols  Too long numberOfPeopleOfTheBulgarianOlympicTeamFor2012  Too short а, n, z, щ  Just right numTeamMembers, teamMembersCount 32
Naming Specific Data Types  Naming counters UsersCount, RolesCount, FilesCount  Naming variables for state ThreadState, TransactionState  Naming temporary variables  Bad examples: a, aa, tmpvar1, tmpvar2  Good examples: index, value, count 33
Naming Specific Data Types (2)  Name Boolean variables with names implying "Yes / No" answers canRead, available, isOpen, valid  Booleans variables should bring "truth" in their name  Bad examples: notReady, cannotRead, noMoreData  Good examples: isReady, canRead, hasMoreData 34
Naming Specific Data Types (3)  Naming enumeration types  Use build in enumeration types (Enum) Color.Red, Color.Yellow, Color.Blue  Or use appropriate prefixes (e.g. in JS / PHP) colorRed, colorBlue, colorYellow  Naming constants – use capital letters MAX_FORM_WIDTH, BUFFER_SIZE  C# constants should be in PascalCase: Int32.MaxValue, String.Empty, InvariantCulture 35
Naming Convention  Some programmers resistto follow standards and conventions  But why?  Conventions benefits  Transfer knowledge across projects  Helps to learn code more quickly on a new project  Avoid calling the same thing by two different names 36
Naming Convention (2)  When should we use a naming convention?  Multiple developers are working on the same project  The source code is reviewed by other programmers  The project is large  The project will be long-lived  You always benefit from having some kind of naming convention! 37
Language-Specific Conventions  C# and Java / JavaScript conventions  i and j are integer indexes  Constants are in ALL_CAPS separated by underscores (sometimes PascalCase in C#)  Variable and method names use uppercase in C# and lowercase in JS for the first word  The underscore _ is not used within names  Except for names in all caps 38
Standard Prefixes  Hungarian notation – not used  Semantic prefixes (ex. btnSave)  Better use buttonSave  Do not miss letters to make name shorter  Abbreviate names in consistent way throughout the code  Create names, which can be pronounced (not like btnDfltSvRzlts)  Avoid combinations, which form another word or different meaning (ex. preFixStore) 39
Kinds of Names to Avoid  Document short names in the code  Remember, names are designed for the people, who will read the code  Not for those who write it  Avoid variables with similar names, but different purpose it UserStatus / UserCurrentStatus  Avoid names, that sounds similar decree / degree / digRee  Avoid digits in names 40
Kinds of Names to Avoid (2)  Avoid words, which can be easily mistaken  E.g. adsl, adcl, adctl, atcl  Avoid using non-English words  Avoid using standard types and keywords in the variable names  E.g. int, class, void, return  Do not use names, which has nothing common with variables content  Avoid names, that contains hard-readable symbols / syllables, e.g. Csikszentmihalyi 41
Using Expressions Best Practices
Avoid Complex Expressions  Never use complex expressions in the code!  Incorrect example: What shall we do if we get at this line IndexOutOfRangeException? for (int i=0; i<xCoords.length; i++) { for (int j=0; j<yCoords.length; j++) { matrix[i][j] = matrix[xCoords[findMax(i)+1]][yCoords[findMin(j)-1]] * matrix[yCoords[findMax(j)+1]][xCoords[findMin(i)-1]]; } } There are 10 potential sources of IndexOutOfRangeException in this expression!  Complex expressions are evil because:  Make code hard to read and understand, hard to debug, hard to modify and hard to maintain 43
Simplifying Complex Expressions for (int i = 0; i < xCoords.length; i++) { for (int j = 0; j < yCoords.length; j++) { int maxStartIndex = findMax(i) + 1; int minStartIndex = findMin(i) - 1; int minXcoord = xCoords[minStartIndex]; int maxXcoord = xCoords[maxStartIndex]; int minYcoord = yCoords[minStartIndex]; int maxYcoord = yCoords[maxStartIndex]; int newValue = matrix[maxXcoord][minYcoord] * matrix[maxYcoord][minXcoord]; matrix[i][j] = newValue; } } 44
Using Constants When and How to Use Constants?
Avoid Magic Numbers and Strings  What is magic number or value?  Magic numbers / values are all literals different than 0, 1, -1, null and "" (empty string)  Avoid using magic numbers / values  They are hard to maintain  In case of change, you need to modify all occurrences of the magic number / constant  Their meaning is not obvious  Example: what the number 1024 means? 46
The Evil Magic Numbers public class GeometryUtils { public static double CalcCircleArea(double radius) { double area = 3.14159206 * radius * radius; return area; } public static double CalcCirclePerimeter(double radius) { double perimeter = 6.28318412 * radius; return perimeter; } public static double CalcElipseArea(double axis1, double axis2) { double area = 3.14159206 * axis1 * axis2; return area; } } 47
Turning Magic Numbers into Constants public class GeometryUtils { public const double PI = 3.14159206; public static double CalcCircleArea(double radius) { double area = PI * radius * radius; return area; } public static double CalcCirclePerimeter(double radius) { double perimeter = 2 * PI * radius; return perimeter; } public static double CalcElipseArea( double axis1, double axis2) { double area = PI * axis1 * axis2; return area; } } 48
Constants in C#  There are two types of constants in C#  Compile-time constants: public const double PI = 3.14159206;  Replaced with their value during compilation  No field stands behind them  Run-time constants: public static readonly string ConfigFile = "app.xml";  Special fields initialized in the static constructor  Compiled into the assembly like any other class member 49
Constants in JavaScript  JS does not support constants  Simulated by variables / fields in ALL_CAPS: var PI = 3.14159206; var CONFIG = { COLOR : "#AF77EE", DEFAULT_WIDTH : 200, DEFAULT_HEIGHT : 300 }; document.getElementById("gameField").style.width = CONFIG.DEFAULT_WIDTH; document.getElementById("gameField").style. backgroundColor = CONFIG.COLOR; 50
When to Use Constants?  Constants should be used in the following cases:  When we need to use numbers or other values and their logical meaning and value are not obvious  File names public static readonly string SettingsFileName = "ApplicationSettings.xml";  Mathematical constants public const double E = 2.7182818284;  Bounds and ranges public const int READ_BUFFER_SIZE = 5 * 1024 *1024; 51
When to Avoid Constants?  Sometime it is better to keep the magic values instead of using a constant  Error messages and exception descriptions  SQL commands for database operations  Titles of GUI elements (labels, buttons, menus, dialogs, etc.)  For internationalization purposes use resources, not constants  Resources are special files embedded in the assembly / JAR file, accessible at runtime 52
Correct Use of Variables, Data, Expressions and Constants курсове и уроци по програмиране, уеб дизайн – безплатно BG Coder - онлайн състезателна система - online judge курсове и уроци по програмиране – Телерик академия форум програмиране, форум уеб дизайн уроци по програмиране и уеб дизайн за ученици ASP.NET курс - уеб програмиране, бази данни, C#, .NET, ASP.NET http://academy.telerik.com програмиране за деца – безплатни курсове и уроци ASP.NET MVC курс – HTML, SQL, C#, .NET, ASP.NET MVC безплатен SEO курс - оптимизация за търсачки алго академия – състезателно програмиране, състезания курсове и уроци по програмиране, книги – безплатно от Наков курс мобилни приложения с iPhone, Android, WP7, PhoneGap уроци по уеб дизайн, HTML, CSS, JavaScript, Photoshop Дончо Минков - сайт за програмиране free C# book, безплатна книга C#, книга Java, книга C# Николай Костов - блог за програмиране безплатен курс "Качествен програмен код" безплатен курс "Разработка на софтуер в cloud среда" C# курс, програмиране, безплатно
Homework 1. Refactor the following code to use proper variable naming and simplified expressions: public class Size { public double wIdTh, Viso4ina; public Size(double w, double h) { this.wIdTh = w; this.Viso4ina = h; } } public static Size GetRotatedSize( Size s, double angleOfTheFigureThatWillBeRotaed) { return new Size( Math.Abs(Math.Cos(angleOfTheFigureThatWillBeRotaed)) * s.wIdTh + Math.Abs(Math.Sin(angleOfTheFigureThatWillBeRotaed)) * s.Viso4ina, Math.Abs(Math.Sin(angleOfTheFigureThatWillBeRotaed)) * s.wIdTh + Math.Abs(Math.Cos(angleOfTheFigureThatWillBeRotaed)) * s.Viso4ina); } 54
Homework (2) 2. Refactor the following code to apply variable usage and naming best practices: public void PrintStatistics(double[] arr, int count) { double max, tmp; for (int i = 0; i < count; i++) { if (arr[i] > max) { max = arr[i]; } } PrintMax(max); // continue on the next slide 55
Homework (3) tmp = 0; max = 0; for (int i = 0; i < count; i++) { if (arr[i] < max) { max = arr[i]; } } PrintMin(max); tmp = 0; for (int i = 0; i < count; i++) { tmp += arr[i]; } PrintAvg(tmp/count); } 56
Free Trainings @ Telerik Academy  C# Programming @ Telerik Academy  csharpfundamentals.telerik.com  Telerik Software Academy  academy.telerik.com  Telerik Academy @ Facebook  facebook.com/TelerikAcademy  Telerik Software Academy Forums  forums.academy.telerik.com

5. using variables, data, expressions and constants

  • 1.
    Correct Use ofVariables, Data, Expressions and Constants Correctly Organizing Data and Expressions Svetlin Nakov Technical Trainer www.nakov.com Telerik Software Academy academy.telerik.com
  • 2.
    Table of Contents Principles for Initialization  Scope, Lifetime, Span  Using Variables  Variables Naming  Naming convention  Standard Prefixes  Using Expressions  Using Constants 2
  • 3.
  • 4.
    Initially Assigned Variablesin C#  Static variables  Instance variables of class instances  Instance variables of initially assigned struct variables  Array elements  Value parameters  Reference parameters  Variablesdeclared in a catch clause or a foreach statement 4
  • 5.
    Initially Unassigned Variablesin C#  Instance variables of initially unassigned struct variables  Output parameters  Including the this variable of struct instance constructors  Local variables  Except those declared in a catch clause or a foreach statement 5
  • 6.
    Guidelines for InitializingVariables  When the problems can happen?  The variable has never been assigned a value  The value in the variable is outdated  Part of the variable has been assigned a value and a part has not  E.g. Student class has initialized name, but faculty number is left unassigned  Developing effective techniques for avoiding initialization problems can save a lot of time 6
  • 7.
    Variable Initialization  Initialize all variables before their first usage  Local variables should be manually initialized  Declare and define each variable close to where it is used  This C# code will result in compiler error: int value; Console.WriteLine(value);  We can initialize the variable at its declaration: int value = 0; Console.WriteLine(value); 7
  • 8.
    Variable Initialization (2) Pay special attention to counters and accumulators  A common error is forgetting to reset a counter or an accumulator int sum = 0; for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) { sum = sum + array[i, j]; The sum must be reset after } the end of the inner for loop Console.WriteLine( "The sum of the elements in row {0} is {1}", sum); } 8
  • 9.
    Variable Initialization (3) Check the need for reinitialization  Make sure that the initialization statement is inside the part of the code that’s repeated  Check input parameters for validity  Before you assign input values to anything, make sure the values are reasonable int input; bool validInput = int.TryParse(Console.ReadLine(), out input); if (validInput) { … 9
  • 10.
    Partially Initialized Objects Ensure objects cannot get into partially initialized state  Make all fields private and require valid values for all mandatory fields in all constructors  Example: Student object is invalid unless it has Name and FacultyNumber class Student { private string name, facultyNumber; public Student(string name, string facultyNumber) { … } } 10
  • 11.
    Variables – OtherSuggestions  Don't define unused variables  Compilers usually issues warnings  Don't use variables with hidden purpose  Incorrect example: int mode = 1; … if (mode == 1) …; // Read if (mode == 2) …; // Write if (mode == 3) …; // Read and write  Use enumeration instead: enum ResourceAccessMode { Read, Write, ReadWrite } 11
  • 12.
    Retuning Result froma Method  Always assign the result of a method in some variable before returning it. Benefits:  Improved code readability  The returned value has self-documenting name  Simplified debugging The intent of the  Example: formula is obvious int salary = days * hoursPerDay * ratePerHour; return salary; We can put a breakpoint at this line  Incorrect example: and check if the result is correct return days * hoursPerDay * ratePerHour; 12
  • 13.
  • 14.
    Scope of Variables Scope – a way of thinking about a variable’s celebrity status  How famous is the variable?  Global (static), member variable, local  Most famous variables can be used anywhere, less famous variables are much more restricted  The scope is often combined with visibility  In C# and Java, a variable can also be visible to a package or a namespace 14
  • 15.
    Visibility of Variables Variables' visibility is explicitly set restriction regarding the access to the variable  public, protected, internal, private  Always tryto reduce maximally the variables scope and visibility  This reduces potential coupling  Avoid public fields (exception: readonly / const in C# / static final in Java)  Access all fields through properties / methods 15
  • 16.
    Exceeded Scope –Example public class Globals { public static int state = 0; } public class ConsolePrinter { public static void PrintSomething() { if (Globals.state == 0) { Console.WriteLine("Hello."); } else { Console.WriteLine("Good bye."); } } } 16
  • 17.
    Span of Variables Variable span  The of lines of code (LOC) between variable usages  Average span can be calculated for all usages  Variable span should be kept as low as possible  Define variables at their first usage, not earlier  Initialize variables as late as possible  Try to keep together lines using the same variable Always define and initialize variables just before their first use! 17
  • 18.
    Calculating Span ofVariable 1 a = 1; 2 b = 1; 3 c = 1; span = 1 4 b = a + 1; 5 b = b / c; span = 0  One line between the first reference to b and the second  There are no lines between the second reference to b and the third  The average span for b is (1+0)/2 = 0.5 18
  • 19.
    Variable Live Time Variable live time  The number of lines of code (LOC) between the first and the last variable usage in a block  Live time should be kept as low as possible  The same rules apply as for minimizing span:  Define variables at their first usage  Initialize variables just before their first use  Try to keep together lines using the same variable 19
  • 20.
    Measuring the LiveTime of a recordIndex Variable ( line 28-line 25 + 1 ) = 4 25 recordIndex = 0; 26 while (recordIndex < recordCount) { 27 ... 28 recordIndex = recordIndex + 1; ... 62 total = 0; total 63 done = false; ( line 69-line 62 + 1 ) = 8 64 while ( !done ) { ... 69 if ( total > projectedTotal ) { done 70 done = true; ( line 70-line 63 + 1 ) = 8  Average live time for all variables:  (4+8+8)/3≈7 20
  • 21.
    Unneeded Large Variable Span and Live Time 1 int count; 2 int[] numbers = new int[100]; 3 for (int i = 0; i < numbers.Length; i++) 4 { 5 numbers[i] = i; 6 } 7 count = 0; live time 8 for (int i = 0; i < numbers.Length / 2; i++) = 19 9 { 10 numbers[i] = numbers[i] * numbers[i]; 11 } 12 for (int i = 0; i < numbers.Length; i++) span = 13 { (5+8+2) 14 if (numbers[i] % 3 == 0) /3=5 15 { 16 count++; 17 } 18 } 19 Console.WriteLine(count); 21
  • 22.
    Reduced Span andLive Time 1 int[] numbers = new int[100]; 2 for (int i = 0; i < numbers.Length; i++) 3 { 4 numbers[i] = i; 5 } 6 for (int i = 0; i < numbers.Length / 2; i++) 7 { 8 numbers[i] = numbers[i] * numbers[i]; 9 } 10 int count = 0; 11 for (int i = 0; i < numbers.Length; i++) 12 { 13 if (numbers[i] % 3 == 0) live time = 9 14 { 15 count++; span= 16 } (4+2) / 3 = 2 17 } 18 Console.WriteLine(count); 22
  • 23.
    Keep Variables Live The best case As Short a Time  Advantages of short time and short span  Gives you an accurate picture of your code  Reduces the chance of initialization errors  Makes your code more readable 23
  • 24.
    Best Practices  Initialize variables used in a loop immediately before the loop  Don’t assigna value to a variable until just before the value is used  Never follow the old C / Pascal style of declaring variables in the beginning of each method  Begin with the most restricted visibility  Expand the visibility only when necessary  Group related statements together 24
  • 25.
    Group Related Statements – Example You have to keep track of void SummarizeData(…) oldData, newData, { numOldData, numNewData, … totalOldData and GetOldData(oldData, numOldData); totalNewData GetNewData(newData, numNewData); totalOldData = Sum(oldData, numOldData); totalNewData = Sum(newData, numNewData); PrintOldDataSummary(oldData, totalOldData); PrintNewDataSummary(newData, totalNewData); SaveOldDataSummary(totalOldData, numOldData); SaveNewDataSummary(totalNewData, numNewData); … }  Six variables for just this short fragment 25
  • 26.
    Better Grouping– Example The two blocks are void SummarizeDaily( … ) each shorter and { individually contain GetOldData(oldData, numOldData); fewer variables totalOldData = Sum(oldData, numOldData); PrintOldDataSummary(oldData, totalOldData); SaveOldDataSummary(totalOldData, numOldData); … GetNewData(newData, numNewData); totalNewData = Sum(newData, numNewData); PrintNewDataSummary(newData, totalNewData); SaveNewDataSummary(totalNewData, numNewData); … }  Easier to understand, right? 26
  • 27.
    Using Variables Best Practices
  • 28.
    Single Purpose  Variablesshould have single purpose  Never use a single variable for multiple purposes!  Economizing memory is not an excuse  Can you choose a good name for variable that is used for several purposes?  Example: variable used to count students or to keep the average of their grades  Proposed name: studentsCountOrAvgGrade 28
  • 29.
    Variables Naming  The name should describe the object clearly and accurately, which the variable represents  Bad names: r18pq, __hip, rcfd, val1, val2  Good names: account, blockSize, customerDiscount  Address the problem, which the variable solves – "what" instead of "how"  Good names: employeeSalary, employees  Bad names: myArray, customerFile, customerHashTable 29
  • 30.
    Poor and GoodVariable Names x = x - xx; xxx = aretha + SalesTax(aretha); x = x + LateFee(x1, x) + xxx; x = x + Interest(x1, x);  What do x1, xx, and xxx mean?  What does aretha mean ? balance = balance - lastPayment; monthlyTotal = NewPurchases + SalesTax(newPurchases); balance = balance + LateFee(customerID, balance) + monthlyTotal; balance = balance + Interest(customerID, balance); 30
  • 31.
    Naming Considerations  Namingdepends on the scope and visibility  Bigger scope, visibility, longer lifetime  longer and more descriptive name: protected Account[] mCustomerAccounts;  Variables with smaller scope and shorter lifetime can be shorter: for (int i=0; i<customers.Length; i++) { … }  The enclosing type gives a context for naming: class Account { Name: string { get; set; } } // not AccountName 31
  • 32.
    Optimum Name Length  Somewhere between the lengths of x and maximumNumberOfPointsInModernOlympics  Optimal length – 10 to 16 symbols  Too long numberOfPeopleOfTheBulgarianOlympicTeamFor2012  Too short а, n, z, щ  Just right numTeamMembers, teamMembersCount 32
  • 33.
    Naming Specific DataTypes  Naming counters UsersCount, RolesCount, FilesCount  Naming variables for state ThreadState, TransactionState  Naming temporary variables  Bad examples: a, aa, tmpvar1, tmpvar2  Good examples: index, value, count 33
  • 34.
    Naming Specific DataTypes (2)  Name Boolean variables with names implying "Yes / No" answers canRead, available, isOpen, valid  Booleans variables should bring "truth" in their name  Bad examples: notReady, cannotRead, noMoreData  Good examples: isReady, canRead, hasMoreData 34
  • 35.
    Naming Specific DataTypes (3)  Naming enumeration types  Use build in enumeration types (Enum) Color.Red, Color.Yellow, Color.Blue  Or use appropriate prefixes (e.g. in JS / PHP) colorRed, colorBlue, colorYellow  Naming constants – use capital letters MAX_FORM_WIDTH, BUFFER_SIZE  C# constants should be in PascalCase: Int32.MaxValue, String.Empty, InvariantCulture 35
  • 36.
    Naming Convention  Someprogrammers resistto follow standards and conventions  But why?  Conventions benefits  Transfer knowledge across projects  Helps to learn code more quickly on a new project  Avoid calling the same thing by two different names 36
  • 37.
    Naming Convention (2) When should we use a naming convention?  Multiple developers are working on the same project  The source code is reviewed by other programmers  The project is large  The project will be long-lived  You always benefit from having some kind of naming convention! 37
  • 38.
    Language-Specific Conventions  C#and Java / JavaScript conventions  i and j are integer indexes  Constants are in ALL_CAPS separated by underscores (sometimes PascalCase in C#)  Variable and method names use uppercase in C# and lowercase in JS for the first word  The underscore _ is not used within names  Except for names in all caps 38
  • 39.
    Standard Prefixes  Hungarian notation – not used  Semantic prefixes (ex. btnSave)  Better use buttonSave  Do not miss letters to make name shorter  Abbreviate names in consistent way throughout the code  Create names, which can be pronounced (not like btnDfltSvRzlts)  Avoid combinations, which form another word or different meaning (ex. preFixStore) 39
  • 40.
    Kinds of Namesto Avoid  Document short names in the code  Remember, names are designed for the people, who will read the code  Not for those who write it  Avoid variables with similar names, but different purpose it UserStatus / UserCurrentStatus  Avoid names, that sounds similar decree / degree / digRee  Avoid digits in names 40
  • 41.
    Kinds of Namesto Avoid (2)  Avoid words, which can be easily mistaken  E.g. adsl, adcl, adctl, atcl  Avoid using non-English words  Avoid using standard types and keywords in the variable names  E.g. int, class, void, return  Do not use names, which has nothing common with variables content  Avoid names, that contains hard-readable symbols / syllables, e.g. Csikszentmihalyi 41
  • 42.
  • 43.
    Avoid Complex Expressions Never use complex expressions in the code!  Incorrect example: What shall we do if we get at this line IndexOutOfRangeException? for (int i=0; i<xCoords.length; i++) { for (int j=0; j<yCoords.length; j++) { matrix[i][j] = matrix[xCoords[findMax(i)+1]][yCoords[findMin(j)-1]] * matrix[yCoords[findMax(j)+1]][xCoords[findMin(i)-1]]; } } There are 10 potential sources of IndexOutOfRangeException in this expression!  Complex expressions are evil because:  Make code hard to read and understand, hard to debug, hard to modify and hard to maintain 43
  • 44.
    Simplifying Complex Expressions for(int i = 0; i < xCoords.length; i++) { for (int j = 0; j < yCoords.length; j++) { int maxStartIndex = findMax(i) + 1; int minStartIndex = findMin(i) - 1; int minXcoord = xCoords[minStartIndex]; int maxXcoord = xCoords[maxStartIndex]; int minYcoord = yCoords[minStartIndex]; int maxYcoord = yCoords[maxStartIndex]; int newValue = matrix[maxXcoord][minYcoord] * matrix[maxYcoord][minXcoord]; matrix[i][j] = newValue; } } 44
  • 45.
    Using Constants When andHow to Use Constants?
  • 46.
    Avoid Magic Numbersand Strings  What is magic number or value?  Magic numbers / values are all literals different than 0, 1, -1, null and "" (empty string)  Avoid using magic numbers / values  They are hard to maintain  In case of change, you need to modify all occurrences of the magic number / constant  Their meaning is not obvious  Example: what the number 1024 means? 46
  • 47.
    The Evil MagicNumbers public class GeometryUtils { public static double CalcCircleArea(double radius) { double area = 3.14159206 * radius * radius; return area; } public static double CalcCirclePerimeter(double radius) { double perimeter = 6.28318412 * radius; return perimeter; } public static double CalcElipseArea(double axis1, double axis2) { double area = 3.14159206 * axis1 * axis2; return area; } } 47
  • 48.
    Turning Magic Numbers into Constants public class GeometryUtils { public const double PI = 3.14159206; public static double CalcCircleArea(double radius) { double area = PI * radius * radius; return area; } public static double CalcCirclePerimeter(double radius) { double perimeter = 2 * PI * radius; return perimeter; } public static double CalcElipseArea( double axis1, double axis2) { double area = PI * axis1 * axis2; return area; } } 48
  • 49.
    Constants in C# There are two types of constants in C#  Compile-time constants: public const double PI = 3.14159206;  Replaced with their value during compilation  No field stands behind them  Run-time constants: public static readonly string ConfigFile = "app.xml";  Special fields initialized in the static constructor  Compiled into the assembly like any other class member 49
  • 50.
    Constants in JavaScript JS does not support constants  Simulated by variables / fields in ALL_CAPS: var PI = 3.14159206; var CONFIG = { COLOR : "#AF77EE", DEFAULT_WIDTH : 200, DEFAULT_HEIGHT : 300 }; document.getElementById("gameField").style.width = CONFIG.DEFAULT_WIDTH; document.getElementById("gameField").style. backgroundColor = CONFIG.COLOR; 50
  • 51.
    When to UseConstants?  Constants should be used in the following cases:  When we need to use numbers or other values and their logical meaning and value are not obvious  File names public static readonly string SettingsFileName = "ApplicationSettings.xml";  Mathematical constants public const double E = 2.7182818284;  Bounds and ranges public const int READ_BUFFER_SIZE = 5 * 1024 *1024; 51
  • 52.
    When to AvoidConstants?  Sometime it is better to keep the magic values instead of using a constant  Error messages and exception descriptions  SQL commands for database operations  Titles of GUI elements (labels, buttons, menus, dialogs, etc.)  For internationalization purposes use resources, not constants  Resources are special files embedded in the assembly / JAR file, accessible at runtime 52
  • 53.
    Correct Use ofVariables, Data, Expressions and Constants курсове и уроци по програмиране, уеб дизайн – безплатно BG Coder - онлайн състезателна система - online judge курсове и уроци по програмиране – Телерик академия форум програмиране, форум уеб дизайн уроци по програмиране и уеб дизайн за ученици ASP.NET курс - уеб програмиране, бази данни, C#, .NET, ASP.NET http://academy.telerik.com програмиране за деца – безплатни курсове и уроци ASP.NET MVC курс – HTML, SQL, C#, .NET, ASP.NET MVC безплатен SEO курс - оптимизация за търсачки алго академия – състезателно програмиране, състезания курсове и уроци по програмиране, книги – безплатно от Наков курс мобилни приложения с iPhone, Android, WP7, PhoneGap уроци по уеб дизайн, HTML, CSS, JavaScript, Photoshop Дончо Минков - сайт за програмиране free C# book, безплатна книга C#, книга Java, книга C# Николай Костов - блог за програмиране безплатен курс "Качествен програмен код" безплатен курс "Разработка на софтуер в cloud среда" C# курс, програмиране, безплатно
  • 54.
    Homework 1. Refactor the following code to use proper variable naming and simplified expressions: public class Size { public double wIdTh, Viso4ina; public Size(double w, double h) { this.wIdTh = w; this.Viso4ina = h; } } public static Size GetRotatedSize( Size s, double angleOfTheFigureThatWillBeRotaed) { return new Size( Math.Abs(Math.Cos(angleOfTheFigureThatWillBeRotaed)) * s.wIdTh + Math.Abs(Math.Sin(angleOfTheFigureThatWillBeRotaed)) * s.Viso4ina, Math.Abs(Math.Sin(angleOfTheFigureThatWillBeRotaed)) * s.wIdTh + Math.Abs(Math.Cos(angleOfTheFigureThatWillBeRotaed)) * s.Viso4ina); } 54
  • 55.
    Homework (2) 2. Refactor the following code to apply variable usage and naming best practices: public void PrintStatistics(double[] arr, int count) { double max, tmp; for (int i = 0; i < count; i++) { if (arr[i] > max) { max = arr[i]; } } PrintMax(max); // continue on the next slide 55
  • 56.
    Homework (3) tmp = 0; max = 0; for (int i = 0; i < count; i++) { if (arr[i] < max) { max = arr[i]; } } PrintMin(max); tmp = 0; for (int i = 0; i < count; i++) { tmp += arr[i]; } PrintAvg(tmp/count); } 56
  • 57.
    Free Trainings @Telerik Academy  C# Programming @ Telerik Academy  csharpfundamentals.telerik.com  Telerik Software Academy  academy.telerik.com  Telerik Academy @ Facebook  facebook.com/TelerikAcademy  Telerik Software Academy Forums  forums.academy.telerik.com