Calculations for a phone call

I'm trying to calculate the price for a phone call under these requirements,
 Price per min 4 dollars.
 VAT 25%.
 Between 8:00 and 18:30 you pay full price
 Prior to 8:00, and after 18:30 are given 65% discount on price per min.
 For conversations longer than 30 minutes are given a discount of 15% of the total price.

There is something wrong with my calculations but I can't figure out what it is.

Here is some examples for prices if the calculations work as they should.

07:45 - 8:15       101.25 $
07:45 - 8:16       90,31 $
07:30 - 07:38      14,00 $
07:55 - 08:10      58,75 $
12:03 - 12:53      212,50 $
17:58 - 18:37      146,41 $
07:59 - 18:31      2680,48 $     



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

using namespace std;

double convert(string start, string end);
double priceCalc(int startHour, int startMinute, int endHour, int endMinute);
bool errorCheck(int startHour, int startMinute, int endHour, int endMinute);

int main()
{
    char ch;
    
    do
    {
        string callStart,callEnd;
        
        cout<<"What time the call start? (hh:mm): ";
        getline(cin, callStart);
        
        cout<<"What time did the call end? (hh:mm): ";
        getline(cin, callEnd);
        
        cout<<convert(callStart,callEnd)<<" $" << endl;
        
        cout << "Run again(y/n)? ";
        cin >> ch; cin.ignore(250,'\n');
        
        do
        {
            ch = toupper(ch);
        }while( !(ch == 'Y' || ch == 'N'));
        
    }while(ch == 'Y');
    
    return 0;
}


double convert(string start, string end)
{
    int startHour = 0, startMinute = 0, endHour = 0, endMinute = 0;
    
    string::size_type startPos = start.find(":");
    if(startPos != string::npos)
        ;
    else
    {
        cout << "Only : is allowed" << endl;
        return 0;
    }
    
    string::size_type endPos = end.find(":");
    if(endPos != string::npos)
        ;
    else
    {
        cout << "Only : is allowed" << endl;
        return 0;
    }
    
    start.replace(start.find(":"), 1, " ");
    end.replace(end.find(":"), 1, " ");
    
    
    istringstream iss(start);
    iss >> startHour >> startMinute;
    
    iss.clear();
    iss.str(end);
    iss >> endHour >> endMinute;
    
    if (errorCheck(startHour,startMinute,endHour,endMinute))
        return 0;
    
    return priceCalc(startHour,startMinute,endHour,endMinute);
    
}


bool errorCheck(int startHour, int startMinute, int endHour, int endMinute)
{
    
    if (((startHour * 60) + startMinute) >= ((endHour * 60) + endMinute))
    {
        cout << "Time error ";
        return true;
    }
    
    if (startHour>23||startHour<00||endHour>23||endHour<00||startMinute>59||startMinute<00||endMinute>59||endMinute<00)
    {
        cout << "Time error ";
        return true;
    }
    else
        return false;
}


double priceCalc(int startHour, int startMinute, int endHour, int endMinute)
{
    int startinMiuntes = startHour * 60 + startMinute;
    int endinMinutes = endHour * 60 + endMinute;
    
    
    int totMin = 0;
    int const pricePerMin=4;
    double price;
    const double VAT=1.25;
    const double disconut=0.35;
    const double discount30min=0.85;
    
    totMin=endinMinutes-startinMiuntes;
    
    if((startHour>=8 && startMinute>=0) && (endHour<=18 && endMinute<=30))
        price=totMin*pricePerMin*VAT;
    else
        price=(pricePerMin*disconut)*totMin*VAT;
    
    if(totMin>30)
    {
        price=price*discount30min;
    }
    
    return price;
}
Last edited on
Please don't post the same problem multiple times. It wastes people's time.
You should continue to post to your existing thread.
http://www.cplusplus.com/forum/beginner/204702/

