Skip to article frontmatterSkip to article content

PS2: How to rename things?

IUT d'Orsay, Université Paris-Saclay

Objectives

The goal of this session is to understand the following points:

Exercise 1 : Magic numbers

magic-numbers.cpp
#include <iostream>
#include <string>

using namespace std;

bool qualifiesForDiscount(double originalPrice) {
    return originalPrice >= 10;
}

double calculateDiscountPercentage(double originalPrice, bool isStudent, bool isLoyalCustomer) {
    double discountPercentage = 0.0;

    if (qualifiesForDiscount(originalPrice)) {
        if (isStudent) {
            discountPercentage += 10; 
        }
        if (isLoyalCustomer) {
            discountPercentage += 10;
        }
    }

    return discountPercentage;
}

double calculateDiscountAmount(double originalPrice, double discountPercentage) {
    return originalPrice * discountPercentage/100;
}

double calculateFinalPrice(double originalPrice, bool isStudent, bool isLoyalCustomer){
    double discountPercentage = calculateDiscountPercentage(originalPrice, isStudent, isLoyalCustomer);
    double discountAmount = calculateDiscountAmount(originalPrice, discountPercentage);
    double finalPrice = originalPrice - discountAmount;
    return finalPrice;
}

double redeemStudentPoints(double discountAmount){
    return discountAmount*(100-10)/100;
}

double redeemLoyaltyPoints(double discountAmount){
    return discountAmount*(100-2*10)/100;
}

double calculateRewardPoints(double discountAmount, bool isStudent, bool isLoyalCustomer){
    double rewardPoints = 0.0;
    if (isStudent){
        rewardPoints = redeemStudentPoints(discountAmount);
    } else if (isLoyalCustomer){
        rewardPoints = redeemLoyaltyPoints(discountAmount);
    }
    return rewardPoints;
}

int main() {
    const double originalPrice = 100;
    const bool isStudent = true;
    const bool isLoyalCustomer = true;

    cout << "Original price: " << originalPrice << " euros." << endl;

    double finalPrice = calculateFinalPrice(originalPrice,isStudent,isLoyalCustomer);
    cout << "Final price with student and loyalty discounts: " << finalPrice << " euros." << endl;

    double discountAmount = originalPrice - finalPrice;
    cout << "Your reward points: " << calculateRewardPoints(discountAmount,isStudent,isLoyalCustomer) << endl;

    return 0;
}
  1. Save and compile the code (with g++ -o magic-numbers magic-numbers.cpp).
  1. Run ./magic-numbers.

  2. Do you understand what this code does?

  1. Although the names of the elements are appropriate, this code is not clean. Can you spot the reasons?
  1. Name the magic numbers.

User input

To avoid recompiling the code every time you modify originalPrice, isStudent, and isLoyalCustomer, we can retrieve the values from the keyboard during execution.

  1. Replace the following lines with the code below.
const double originalPrice = 100;
const bool isStudent = true;
const bool isLoyalCustomer = true;
double userOriginalPrice;
cout << "Enter the original price: ";
cin >> userOriginalPrice;
const double& originalPrice = userOriginalPrice;

bool userIsStudent;
cout << "Are you a student? (1:Yes, 0:No) ";
cin >> userIsStudent;
const bool& isStudent = userIsStudent;

bool userIsLoyalCustomer;
cout << "Do you have a loyalty card? (1:Yes, 0:No) ";
cin >> userIsLoyalCustomer;
const bool& isLoyalCustomer = userIsLoyalCustomer;
  1. Test your code and answer the questions in the Quiz.

Exercise 2 : Classes and methods

classes-and-methods.cpp
#include <iostream>
using namespace std;

double b1 = 0.0;
double b2 = 100.0;

void d1(double x) {
    b1 += x;
}

void d2(double x) {
    b1 += x;
}

void w1(double x) {
    if (x + 4 <= b1) {
        b1 -= (x + 4);
    } else {
        cout << "Insufficient funds!" << endl;
    }
}

void w2(double x) {
    if (x + 2 <= b2) {
        b2 -= (x + 2);
    } else {
        cout << "Insufficient funds!" << endl;
    }
}

int main() {
    d1(100.0);
    w1(50.0);
    w2(50.0);
    cout << "First account balance: " << b1 << endl;
    cout << "Second account balance: " << b2 << endl;
    return 0;
}
  1. Do you understand what this code does?
  1. Quiz: Which of the two accounts has the higher balance after these transactions?

  2. Replace the previous transactions with the following:

d1(100.0);
w1(50.0);
d2(100.0);
w2(50.0);
  1. Quiz: Now, which account has the higher balance?
  1. To improve this code, we will rewrite it as follows:
classes-and-methods.cpp
#include <iostream>
using namespace std;

enum t {B, S};

class b {
private:
    double mB1;
    t mT;
    double mF;

public:
    b(double b1, t t1) : mB1(b1), mT(t1) {
        switch(t1){
            case B:
                mF = 4;
                break;
            case S: 
                mF = 2;
                break;
        }
    }

    void d(double x) {
        mB1 += x;
    }

    void w(double x) {
        if (x + mF <= mB1) {
            mB1 -= (x + mF);
        } else {
            cout << "Insufficient funds!" << endl;
        }
    }

    double getB1() const {
        return mB1;
    }

    string tToString() const {
        switch(mT){
            case B: return "Basic";
            case S: return "Standard";
            default: return "Unknown";
        }
    }
};

int main() {
    b a1(0.0,B);
    b a2(100.0,S);
    a1.d(100.0);
    a1.w(50.0);
    a2.d(100.0);
    a2.w(50.0);
    cout << "First account type: " << a1.tToString() << " and balance: " << a1.getB1() << endl;
    cout << "Second account type: " << a2.tToString() << " and balance: " << a2.getB1() << endl;
    return 0;
}
  1. Do you understand what this code does?
  1. Quiz: This time, which account has the highest balance?

  2. This code compiles and works as it should, but it is a real eyesore. It hurts me physically to look at it. It is essential to rename these horrors.

  1. Recompile and test your code.

  2. Add a third “Premium” type with a withdrawal fee of 1 euro.

  3. In the int main() function, replace the existing code with the following instructions:

  1. Quiz: What is the sum of the balances of all three accounts?

Return to the objectives and check the points you have mastered. Review the points you have not fully understood yet. Ask your instructor for help if needed.