Starting from:

$30

CS31- Project 3: Grocery Cart Options Solved

Introduction
In response to the emergence of the novel coronavirus, grocery stores have become very creative in enabling their customers to acquire groceries in many different ways that reduce potential virus exposure.  For example, the Ralph's where I shop supports the following ways to fulfill grocery store orders:

 

 

For this assignment, suppose that a sensor is recording grocery store order fulfillments at the sliding doors as they leave the store.  For example, 

    1P1D


would indicate that a single pickup and a single delivery order had been fulfilled.  From this information, note that the character P is being used to represent a pickup order, the character D is being used to represent a delivery order.  Similarly, the character S and I would represent shipped order and in-store order.  Additionally, lowercase letters p, d, s and i could also be used.  For example,

    5s10i

would indicate that five shipped orders and ten in-store orders had been fulfilled.  Additionally, no more than 20 pickup orders, no more than 10 delivery orders and no more than 99 total orders can be processed in one grocery store string.  For example, 


    20p10d99i

would not be valid because more than 99 total orders are represented in this one grocery store string.

 

Precisely, to be a valid grocery store order string, 

- digit(s) must be followed by an order type (p,d,s,i or P,D,S, I)
- leading extra zeros in the digit portion is not allowed
- only digit characters and the order type character are allowed.  No spaces or any other characters allowed
- no more than 20 pickup type orders are allowed in a single grocery order string
- no more than 10 delivery type orders are allowed in a single grocery order string
- no more than 99 total orders are allowed in a single grocery order string

All of the following are examples of valid grocery store order strings:

 

1p1d1s1i                            (a single pickup, single delivery, single shipped and single in-store order)
5d5p                                 (five delivery and five pickup orders)
1D1P4d4p                        (five delivery and five pickup orders)
 

All of the following are examples of invalid grocery order strings:

 

happyDays10                        (no characters allowed besides digits, p, P, d, D, s, S, i or I)
000001p                                (no leading zeros in the digit portion allowed)
+1p                                          (no + allowed)
1p1d   XYZ                             (string must be fully consumed to be valid)
50i50i50s                              (no more than 99 orders total)
10p10p10p1d1s1i                  (no more than 20 pickup orders allowed)
5d5d5d1p1s1i                     (no more than 10 delivery orders allowed)
Your task
For this project, you will implement the following five functions, using the exact function names, parameter types, and return types shown in this specification. (The parameter names may be different if you wish).

bool isWellFormedGroceryOrderString(string grocerystring)

This function returns true if its parameter is a well-formed grocery order string as described above, or  false otherwise.
int pickupCount(string grocerystring)
If the parameter is a well-formed grocery order string, this function should return the number of pickup type grocery orders after the string is fully processed.  If the parameter is not a valid grocery order string, return -1. 
 
int deliveryCount(string grocerystring)
If the parameter is a well-formed animal park grocery order string, this function should return the number of delivery type grocery orders after the string is fully processed.  If the parameter is not a valid grocery order string, return -1.   
 
int shipCount(string grocerystring)
If the parameter is a well-formed animal park grocery order string, this function should return the number of shipped type grocery orders after the string is fully processed.  If the parameter is not a valid grocery order string, return -1.  
int inpersonCount(string grocerystring)
If the parameter is a well-formed animal park grocery order string, this function should return the number of in-person type grocery orders after the string is fully processed.  If the parameter is not a valid grocery order string, return -1. 
These are the only five functions you are required to write. Your solution may use functions in addition to these five if you wish. While we won't test those additional functions separately, using them may help you structure your program more readably. Of course, to test them, you'll want to write a main routine that calls your functions. During the course of developing your solution, you might change that main routine many times. As long as your main routine compiles correctly when you turn in your solution, it doesn't matter what it does, since we will rename it to something harmless and never call it (because we will supply our own main routine to thoroughly test your functions).
 
Clearly, I am expecting the last four functions to invoke the first function as they complete their assigned task.  This code reuse is one of the major benefits of having functions.  So please do that.
 
Before you ask a question about this specification, see if it has already been addressed by the Project 3 FAQ. And read the FAQ before you turn in this project, to be sure you didn't misinterpret anything.  Be sure you also do the warmup exercises accompanying this project. 

 
Additionally, I have created a testing tool called CodeBoard to help you check your code.  CodeBoard enables you to be sure you are naming things correctly by running a small number of tests against your code.  Passing CodeBoard tests is not sufficient testing so please do additional testing yourself.  To access CodeBoard for Project 3, please click the link you see in this week named CodeBoard for Project 3.  Inside the file named user_functions.cpp, copy and paste your implementation of the assigned functions.  CodeBoard uses its own main( ) to run tests against your code.  Click Compile and Run.  However please be aware that no editing changes can be saved inside CodeBoard.  In this anonymous user configuration, CodeBoard is read-only and does not allow for saving changes.

Programming Guidelines
The functions you write must not use any global variables whose values may be changed during execution (so global constants  are allowed).

