do { cout << "Please enter the desired type of berth." << endl; cout << "s/S for suite, b/B for balcony, o/O for oceanview, i/I for inside berth." << endl; cin >> berthType; berthType = tolower(berthType); }while(!(berthType == 's' || berthType == 'b' || berthType == 'o'|| berthType == 'i')); switch (berthType) { case 's': berthName = "suite"; berthPrice = SUITE; break; case 'b': berthName = "balcony"; berthPrice = BALCONY; break; case 'o': berthName = "oceanview"; berthPrice = OCEANVIEW; break; case 'i': berthName = "inside berth"; berthPrice = INSIDE; } if (berthType == 's' || berthType == 'b' || berthType == 'o' || berthType == 'i') { do { cout << "Please enter the number of tickets." << endl; cin >> tickets; total_ticket = total_ticket + tickets; }while(!(tickets >= 2)); } --------------------------------------------------------------------- do { cout << "Please enter the number of tickets" << endl; cin >> ticket; }while ( !(ticket > 0 && ticket >= 2)); -------------------------------------------------------- char contd = anotherTransaction(); double totalcommission = 0; double totalcost = 0; int index = 0; while (contd == 'y'){ getTransaction(today[index]); totalcost += (today[index].hourlywage)*(today[index].hours); commission[index] = getCommission(today[index]); totalcommission += commission[index]; cout << setprecision(2) << fixed; cout << "The cost of this employee is $" << (today[index].hours)*(today[index].hourlywage) << endl; cout << "The commission charged is $" << commission[index] << endl; cout << endl; contd = anotherTransaction(); if (contd == 'y'){ index++; } if (contd =='n'){ cout << endl; cout << index + 1 << "transactions were processed" << endl; cout << setprecision(2) << fixed; cout << "The total cost of the transactions is: $" << totalcost << endl; cout << "The Total Commission is: $" << totalcommission << endl; printAllTransactions(today, index); } } ---------------------------------------------------- //another transaction function bool anotherTransaction() { bool runAgain; char yesNo; do { cout << "Would you like to process another transaction? " << endl; cin >> yesNo; if (toupper(yesNo) == 'Y') { cout << "chose yes" << endl; runAgain = true; } else { runAgain = false; } }while(runAgain!='Y' || runAgain!='N'); return runAgain; } ------------------------------------------------------ for (;;) { if (anotherTransaction(yes_no) == true) { getTransaction(todaysTransactions, index, total_cost, total_commission); index++; } else break; } ------------------------------------------------------ void getTransaction(transaction todaysTransactions[], int index, float& total_cost, float &total_commission) { char ans; float cost, commission; ans = getType(ans, todaysTransactions, index); todaysTransactions[index].employee_symbol = ans; todaysTransactions[index].number_hours = getHours(); todaysTransactions[index].pay_rate = getRate(); cost = todaysTransactions[index].number_hours * todaysTransactions[index].pay_rate; todaysTransactions[index].trans_cost = cost; cout << "The cost of this employee is: $" << fixed << setprecision(2) << cost << endl; commission = getCommission(ans, cost); cout << "The commission charged was: $" << fixed << setprecision(2) << commission << endl; total_cost = total_cost + cost; total_commission = total_commission + commission; } ------------------------------------------------------ bool anotherTransaction(char yes_no) { do { cout << "Is there another transaction that needs to be processed?" << endl; cin >> yes_no; yes_no = tolower(yes_no); if (yes_no == 'y') return true; else if (yes_no == 'n') return false; }while(yes_no != 'y' || yes_no != 'n'); } ------------------------------------------------------ void printOneTransaction(transaction todaysTransactions[], int index) { char letter = 'm'; string name = "manual employees:"; for (int first=0; first < 3; first++) { cout << "A summary of all the transactions for "<< name << endl; for (int count = 0; count < index; count++) { if (todaysTransactions[count].employee_symbol == letter) { cout << "Manual laborer provided for " << fixed << setprecision(2) << todaysTransactions[count].number_hours << " at a rate of $" << fixed << setprecision(2) << todaysTransactions[count].pay_rate << " an hour costs $" << fixed << setprecision(2) << todaysTransactions[count].trans_cost << endl; } } if (first = 0) { letter = 's'; name = "secretarial employees:"; } else if (first = 1) { letter = 't'; name = "trades people:"; } } } ------------------------------------------------------ while(process == true) { transact[time].typeOfEmployee = getType(transact[time]); transact[time].hourly_rate = getRate(transact[time]); transact[time].hours = getHours(transact[time]); transact[time].cost = getTransaction(transact[time]); totalCost += transact[time].cost; eachCommission = getCommission(transact[time]); totalCommission += eachCommission; printOneTransaction(transact[time], eachCommission); time++; cout << "--------------------------------------------" << endl; process = anotherTransaction(); } ------------------------------------------------------ if( 'e' == seating ) // economy cost = 39.95; if( 'f' == seating ) // family cost = 59.95; if( 'l' == seating ) // luxury seating cost = 99.95; else // if 'n' == seating // nosebleed seating cost = 29.95; Why is this incorrect? How do you fix it? ------------------------------------------------------ public void subclass::function() { superclass:function(); } Function not needed! ------------------------------------------------------ public void superclass:function() { // Code A // Code B // Code C } public void superclass:function() { // Code A // Code B // Code C // Code D } Why not: public void subclass:function() { superclas::function(); // Code D } ------------------------------------------------------ If( grade >= 90 ) Else if( grade < 90 && grade >= 80 ) Else if( grade < 80 && grade >= 70 ) ---------------------------- If( condition ) Var = value Else Var = var ---------------------------- if( condition1 && condition2 ) code A if( condition1 && not condition2 ) code B if( not condition1 && condition2 ) code C if( not condition1 && not condition2 ) code D ---------------------------- if( condition1 ) if( condition2 ) variable = A + X else variable = A + Y else if( condition2 ) variable = B + X else variable = B + Y void ---------------------------- Redefining subclass function to simply call superclass function? ---------------------------- Providing mutators for dependent variables: x,y, distance ---------------------------- Recursion: continue recursion for element replacement even after finding the element If( index >= size ) Return Else if( index == 0 ) Array[index] = value; Recursive call (array, index+1, value) Else Recursive call (array, index+1, value) ---------------------------- If( variable == 'A' ) Result = A If( variable == 'B' ) Result = B (Inefficient coding) ---------------------------- Pass a struct to a function by reference, which modifies it and returns it. --------------------------- X = X++; --------------------------- while( condition ) { if( condition ) { Code segment A } else { Code segment X break; } } Move post-loop code outside the loop --------------------------- In a method, using selectors to access data members --------------------------- do not pass arrays as const in C++ --------------------------- passing array size as const! - why? passed by value after all? --------------------------- Use symbolic constants when possible --------------------------- Move function closer to data cout << obj.getName() << " is paid $ " << obj.getRate() * obj.getHours() Why not obj.print()? --------------------------- Separate reading from computing: do { cout << "Enter number of shares" << endl; cin >> amount; cout << "Purchasing " << amount << " shares costs you $ " << amount * PRICE; } while( amount <= 0 ); --------------------------- Save character values to one case or the other and then use it. chVar = tolower( chVar ); Instead of using tolower() on each reference to the variable, if( tolower( chVar ) == 'y' ) or comparing the value of the variable to lower and uppercase values: if( chVar == 'y' || chVar == 'Y' ) --------------------------- Break up functions into logically modular units. Not a function to read two values. --------------------------- cond = true; do { if( cond ) loop body } while( cond ); --------------------------- switch( type ) case 0: cost = costArray[0] * shares; commission += 0.2 * cost; break; case 1: cost = costArray[1] * shares; commission += 0.2 * cost; break; case 2: cost = costArray[2] * shares; commission += 0.2 * cost; break; } Similarly, if( boardSize == 6 ) for( row = 0; row < 6; row++ ) for( col = 0; col < 6; col++ ) print board[row][col]; else if( boardSize == 8 ) for( row = 0; row < 8; row++ ) for( col = 0; col < 8; col++ ) print board[row][col]; else if( boardSize == 10 ) for( row = 0; row < 10; row++ ) for( col = 0; col < 10; col++ ) print board[row][col]; --------------------------- Returning something already passed by reference objClass function( obj & myObj, .. ) { return obj; } --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- --------------------------- Learning to re-factor code Replace magic numbers - use symbolic constants Use DeMorgan's laws to simplify boolean expressions/conditions Selection statements: Factor out code from if/else Factor out common code from nested if/else Use exhaustive analysis to simplify nested code Use nested code to make code more efficient (not a series of if statements) Loops: Functions: Make a function return if only one value Principle of least privilege - pass parameters by reference only as needed Classes: Make data members private Validate input in mutators of a class Avoid breaking encapsulation in selectors and mutators Polymorphism: Demorgan's laws for conditions ---------------------------------------------- if(advertisement == 'P'&& pages < 100000 && target =='N') { cost=35*(pages/PAGEMIN); } else { if(advertisement =='P' && pages < 100000 && target == 'Y') { cost=35*(pages/PAGEMIN)+FLATFEE; } else { if(advertisement == 'P' && pages >=100000 && target == 'N') { cost=35*(pages/PAGEMIN)*DISCOUNT; } else { cost=(60*pages/PAGEMIN +FLATFEE)*DISCOUNT; } } } //IF ELSE FOR Graphic if(advertisement == 'G' && pages <100000 && target =='N') { cost=60*(pages/PAGEMIN); } else { if(advertisement =='G' && pages < 100000 && target =='Y') { cost=60*(pages/PAGEMIN)+FLATFEE; } else { if(advertisement =='G' && pages >=100000 && target =='N') { cost=(60*pages/PAGEMIN)*DISCOUNT; } else { cost=(60*pages/PAGEMIN + FLATFEE)*DISCOUNT; } } } //IF ELSE FOR Audio if(advertisement == 'A' && pages <100000 && target == 'N') { cost=75*(pages/PAGEMIN); } else { if(advertisement =='A' && pages < 100000 && target =='Y') { cost=75*(pages/PAGEMIN)+FLATFEE; } else { if(advertisement =='G' && pages >=100000 && target =='N') { cost=75*(pages/PAGEMIN)*DISCOUNT; } else { cost=75*(pages/PAGEMIN+FLATFEE)*DISCOUNT; } } } } ------------------------------------------------------ if('p'==ad_type) { total_cost = (PRINT * pages)/1000; } else { if('g'==ad_type) { total_cost = (GRAPHIC * pages)/1000; } else { if('a'==ad_type) { total_cost = (AUDIO * pages)/1000; } } } return total_cost; if(ad_type=='p' || ad_type=='g' || ad_type=='a') { if(pages >= 100000) { discount_cost = total_cost * .09; final_cost = total_cost - discount_cost; } } return final_cost; if(ad_type=='p' || ad_type=='g' || ad_type=='a') { if(target=='y') { final_cost = total_cost + 250; } } ----------------------------------------------------------------------- switch(ad_type) { case 'p': type=35; break; case 'g': type=60; break; case 'a': type=75; break; default: cout<<"Error."<=1000&&pages<100000) { cost = (pages/1000)*(type); if(target_reply=='y') { cost = cost + TARGET_CHARGE; } } --------------------------------------------------------------------- double cost; const int PRINT = 35; const int GRAPHICS = 60; const int AUDIO = 75; const double DISCOUNT = .9; const int TARGET = 250; if(type == 'p') { if(pages >= 100000) { if(yesno == true) { cost = PRINT * (pages/1000) * DISCOUNT + TARGET; } else { cost = PRINT * (pages/1000) * DISCOUNT; } } else { if(yesno == true) { cost = PRINT * (pages/1000) + TARGET; } else { cost = PRINT * (pages/1000); } } } else { if(type == 'g') { if(pages >= 100000) { if(yesno == true) { cost = GRAPHICS * (pages/1000) * DISCOUNT + TARGET; } else { cost = GRAPHICS * (pages/1000) * DISCOUNT; } } else { if(yesno == true) { cost = GRAPHICS * (pages/1000) + TARGET; } else { cost = GRAPHICS * (pages/1000); } } } else { if(pages >= 100000) { if(yesno == true) { cost = AUDIO * (pages/1000) * DISCOUNT + TARGET; } else { cost = AUDIO * (pages/1000) * DISCOUNT; } } else { if(yesno == true) { cost = AUDIO * (pages/1000) + TARGET; } else { cost = AUDIO * (pages/1000); } } } } ---------------------------------------------------------------- Avoid third party variables in loops: ------------------------------------------ Avoid third party values in loops: // The additional investment double newInvestment = -1; // Ask user for the amount to invest while(newInvestment < 0) { cout << "How much would you like to invest $ \n"; cin >> newInvestment; } ------------------------------------------ Pass the whole object if more than one of its members used to update another object. // Set the objects name and tradedPrice to the name // and currentPrice of the stock selected newTransaction.set_name( holding.get_name() ); newTransaction.set_tradedPrice( holding.get_currentPrice() ); ------------------------------------------ bool do_conversion = false; bool done = false; cout << " Welcome to Cirsche Kriek's currency converter. " << endl; while ( ! done ) { // Input ready = false; while ( ! ready ) { cout << " Would you like to make another conversion (y/n)? " << endl; cin >> yes_no; yes_no = tolower(yes_no); if ( yes_no == 'y' ) { ready = true; do_conversion = true; } else if( yes_no == 'n' ) { ready = true; do_conversion = false; done = true; } } if (do_conversion) { ready = false; do { cout << " You can convert to/from the following currencies: " << endl << " South African Rand" << endl << " Maurition Rupess" << endl << " Japanese Yen" << endl << " European Euros" << endl << " British Pounds" << endl << " Russian Rubles" << endl << " Saudi Arabia Riyals" << endl << " Thailand Baht" << endl << " Please enter r for Rand, m for Maurition Rupees, y for Yen, e for Euros, p for Pounds, " << "u for Rubles, a for Arabian Riyals, and b for Baht: "; cin >> currency; currency = tolower(currency); //Use a switch to update while condition switch (currency) { case 'r': case 'm': case 'y': case 'e': case 'p': case 'u': case 'a': case 'b': ready = true; } } while ( ! ready); } ------------------------------------------ More likely to have logical errors. Use if-else to make the cases mutually exclusive. if( 'e' == currency ) { convert from dollar to euro } if( 'p' == currency ) { convert from dollar to pound } ------------------------------------------ If you have a hammer, everything appears like a nail. do { do { cout << "Would you like to make another conversion (y/n)"; cin >> toContinue; toContinue = tolower(toContinue); } while('y' != toContinue && 'n' != toContinue); if('y' == toContinue) { .. process } } Why not a while loop?! -------------------------------------------- if( isLatitude == true ) { do { cout << "Enter the minutes latitude" << endl; cin >> minutes; } while( minutes < 0 || minutes >= 60 ); } else // longitude { do { cout << "Enter the minutes longitude" << endl; cin >> minutes; } while( minutes < 0 || minutes >= 60 ); } -------------------------------------------- int const VIPMS = 125; int const VIPES = 200; int const ORMS = 100; int const ORES = 165; int const MEZMS = 75; int const MEZES = 115; int const BALMS = 60; int const BALES = 90; char choice; bool answer; string choicestring, isshow; int quantity; getPatronData(quantity, answer, choice); if(choice == 'v'&& answer == 1) { cost = VIPES * quantity; charge = .15; isshow = "Evening Show"; choicestring = "VIP"; } else { cost = VIPMS * quantity; charge = .1; isshow = "Matinee Show"; choicestring = "VIP"; } if(choice == 'o' && answer == 1) { cost = ORES * quantity; charge = .15; isshow = "Evening Show"; choicestring = "Orchestra"; } else { cost = ORMS * quantity; charge = .1; isshow = "Matinee Show"; choicestring = "Orchestra"; } if(choice == 'm' && answer == 1) { cost = MEZES * quantity; charge = .15; isshow = "Evening Show"; choicestring = "Mezzanine"; } else { cost = MEZMS * quantity; charge = .1; isshow = "Matinee Show"; choicestring = "Mezzanine"; } if(choice == 'b' && answer == 1) { cost = BALES * quantity; charge = .15; isshow = "Evening Show"; choicestring = "Balcony"; } else { cost = BALMS * quantity; charge = .1; isshow = "Matinee Show"; choicestring = "Balcony"; } ------------------------------------- //Compute Price price = temp_price * guests; //Compute discount for over 100 if(guests > 100) { personal_discount = price * DISCOUNT; discounted_price = price - personal_discount; price = discounted_price; } --- //Compute discount if (guests > 100) { total2 = total*discount; } total = total-total2; // what happens when guests not > 100? --- // Use different variable for each quantity //Input type of item do { cout<<"Please enter the type of item (g/G for groceries, d/D for durables, n/N for non-essentials)"<>type; if(type=='g') { type=1; } else { if(type=='d') { type=2; } else { type=3; } } } while(!(type<1)); //Input type of item --- Improve the reusability of the following code: String readFromFile() { File file = new File( "rulebase.txt" ); ... } Answer: pass file name as a parameter.. ------------------------------------- Similarly, improve: clarity/reusability/... if (!(month == 5 || month == 6 || month == 7 || month == 8)) { inital_cost = LAND_OFF; } else { inital_cost = LAND_PEAK; } ------------------------------------------ Do not pass as parameter, what can be declared as a local variable. e.g., int getNumber( int number ) { cin >> number; return number; } ------------------------------------------- Do not pass unnecessary parameters e.g., void printAmount( double amount, string currency, bool gainOrLoss ) { cout << "You bought goods worth " << amount << currency << endl; } -------------------------------------------- Do not declare parameter as a local variable also - syntax error otherwise. -------------------------------------------- Declare symbolic constants in the function where used, rather than in main, and then passed as parameter... -------------------------------------------- Instead of calling a function the second time, duplicating its code in main! -------------------------------------------- void readTransaction (char& choiceName, double& amountOfStocks ) { string companyName; string name; // choice of which company choiceName =getCompany(); //Get the amount of stocks name = printCompany(); amountOfStocks= getQuantity(companyName); return; } ---------------------------------------------------- string getShareName(char shareType) { char shareLetter; string shareName; switch(shareLetter) { case 'd': shareName= "Disney"; break; case 'm': shareName= "McDonalds"; break; case 'o': shareName= "Boa"; break; case 'k': shareName= "Kraft"; break; case 'c': shareName= "Coke"; break; case 'e': shareName= "Exxon"; break; case 'w': shareName= "Walmart"; break; case 'v': shareName= "Verizon"; } return shareName; } ---------------------------------------------------- double calculateCost (char choiceName, double amountOfStocks) { double stockPrice; double costForStocks; double totalCostStocks; //Switch for stock price switch(choiceName) { case 'd': stockPrice = WALT_DISNEY_STOCK; break; case 'a': stockPrice = AMERICAN_EXPRESS_STOCK; break; case 'h': stockPrice = HOME_DEPOT_STOCK; break; case 'm': stockPrice = MICROSOFT_STOCK; break; case 'v': stockPrice = VERIZON_STOCK; break; case 'n': stockPrice = MCDONALD_STOCK; break; case 'c': stockPrice = COCA_COLA_STOCK; break; case 'b': stockPrice = BANK_OF_AMERICA_STOCK; break; default: break; } costForStocks = amountOfStocks * stockPrice; cout.setf(ios_base::fixed, ios_base::floatfield); cout.precision(2); return costForStocks; } ---------------------------------------------------- void computeTransaction (char& choiceName, double& amountOfStocks, double& costForStocks) { double totalCost; double finalCommission; totalCost = calculateCost (choiceName, amountOfStocks); cout << "The totalCost is $" << totalCost<= 200) { credit = (cost - 200)*DISCOUNT; cout << "A credit of $" << credit << " was awarded at the gift store for this purchase" << endl; } } } return credit; } ---------------------------------------------------- double calculateCost(int&day, int&time, int&tickets) { double ticketPrice; double totalCost, totalTax; switch(day) { case 1: if(time == 10 || time == 14 ) { ticketPrice = MONDAY_FRIDAY_10_14; } else { ticketPrice = MONDAY_FRIDAY_6_18; } break; case 2: if(time == 10 || time == 14 ) { ticketPrice = MONDAY_FRIDAY_10_14; } else { ticketPrice = MONDAY_FRIDAY_6_18; } break; case 3: if(time == 10 || time == 14 ) { ticketPrice = MONDAY_FRIDAY_10_14; } else { ticketPrice = MONDAY_FRIDAY_6_18; } break; case 4: if(time == 10 || time == 14 ) { ticketPrice = MONDAY_FRIDAY_10_14; } else { ticketPrice = MONDAY_FRIDAY_6_18; } break; case 5: if(time == 10 || time == 14 ) { ticketPrice = MONDAY_FRIDAY_10_14; } else { ticketPrice = MONDAY_FRIDAY_6_18; } break; case 6: if(time == 10 || time == 14) { ticketPrice = SATURDAY_10_14; } else { ticketPrice = SATURDAY_6_18; } break; case 7: if(time == 10 || time == 14 ) { ticketPrice = SUNDAY_10_14; } else { ticketPrice = SUNDAY_6_18; } break; } totalCost = ticketPrice * tickets; totalTax = totalCost * TAX; totalCost = totalCost + totalTax; return totalCost; } ---------------------------------------------------- Improve the readability of this code: void updateResources( char & type, double & amount, double & barTotal, double & restTotal ) { switch( type ) { case 'b': barTotal += amount; ... } } Do not pass by reference! ------------------------------------------------------- Similarly, improve readability in a program with arrays and no symbolic constant for its size or initializaing for loop or referencing for loop -------------------------------------------------------- answer = ' '; while( answer != 'p' && answer != 'q' ) { cin >> answer; } Do not initialize where input is needed --------------------------------------------------------- Do not use multiple ifs instead of if-else if( guessedSuit == computerSuit ) { if( guessedFace == computerFace ) { points = 10; } else { points = 2; } } else { if( guessedFace == computerFace ) { points = 4; } else { points = 0; } } versus the following incorrect code: points = 0; if( guessedSuit == computerSuit && guessedFace == computerFace ) points = 10; if( guessedSuit == computerSuit ) points = 2; if( guessedFace == computerFace ) points = 4; ------------------------------------ // ************printAllBySize() function************ // type can be f, g, or h (flying, gliding or hang-gliding void printAllBySize(const char typeList[], const short ageList[], short currentCustomer) { // Variables char sportChoice; short count, totalReservationsOfType = 0; // Input type of sport sportChoice = inputType(); // Print reservations by type switch(sportChoice) { case 'f': // Print all flying reservations for(count = 0; count < currentCustomer; count ++) { if(typeList[count] != 'f') { } else { printOneReservation(typeList, ageList, count); totalReservationsOfType ++; } } break; case 'g': // Print all gliding reservations for(count = 0; count < currentCustomer; count ++) { if(typeList[count] != 'g') { } else { printOneReservation(typeList, ageList, count); totalReservationsOfType ++; } } break; case 'h': // Print all hang-gliding reservations for(count = 0; count < currentCustomer; count ++) { if(typeList[count] != 'h') { } else { printOneReservation(typeList, ageList, count); totalReservationsOfType ++; } } break; } // Print total reservations of type cout << "There were a total of " << totalReservationsOfType << " reservations" << endl; // Return return; } -------------------------------