closed account (48T7M4Gy)
http://www.cplusplus.com/forum/beginner/204686/
Another one :(

Green tick all the multiple threads. Thanks for your cooperation.
@AbstractionAnon people don't answer me so what do you expect me to do?
closed account (48T7M4Gy)
what do you expect me to do?

Cooperate perhaps.
@kermot sure want happen again. Now, can you pls help me?
Lines 42:73: Do you see a lot of repetitive code here? Perfect for a function.

There are six pricing cases you have to deal with:
// 1 Call begins and ends before full price start time
// 2 Call overlaps full price start time
// 3 Call begins and ends within full price window
// 4 Call overlaps full price end time
// 5 Call begins and ends after full price end time
// 6 Call begins before full price window and ends after full price window

Your code assumes that if the call is not fully within the full price window, the discount price applies.

You also have a problem with your 30 minute discount and VAT calculation. You should calculate the price, apply the discount if applicable, then apply the VAT. As you're doing it, you discounting after applying the VAT. i.e. You're charging VAT on the pre-discounted amount.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <algorithm>
using namespace std;

double priceCalc (int start_min, int end_min, int elapsed); 

//  Return a time as minutes since midnight
int get_time ()
{   string  temp;
    int     hr;
    int     min;
    char    junk;
    
    while (getline (cin, temp))
    {   stringstream        ss (temp);
    
        ss >> hr >> junk >> min;
        if (hr >= 0 && hr <= 23 && junk == ':' && min >= 0 && min <= 59)
            return hr * 60 + min;   //  Good time
        cout << "Invalid time" << endl;
    }
    throw std::exception ("Error on cin");
}                
    
int main()
{   int     start_time, end_time, elapsed_time;
    double  cost;
    char    ch = 'Y';
            
    do
    {   cout << "What time the call start? (hh:mm): ";
        start_time = get_time (); 
        cout << "What time did the call end? (hh:mm): ";
        end_time = get_time (); 
        elapsed_time = end_time - start_time; 
        if (elapsed_time <= 0)
        {   cout << "End time must be > start time" << endl;
            continue;
        }            
        cout << "Elapsed minutes: " << elapsed_time << endl;
        cost = priceCalc (start_time, end_time, elapsed_time);
        cout << fixed << setprecision(2) << cost << " $" << endl;
        
        cout << "Run again(y/n)? ";
        cin >> ch; 
        cin.ignore(250,'\n');        
        do
        {   ch = toupper(ch);
        } while ( !(ch == 'Y' || ch == 'N'));        
    } while (ch == 'Y');    
    return 0;
}

int minutes_in_window (int start_min, int end_min, int window_start, int window_end)
{   if (end_min < window_start)
        return 0;   //  Fully before window
    if (start_min > window_end)
        return 0;   //  Fully after window
    if (start_min >= window_start && end_min <= window_end)
        return end_min - start_min; //  Fully within window        
    if (start_min < window_start && end_min <= window_end)
        return end_min - window_start;  //  Overlaps only window start
    if (start_min >= window_start && end_min > window_end)
        return window_end - start_min;  //  Overlaps only window end
    //  Overlaps both      
    return window_end - window_start;            
}
    
void calculate_minutes (int start_min, int end_min, int & discount_min, int & prime_min)
{   const int prime_start_time = 8 * 60 + 0;
    const int prime_end_time = 18 * 60 + 30;
    const int midnight = 0;
    const int midnight_plus_one = 24*60;
    
    discount_min += minutes_in_window (start_min, end_min, midnight, prime_start_time);
    prime_min += minutes_in_window (start_min, end_min, prime_start_time, prime_end_time);
    discount_min += minutes_in_window (start_min, end_min, prime_end_time, midnight_plus_one);
    cout << "Discount minutes = " << discount_min << endl;
    cout << "Prime Minutes = " << prime_min << endl;
}    

double priceCalc (int start_min, int end_min, int elapsed_min)
{   const double pricePerMin = 4.00;
    const double VAT=1.25;
    const double discount=0.35;
    const double discount30min=0.85;
    double price = 0.0;
    int     discount_min = 0;
    int     prime_min = 0;
    
    calculate_minutes (start_min, end_min, discount_min, prime_min);
    price += prime_min * pricePerMin;
    price += (pricePerMin * discount) * discount_min;
    
    if (elapsed_min > 30)
        price *= discount30min;
    price *= VAT;    
    return price;
}

Last edited on
Thank you! @AbstractionAnon
Topic archived. No new replies allowed.