When you turn in your solution, neither of the four five required functions, nor any functions they call, may read any input from cin  or write any output to  cout. (Of course, during development, you may have them write whatever you like to help you debug.) If you want to print things out for debugging purposes, write to cerr  instead of cout. cerr  is the standard error destination; items written to it by default go to the screen. When we test your program, we will cause everything written to cerr  to be discarded instead — we will never see that output, so you may leave those debugging output statements in your program if you wish.

The correctness of your program must not depend on undefined program behavior. For example, you can assume nothing about  c 's value at the point indicated, nor even whether or not the program crashes:

    int main()
    {
        string s = "Hello";
        char c = s[5];   // c's value is undefined
        …

Be sure that your program builds successfully, and try to ensure that your functions do something reasonable for at least a few test cases. That way, you can get some partial credit for a solution that does not meet the entire specification.

There are a number of ways you might write your main routine to test your functions. One way is to interactively accept test strings:

int main()
    {
        string s;
           cout.setf( ios::boolalpha ); // prints bool values as "true" or "false"
for(;;) { cout << "Enter a possible grocery store string: "; getline(cin, s); if (s == "quit") break; cout << "isWellFormedGroceryOrderString returns ";  cout << isWellFormedGroceryOrderString(s) << endl; cout << "pickupCount(s) returns "; cout << pickupCount(s) << endl; cout << "deliveryCount(s) returns "; cout << deliveryCount(s) << endl; cout << "shipCount(s) returns "; cout << shipCount(s) << endl;  cout << "inpersonCount(s) returns "; cout << inpersonCount(s) << endl;  }
            return 0;
    }

While this is flexible, you run the risk of not being able to reproduce all your test cases if you make a change to your code and want to test that you didn't break anything that used to work.

Another way is to hard-code various tests and report which ones the program passes:

    int main()
    {
        if (!isWellFormedGroceryOrderString(""))
        cout << "Passed test 1: !isValidGroceryOrderString(\"\")" << endl;
        if (!isWellFormedGroceryOrderString("   "))
        cout << "Passed test 2: !isWellFormedGroceryOrderString(\"   \")" << endl;
        …

This can get rather tedious. Fortunately, the library has a facility to make this easier:  assert . If you #include the header <cassert> , you can call assert  in the following manner:

    assert(some boolean expression);

During execution, if the expression is true, nothing happens and execution continues normally; if it is false, a diagnostic message is written to cerr telling you the text and location of the failed assertion, and the program is terminated. As an example, here's a very incomplete set of tests:

    #include <cassert>
    #include <iostream>
    #include <string>
    using namespace std;

    …

    int main()
    {
        assert( isWelLFormedGroceryOrderString("") == false );
        assert( isWellFormedGroceryOrderString("    ") == false );
            assert( shipCount( "    " ) == -1 );
            assert( deliveryCount( "      " ) == -1 );
            assert( inpersonCount( "      " ) == -1 );
            assert( pickupCount( "       " ) == -1 );
            assert( isWellFormedGroceryOrderString( "1s1d1i1p1S1D1I1P" ) == true );
            assert( shipCount( "1s1d1i1p1S1D1I1P" ) == 2 );
            assert( deliveryCount( "1s1d1i1p1S1D1I1P" ) == 2 );
            assert( inpersonCount( "1s1d1i1p1S1D1I1P" ) == 2 );
            assert( pickupCount( "1s1d1i1p1S1D1I1P" ) == 2 );
        …
        cerr << "All tests succeeded" << endl;
            return 0;
    }

The reason for writing one line of output at the end is to ensure that you can distinguish the situation of all tests succeeding from the case where one function you're testing silently crashes the program.

What to turn in
What you will turn in for this assignment is a zip file containing these two files and nothing more:

A text file named grocery.cpp  that contains the source code for your C++ program. Your source code should have helpful comments that tell the purpose of the major program segments and explain any tricky code. The file must be a complete C++ program that can be built and run, so it must contain appropriate #include lines, a main routine, and any additional functions you may have chosen to write.
A file named report.doc or report.docx (in Microsoft Word format) or report.txt (an ordinary text file) that contains in addition your name and your UCLA Id Number:A brief description of notable obstacles you overcame.
A description of the design of your program. You should use  pseudocode in this description where it clarifies the presentation.
A list of the test data that could be used to thoroughly test your program, along with the reason for each test. You don't have to include the results of the tests, but you must note which test cases your program does not handle correctly. (This could happen if you didn't have time to write a complete solution, or if you ran out of time while still debugging a supposedly complete solution.)
By July 15th, there will be a link on the class webpage that will enable you to turn in your zip file electronically. Turn in the file by the due time above. Give yourself enough time to be sure you can turn something in, because we will not accept excuses like "My network connection at home was down, and I didn't have a way to copy my files and bring them to a SEASnet machine." There's a lot to be said for turning in a preliminary version of your program and report early (You can always overwrite it with a later submission). That way you have something submitted in case there's a problem later. Notice that most of the test data portion of your report can be written from the requirements in this specification, before you even start designing your program.

 

G31 Build Commands
    g31 -c grocery.cpp
        g31 grocery.o -o runnable
        ./runnable

More products