5

Okay, so the assignment is to take input from a file named tickets.txt and output the total number of tickets sold, as well as the total revenue. The values in the text file are input in two columns (1) number of tickets sold, and (2) price of each ticket category.

The text file looks like:

250 5750
100 28000
50 35750
25 18750

This is the code that I came up with...

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

/* Program Name:  Ticket_Sales.cpp
 * Date: May 2, 2018
 * Purpose: Calculate Total Ticket Sales
 */

int main() {

    {
        ifstream inFile;
        float ticket_cost;
        float tickets_sold;
        float total_cost ;
        float total_sold ;
        float ticket_revenue;

        /*
         * I noticed someone doing something similar to this on StackExchange; seems absolutely brilliant to include
         * a manner to check if the program is accessing the file.
         */
        inFile.open("C:\\Users\\pinkp\\CLionProjects\\M05_Ticket_Sales\\tickets.txt");
            if (inFile.fail()) {
                cout << "Failed to open the file." << endl;
                cin.get ();
                return 1;
            }

        while(inFile >> tickets_sold >> ticket_cost) {
                total_sold += tickets_sold;
                total_cost += ticket_cost;
                ticket_revenue = (total_cost * total_sold);

        }
        cout << fixed << setprecision(2);
        cout << "Total Tickets Sold:  " << total_sold << "." << endl;
        cout << "Total Revenue:  " << ticket_revenue << "." << endl;
    }
    /*
     * The value continues to return 2 less than the intended output, and I cannot pinpoint the exact cause.
     */
    return 0;
}

But my output for ticket_revenue continues to give me 37506248.00, when inputting the numbers into a calculator manually will give you 37506250.00. A two number discrepancy. I thought about just doing a '+2' to get it up to the right number, but I figured my professor would frown on that.

Regardless of the numbers in the tickets.txt (I've changed them around a few times), it will always be two less than what I am expecting. Is this some super easy C++ or programming concept that I've somehow missed?

Thank you!

  • 1
    You should almost never use float when dealing with monetary amounts. Edit: or double either. Count cents in an int instead. –  May 03 '18 at 12:34
  • 1
    [Float and Double for monetary values](https://stackoverflow.com/q/4354710/332733) TL;DR; never ever use floating point for monetary values – Mgetz May 03 '18 at 12:36
  • @Ron floating point inaccuracies will catch up to you sooner or later, because you are bound to add a small number to a big one eventually, and fault tolerance is very low when dealing with money –  May 03 '18 at 12:38
  • 4
    Possible duplicate of [Why not use Double or Float to represent currency?](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) – Mgetz May 03 '18 at 12:39
  • @Ron I would hope not! Every financial coder I know uses `std::int64_t` almost exclusively. – Mgetz May 03 '18 at 12:42
  • @Rpn it's technically ok when dealing with amounts < 10000$, but why risk it? –  May 03 '18 at 12:43
  • 2
    *when inputting the numbers into a calculator manually will give you 37506250.00* -- Not surprising. That's why many financial institutions prohibit the usage of floating point, and instead use fixed point / integer (or even in "extreme" cases, use COBOL and not C++). – PaulMcKenzie May 03 '18 at 13:00
  • Are you sure the correct answer is `37506250`? I think you've made the same error in your calculation as you made in the code, namely computing `Σquantity * Σprice`, instead of `Σ (quantity * price)`. – Toby Speight May 03 '18 at 13:17
  • @TobySpeight Yeah, I noticed you pointed that out below. I just jumped in, without thoroughly thinking about it, and figured that adding up both columns and multiplying them together would be the way to go. We did something like that in-class before being assigned this... so I just assumed. Enormously grateful that you pointed it out! Saves me the headache of making the mistake again on future projects. – Jonas McClure May 03 '18 at 13:25
  • @JonasMcClure Rule of thumb is to do it on a whiteboard first. Every half hour of whiteboard time can save 4 hours of coding. – Mgetz May 03 '18 at 13:32

2 Answers2

6

You failed to initialize ticket_revenue - and look how it is assigned:

            ticket_revenue = (total_cost * total_sold);

This overwrites ticket_revenue with the product of the total number of tickets sold and the sum of all the prices.

You need something like (untested):

    unsigned long total_sold = 0;
    unsigned long ticket_revenue = 0;
    while (inFile >> tickets_sold >> ticket_cost) {
            auto transaction_revenue = tickets_sold * ticket_cost;
            total_sold += tickets_sold;
            ticket_revenue += transaction_revenue;
    }

BTW, don't use floating-point types for currency calculations!


Here's a version of your code with the above errors fixed, and without the external input file (so that it stands as a Minmal, Complete and Verifiable Example):

#include <iostream>
#include <vector>

int main()
{
    static const
        std::vector<std::pair<int, long>> sales =
        {{ 250, 5750 },
         { 100, 28000 },
         { 50, 35750 },
         { 25, 18750 } };

    long total_sold = 0;
    long ticket_revenue = 0;

    for (auto& sale: sales) {
        int tickets_sold = sale.first;
        long ticket_cost = sale.second;
        total_sold += tickets_sold;
        ticket_revenue += tickets_sold * ticket_cost;
    }

    std::cout << "Total Tickets Sold:  " << total_sold << ".\n";
    std::cout << "Total Revenue:  " << ticket_revenue << ".\n";
}

This produces the correct answer:

Total Tickets Sold:  425.
Total Revenue:  6493750.
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • Thank you!! I didn't even realize what I had done until I read your comment. I should have noticed something being off when 425 tickets made over 37 million! I completely overlooked that it'd need to multiply line by line rather than in total. – Jonas McClure May 03 '18 at 13:16
  • That's such a cool looking blurp of code, but I think that my professor might be a little confused as to how I went from learning what #include does to being able to code like an absolute beast. Thankfully, reading your code gives me a good starting point on things that I need to start looking up =) – Jonas McClure May 03 '18 at 13:22
  • Heh, I purposefully gave you code that you could learn from, but that would betray you if you just turned it in without understanding it... – Toby Speight May 03 '18 at 13:27
  • Oh no, I'm genuinely interested in learning all of this, and I really don't feel like getting kicked out of university for plagiarism anyhow. You've been a wonderful help, thank you. – Jonas McClure May 03 '18 at 13:30
2

I suppose that instead

    while(inFile >> tickets_sold >> ticket_cost) {
            total_sold += tickets_sold;
            total_cost += ticket_cost;
            ticket_revenue = (total_cost * total_sold);

    }

you should write

    ticket_revenue = 0;

    while(inFile >> tickets_sold >> ticket_cost) {
       ticket_revenue += ticket_sold * ticket_cost;
    }

Otherwise you sum number of tickets and cost of tickets and you should get a bigger value.

max66
  • 65,235
  • 10
  • 71
  • 111
  • Goot catch. The original algorithm is just plain wrong anyway. – Jabberwocky May 03 '18 at 13:17
  • Yep, sorry about that, and thank you for pointing it out. I totally overlooked that my logic in solving it was totally off. Also, thanks for keeping it simple enough for me to understand =) – Jonas McClure May 03 '18 at 13:27
  • @JonasMcClure - what I don't understand is how you can obtain a difference of only 2.00. – max66 May 03 '18 at 13:32
  • @max66 The difference was based on my previous assertion that the answer would be columnA * columnB. In that scenario, the output of my code would be 2 away from the *expected* output, which I found through the previously mentioned... and wrong... calculation. – Jonas McClure May 03 '18 at 13:51