Thread: Any tips on my program?

  1. #1
    Registered User
    Join Date
    Sep 2018
    Posts
    217

    Any tips on my program?

    For example I wasn't sure whether to use an array or vectors for keeping track of invalid_attempts and incorrect_attempts.

    The program is basically to generate nCr (combinations formula) questions, ask user for answer and verify the answer.

    The program currently keeps track of invalid attempts and incorrect attempts but it would support time spent to answer a question as well, in the future.

    You can specify ranges for question, n and r.

    Additional questions:
    Is it possible to declare an array with a variable as index declared value?
    eg:
    Code:
    int a = 10;
    int b[a];
    here b must be allotted 10 spaces.

    I take it that you cannot increase the size of an array after it has been declared.

    Also what can I use to manipulate the text on the console window and the console window itself? Is there anything like graphics.h in modern c++17 compilers (I use microsoft visual 2017) or would I have to use a library?

    If so what library must I use? I know GUI would be the way to go but console programming is so much simpler and I just write programs for myself that help me practice my math and etc.

    Otherwise what's a good GUI library?
    code:
    Code:
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    #include <vector>
    
    int random(int n, int m) {
        return rand() % (m - n + 1) + n;
    }
    
    unsigned long long int factorial(unsigned int input) {
        unsigned long long int factorial = 1;
        for (unsigned int i = 1; i <= input; ++i) 
            factorial *= i;
        return factorial;
    }
    
    int main() {
        srand(time(NULL));
    
        bool validator = false;
        unsigned int inputted_n;
        unsigned int inputted_r;
        unsigned int no_of_questions;
    
        validator = true;
        while (validator) {
            system("cls");
            std::cout << "How many questions would you like to answer?: ";
            std::cin >> no_of_questions;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore();
            }
            else if (no_of_questions == 0) {
                std::cout << "Great, you're done answering 0 questions! What now?";
                Sleep(1000);
                std::cin.get();
            }
            else
                validator = false;
        }
    
        validator = true;
        while (validator) {
            system("cls");
            std::cout << "Range for n: ";
            std::cin >> inputted_n;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore();
            }
            else if(inputted_n>19) {
                std::cout << "n does not support value greater than 19 currently.. due to loss of precision";
                Sleep(1000);
                std::cin.get();
            }
            else
                validator = false;
        }
    
        validator = true;
        while (validator) {
            system("cls");
            std::cout << "Range for n: " << inputted_n;
            std::cout << "\nRange for r: ";
            std::cin >> inputted_r;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore();
            }
            else if (inputted_r > inputted_n) {
                std::cout << "r cannot be greated than n!";
                Sleep(1000);
                std::cin.get();
            }
            else
                validator = false;
        }
    
        bool run_time = true;
        unsigned int iteration = 0;
        unsigned int answer, taken_answer, no_of_regular_questions = 0, no_of_easy_questions = 0, is_correct = 0;
        std::vector <int> invalid_attempts, incorrect_attempts;
    
        while (run_time) {
    
            iteration++;
            if (iteration > no_of_questions) {
                run_time = false;
                break;
            }
    
            invalid_attempts.push_back(0);
            incorrect_attempts.push_back(0);
    
            int n = random(1, inputted_n);
            int r = random(0, inputted_r);
    
            while (r > n)
                r = random(0, inputted_r);
    
            answer = (factorial(n)) / (factorial(r)*factorial(n - r));
    
            validator = true;
            while (validator) {
                system("cls");
                std::cout << iteration << ") Find nCr if n = " << n << ", r = " << r << "\nAnswer(";
                if (is_correct == 1)
                    std::cout << "CORRECT";
                else if (is_correct == 2)
                    std::cout << "INCORRECT";
                else if (is_correct == 3)
                    std::cout << "INVALID";
                std::cout<<"): ";
                std::cin >> taken_answer;
                if (!std::cin) {
                    std::cin.clear();
                    std::cin.ignore();
                    is_correct = 3;
                    invalid_attempts[iteration-1]++;
                }
                else if (taken_answer == answer) {
                    validator = false;
                    is_correct = 1;
                }
                else {
                    is_correct = 2;
                    incorrect_attempts[iteration-1]++;
                }
            }
    
            if (r == 0 || r == 1 || r == n)
                no_of_easy_questions++;
            else
                no_of_regular_questions++;
        }
        
        system("cls");
        std::cout << "You've answered " << no_of_questions << " question";
            if (no_of_questions > 1)
                std::cout << "s";
        std::cout<<". Of which " << no_of_easy_questions << " of them"; 
        if (no_of_easy_questions == 1)
            std::cout << "is";
        else
            std::cout << "are";
        std::cout<<" considered as \"easy\"";
    
        std::cout << "\n\nPerformance Summary:\n\n";
        for (unsigned int i = 0; i < no_of_questions; i++) {
            std::cout << "Question (<" << i << ">):  Failed Attempts = (";
            if (incorrect_attempts[i] == 0)
                std::cout << "ZER0!";
            else
                std::cout << incorrect_attempts[i];
            std::cout << "),  Invalid Attempts = (";
            if (invalid_attempts[i] == 0)
                std::cout << "ZER0";
            else
                std::cout << invalid_attempts[i];
            std::cout << "),  \n\tQuestion was answered in NOT IMPLEMENTED seconds\n\n";
        }
    
        std::cin.get();
        std::cin.get();
        std::cin.get();
    
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Jun 2017
    Posts
    157
    A few hints:
    Code:
    unsigned long long int
    use uint64_t instead => include <cstdint>

    int a = 10;int b[a];
    Not valid in C++
    Better use std::vector

    Also what can I use to manipulate the text on the console window and the console window itself?
    Console Functions - Windows Console | Microsoft Docs

  3. #3
    Registered User
    Join Date
    Sep 2018
    Posts
    217
    Quote Originally Posted by OldGuy2 View Post
    A few hints:
    Code:
    unsigned long long int
    use uint64_t instead => include <cstdint>


    Not valid in C++
    Better use std::vector


    Console Functions - Windows Console | Microsoft Docs
    for uint64_t it seems I did not have to include <cstdint>? Also is there any specific reason this is used over unsigned long long int or is it just that it's better?

    I'm still not that familiar with using WinApi functions.. but also is it possible to change the font size of text on console while simultaneously having other text with different size? Or there's no way other than to have all the text to be of the same font size?

    Thanks a lot.



    It seems I cannot edit my old post..? Also are there no "spoilers" in this forum? They would be helpful.

    Anyways I replaced the datatype like suggested, replaced "using namespace std::" by writing std:: wherever applicable (I still donno why tho lol but it seems to make a lot of people angry) and added support for recording time taken to get the answer right.

    Is there a better way to do this:
    Code:
          duration_of_attempts[iteration-1] = (std::clock() - start) / (double)CLOCKS_PER_SEC; 
    /* I'm talking about the line below over here: */
             duration_of_attempts[iteration-1] =  trunc(duration_of_attempts[iteration-1]) +  (round((duration_of_attempts[iteration-1] -  trunc(duration_of_attempts[iteration-1])) * 10) / 10);
    --> The idea of this is to round off decimal up to 1decimal place. I.e if we have 4.232 it would be rounded off to 4.2 and if we had 4.262 it would be rounded off to 4.3

    Code (to anybody interested):
    Code:
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    #include <vector>
    
    int random(int n, int m) {
        return rand() % (m - n + 1) + n;
    }
    
    uint64_t factorial(unsigned int input) {
        uint64_t factorial = 1;
        for (unsigned int i = 1; i <= input; ++i) 
            factorial *= i;
        return factorial;
    }
    
    int main() {
        srand(time(NULL));
        std::clock_t start;
    
        bool validator = false;
        unsigned int inputted_n;
        unsigned int inputted_r;
        unsigned int no_of_questions;
    
        validator = true;
        while (validator) {
            system("cls");
            std::cout << "How many questions would you like to answer?: ";
            std::cin >> no_of_questions;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore();
            }
            else if (no_of_questions == 0) {
                std::cout << "Great, you're done answering 0 questions! What now?";
                Sleep(1000);
                std::cin.get();
            }
            else
                validator = false;
        }
    
        validator = true;
        while (validator) {
            system("cls");
            std::cout << "Range for n: ";
            std::cin >> inputted_n;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore();
            }
            else if(inputted_n>19) {
                std::cout << "n does not support value greater than 19 currently.. due to loss of precision";
                Sleep(1000);
                std::cin.get();
            }
            else
                validator = false;
        }
    
        validator = true;
        while (validator) {
            system("cls");
            std::cout << "Range for n: " << inputted_n;
            std::cout << "\nRange for r: ";
            std::cin >> inputted_r;
            if (!std::cin) {
                std::cin.clear();
                std::cin.ignore();
            }
            else if (inputted_r > inputted_n) {
                std::cout << "r cannot be greated than n!";
                Sleep(1000);
                std::cin.get();
            }
            else
                validator = false;
        }
    
        bool run_time = true;
        unsigned int iteration = 0;
        unsigned int answer, taken_answer, no_of_regular_questions = 0, no_of_easy_questions = 0, is_correct = 0;
        std::vector <unsigned int> invalid_attempts, incorrect_attempts;
        std::vector <double> duration_of_attempts;
    
        while (run_time) {
    
            iteration++;
            if (iteration > no_of_questions) {
                run_time = false;
                break;
            }
    
            invalid_attempts.push_back(0);
            incorrect_attempts.push_back(0);
            duration_of_attempts.push_back(0);
    
            int n = random(1, inputted_n);
            int r = random(0, inputted_r);
    
            while (r > n)
                r = random(0, inputted_r);
    
            answer = (factorial(n)) / (factorial(r)*factorial(n - r));
    
            start = std::clock();
            validator = true;
            while (validator) {
                system("cls");
                std::cout << iteration << ") Find nCr if n = " << n << ", r = " << r << "\nAnswer(";
                if (is_correct == 1)
                    std::cout << "CORRECT";
                else if (is_correct == 2)
                    std::cout << "INCORRECT";
                else if (is_correct == 3)
                    std::cout << "INVALID";
                std::cout<<"): ";
                std::cin >> taken_answer;
                if (!std::cin) {
                    std::cin.clear();
                    std::cin.ignore();
                    is_correct = 3;
                    invalid_attempts[iteration-1]++;
                }
                else if (taken_answer == answer) {
                    validator = false;
                    is_correct = 1;
                }
                else {
                    is_correct = 2;
                    incorrect_attempts[iteration-1]++;
                }
            }
            duration_of_attempts[iteration-1] = (std::clock() - start) / (double)CLOCKS_PER_SEC;
            duration_of_attempts[iteration-1] = trunc(duration_of_attempts[iteration-1]) + (round((duration_of_attempts[iteration-1] - trunc(duration_of_attempts[iteration-1])) * 10) / 10);
    
            if (r == 0 || r == 1 || r == n)
                no_of_easy_questions++;
            else
                no_of_regular_questions++;
        }
        
        system("cls");
        std::cout << "You've answered " << no_of_questions << " question";
            if (no_of_questions > 1)
                std::cout << "s";
        std::cout<<". Of which " << no_of_easy_questions << " of them"; 
        if (no_of_easy_questions == 1)
            std::cout << "is";
        else
            std::cout << "are";
        std::cout<<" considered as \"easy\"";
    
        std::cout << "\n\nPerformance Summary:\n\n";
        for (unsigned int i = 0; i < no_of_questions; i++) {
            std::cout << "Question (<" << i << ">):  Failed Attempts = (";
            if (incorrect_attempts[i] == 0)
                std::cout << "ZER0!";
            else
                std::cout << incorrect_attempts[i];
            std::cout << "),  Invalid Attempts = (";
            if (invalid_attempts[i] == 0)
                std::cout << "ZER0!";
            else
                std::cout << invalid_attempts[i];
            std::cout << "),  \n\tQuestion was answered in "<<duration_of_attempts[i]<<" seconds\n\n";
        }
    
        std::cin.get();
        std::cin.get();
        std::cin.get();
    
        return 0;
    }
    For some reason I did not even need math.h header file nor <cstdint> (cstdint as suggested).. is that normal?
    I only needed these headers:
    #include <iostream>
    #include <ctime>
    #include <Windows.h>
    #include <vector>
    Last edited by Nwb; 10-06-2018 at 01:58 AM.

  4. #4
    Registered User
    Join Date
    Jun 2017
    Posts
    157
    Also is there any specific reason this is used over unsigned long long int or is it just that it's better?
    When using uint64_t you know that it is an unsigned 64 bit type.
    What is unsigned long long int ? You can't answer it in general the size depends on the compiler and the architecturre 32/64 bit ot sth. else
    As a nice side effect it saves typing as well.

    With headers it considered best practice to include what you need - like <cstdint>.
    Maybe they have been included by some library headers but you can't be sure.

    but also is it possible to change the font size of text on console while simultaneously having other text with different size? Or there's no way other than to have all the text to be of the same font size?
    I have not tried it, but it might be possible with a library.
    GitHub - wmcbrine/PDCurses: Public Domain Curses - a curses library for environments that don&#39;t fit the termcap/terminfo model.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    On a further note, your main() needs to be split into many more functions.

    100's of lines of code in a single function is seldom a good idea.
    All your while (validator) loops should for example be separate functions to return a validated result.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Sep 2018
    Posts
    217
    Quote Originally Posted by Salem View Post
    On a further note, your main() needs to be split into many more functions.

    100's of lines of code in a single function is seldom a good idea.
    All your while (validator) loops should for example be separate functions to return a validated result.
    But the validator loops have different inputs and different clauses..
    I'll have to figure out split my main function into functions. Thanks.


    Is there a better way to round a decimal like 4.3242 to 4.3 and a decimal like 4.3842 to 4.3? (round() returns purely decimal number and I believe it does not support round till decimal place).
    Last edited by Nwb; 10-06-2018 at 07:51 AM.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > But the validator loops have different inputs and different clauses..
    True, to a point.

    When you think you need to do some copy/pasting, what you should be thinking about are
    1. The block you copied needs to be a function.
    2. The variables you tweak when you paste it become parameters to the function you create.


    > Is there a better way to round a decimal like 4.3242 to 4.3 and a decimal like 4.3842 to 4.3?
    You normally have to do this as a string.

    All floats are approximations.
    4.3 is not representable, you end up with either 4.29<recurring><digits> (say 4.299999713897705078125) or 4.30<recurring><digits> (say 4.30000019073486328125)
    IEEE-754 Floating Point Converter
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Logic error in larger program, troubleshoot tips/help
    By Glassjaw in forum C Programming
    Replies: 4
    Last Post: 12-05-2015, 03:21 AM
  2. tips on making my program faster?
    By jackhasf in forum C Programming
    Replies: 4
    Last Post: 10-25-2009, 06:32 AM
  3. First time GUI program tips and help needed.
    By naja77 in forum C Programming
    Replies: 1
    Last Post: 08-01-2008, 08:28 AM
  4. Tips
    By laughman in forum C++ Programming
    Replies: 5
    Last Post: 10-01-2002, 11:48 AM
  5. Help!! Tips on Matrix Calculator Program please!
    By skanxalot in forum C++ Programming
    Replies: 12
    Last Post: 03-11-2002, 11:26 AM

Tags for this Thread