changing arrays

hello,
I'm trying to figure out a problem I'm having. The original code would hold the original price and the increased price in the array. He wants us to change the code to receive the original price(can no longer be stored in array), receive the increase in price, find the difference of the price change and store only the price change in the array. we cannot store the new price. He doesn't want the display to change just the inner workings of the functions. I have tried this for a few days then went to get help from him. The way he worked through it with me was to store the price from the set function (I was able to do this), then he went through how i should handle the array(priceHistory) and original price. That the way i should be looking at it is to subtract the first increase from the original and store that. then when i need to find the previous price is to add the array(that holds to difference in price) to the original number. I should subtract it from the newPrice coming in and once again storing the difference in the array. I hope I explained it well enough, but once again the constraints are to store the original price but not in the array, cannot store the new price, store only the change in price from the previous price. example he helped me with:
Product prod (-,5.0,-)told me not to worry about 1st and 3rd argument
prod setPrice(5.5)
prod setPrice(5.25)
prod setPrice(6.0)
prod setPrice(5.25)
Original price is 5.0
history(array)
5.0 - 5.5 = 0.5 5.0 + .5 - 5.25 = -.25 5.0 + .5 + (-.25) - 6.0 = .75
0.5 | -.25 | .75

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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
  *main.cpp
 * Name: Jason Glenn
 * Product Project
 * Course: CSI218 (Spring 2019)
 * Lecture: Tools for Data Structures
 * Date: January 29, 2019
 * Description: Using class to represent products (now
 *				with a price history for each).
 */

#include <iostream>
#include "product.h"
using namespace std;
using namespace Store;

void increasePrice(Product incrProds[], int numProds, double amt);

int main()
{
	const int NUM_PRODUCTS = 5;
	string ids[NUM_PRODUCTS] = {  // Ids for new candy bars
		"12-567-01",
		"12-567-02",
		"12-567-03",
		"12-567-04",
		"12-567-05"
	};
	// Declare array of objects (class type Product).
	Product products[NUM_PRODUCTS];

	// Add a set of candy bars (all same price).
	for (int i = 0; i < NUM_PRODUCTS; i++)
	{	//changing .99 to 5.0 for test
		products[i].set(ids[i], 5.0, false);
	
	}
	

	 
	// Increase prices by $1.
	increasePrice(products, NUM_PRODUCTS, 1.00);

	// Output info for each.
	cout << "Candy bars:" << endl << endl;

	for (int i = 0; i < NUM_PRODUCTS; i++)
	{
		products[i].output();
		cout << endl << endl;
	}

	return 0;
}

void increasePrice(Product incrProds[], int numProds, double amt)
{
	for (int i = 0; i < numProds; i++)
	{
		// Increase price by given amount.
		incrProds[i].setPrice(incrProds[i].getPrice() + (amt + i) );
	}
}


/*product.cpp
 * Name: Jason Glenn
 * Product Member Function Definitions
 * Course: CSI218 (Spring 2019)
 * Lecture: Tools for Data Structures
 * Date: January 29, 2019
 * Description: Product member function definitions.
 */

#include <iostream>
#include <iomanip>  // for setprecision()
#include "product.h"
using namespace std;

namespace Store
{
	// Product member function definitions.

	// Constructors

	Product::Product()  // default constructor
	{
		clearHistory();
		id = "00-000-00";
		price = 0.00;
		taxable = false;
	}

	Product::Product(const string &newId,
					 double newPrice,
					 bool newTaxable)
	{
		// Clear history first, since set() will
		// store the initial price (newPrice) in
		// history.
		clearHistory();

		// Call member function "set" to initialize
		// data members.  Price will be checked for
		// validity.
		set(newId, newPrice, newTaxable);
	}

	// Accessors

	const string Product::getId() const
	{
		return id;
	}

	double Product::getPrice() const
	{
		return price;
	}

	void Product::output() const
	{
		cout << "Id: " << id << endl
			<< "Price: $"
			<< fixed << setprecision(2)
			<< originalPrice;
	
		// Also output price history.
		cout << " (";
		outputHistory();
		cout << ")" << endl;

		if (taxable)
			cout << "Taxable";
		else
			cout << "Non-taxable";
	}

	// Precondition: taxRate must be non-negative and represented
	// as a decimal (e.g., 0.05 for 5%).
	// Postcondition: Returns amount of tax based on price of
	// product and given taxRate.
	double Product::computeTax(double taxRate) const
	{
		if (taxable)
			return price * taxRate;
		else
			return 0.0;
	}

	// Mutators

	// Precondition: newPrice must be a non-negative number.
	void Product::set(const string &newId,
					  double newPrice,
					  bool newTaxable)
	{
		//bool isTrue = false;

		if (setPrice(newPrice)) {
			originalPrice = newPrice;
		}  // Store price and check whether valid

		id = newId;
		taxable = newTaxable;

		//this will allow for the original number to be saved but not in history
		clearHistory();
	}

	// Precondition: newPrice must be a non-negative number.
	bool Product::setPrice(double newPrice)
	{
		int stopValue = 0;
		//price = newPrice;
		
		if (newPrice < 0.0)
			cerr << "Product price should be non-negative." << endl;



		// WRITE LOOP TO FIND PLACE FOR ADDITIONAL PRICE
		// IN HISTORY (IF ANY) AND STORE PRICE.
		for (int i = 0; i < MAX_HISTORY; i++)
		{
			
			
			//see's if the element is 0, if 0 then the price change will be placed
			
				if (priceHistory[i] == 0)
				{
					//add original to all elements of the array
					while (stopValue <= MAX_HISTORY)
					{
						price = originalPrice + priceHistory[stopValue];
						stopValue++;
					}

					// subtract that from newPrice
					// difference is put into priceHistory
					priceHistory[i] = price - newPrice;
					

					//priceHistory[i] = newPrice - priceHistory[i];

					
					break;
				}
			
				//reset storValue and price
				stopValue = 0;
				price = 0;
		}
		return true;
	}
	

	// Helper functions.

	// Clear price history (value zero signals unused entries).
	void Product::clearHistory()
	{
		for (int i = 0; i < MAX_HISTORY; i++)
			 priceHistory[i] = 0.0;
	}

	// Output price history (only non-zero values will
	// be displayed).
	void Product::outputHistory() const
	{
		cout << "History:";

		for (int i = 0; i < MAX_HISTORY; i++)
			if (priceHistory[i] != 0.0)
				cout << " " << priceHistory[i];
	}
}


/*product.h
 * Name: Jason Glenn
 * Product Class Definition
 * Course: CSI218 (Spring 2019)
 * Lecture: Tools for Data Structures
 * Date: January 29, 2019
 * Description: Product class definition declaring
 *				data members and member functions.
 */

#ifndef PRODUCT_H
#define PRODUCT_H

#include <string>
// See https://stackoverflow.com/questions/5849457/using-namespace-in-c-headers
using namespace std;

namespace Store
{
	// Product class definition with data members and
	// prototypes for member functions.

	class Product
	{
	public:
		// Constructors
		Product();  // default constructor (no parameters)
		Product(const string &newId,
				double newPrice,
				bool newTaxable);

		// Accessors
		const string getId() const;
		double getPrice() const;

		void output() const;

		double computeTax(double taxRate) const;
		// Precondition: taxRate must be non-negative and represented
		// as a decimal (e.g., 0.05 for 5%).
		// Postcondition: Returns amount of tax based on price of
		// product and given taxRate.

		// Mutators
		void set(const string &newId,
				 double newPrice,
				 bool newTaxable);
		// Precondition: newPrice must be a non-negative number.

		// Set only price.
		bool setPrice(double newPrice);
		// Precondition: newPrice must be a non-negative number.

	private:
		string id;
		double price;
		bool taxable;
		double differenceInPrice;
		double originalPrice = 0.0;

		static const int MAX_HISTORY = 5;
		double priceHistory[MAX_HISTORY];

		// Helper functions to deal with price history.
		void clearHistory();
		void outputHistory() const;
	};
}

#endif 
Last edited on
JayGln,

I'm not quite sure if I understood the requirements of your assignment 100% correctly, but I will take a stab at it and if I make any wrong assumptions, please let me know

Your new code has to only keep track of the original price and change history, so your member variables of the Product class would have to look something like below code? Also, I'm assuming that user can setPrice only 5 time max since you only keep up to 5 history changes?
1
2
3
4
5
6
7
private:
    string id;
    bool taxable;
    double originalPrice;

    static const int MAX_HISTORY = 5;
    double priceHistory[MAX_HISTORY];


If user wants original price, you can simply return originalPrice as shown below
1
2
3
double getOriginalPrice() {
    return originalPrice;
}


If user wants the current price (price including all previous changes), you would need to iterate priceHistory and add each difference to the original price. It would look something like below.
1
2
3
4
5
6
7
double getCurrentPrice() {
    double result = originalPrice;
    for(int i = 0; i < MAX_HISTORY; i++) {
        result += priceHistory[i];   // Assuming all elements in priceHistory are initialized to 0
    }
    return result;
}


If user calls the setPrice function, you would have to calculate the currentPrice, find the difference between the newPrice and the currentPrice and then store the difference at the next available index as long as the history count is less than 5.
1
2
double difference = newPrice - getCurrentPrice();
// Logic to back-insert this difference to priceHistory 


If user wants price at a specific change history (i.e. Price after 3rd change), then you would need to do this.
1
2
3
4
5
6
7
8
9
10
11
12
13
double getChangedPriceAt(int index) {
    // Logic to check if the index is less than 5 and greater than or equal to 0

    // index = 0 : get price after 1st change
    // index = 1 : get price after 2nd change
    // ....
    // index = 4 : get price after 5th change

    double result = originalPrice;
    for(int i = 0; i < index + 1; i++) {
        originalPrice += priceHistory[i];
    }
}


Here is a suggestion:
You may want to keep another integer member variable to keep track of how many price changes have been made so far. You have the max limit set to 5, but you have no way of knowing how many changes have been made unless you loop priceHistory. Better yet, utilize dynamic array such as std::vector.

1
2
3
static const int MAX_HISTORY = 5;
int historyCount = 0;    // Gets incremented every time setPrice() is invoked
double priceHistory[MAX_HISTORY]


1
2
std:vector<double> priceHistory; // Dynamically grows as more elements are added.
// You know exactly how many elements this container has by calling priceHistory.size() 

Hope this helps.
Last edited on
mpark4656,

Yes Thank you! I actually was going over it earlier at lunch while trying to remember the constraints. I realized that like the way you did the getCurrentPrice(), is the way that i should do it as well. I don't know if we can't write a new function, so i was thinking of doing a for loop to do the same operation as your function. I know he didn't want us to keep and store the price the newest price. I am going to ask tomorrow if I can make new functions,if so I like the way you did yours. I hope he allows for more modifications and creativity to be graded , I was thinking about making the setPrice() & the priceIncrease() use a random number so I can show price changes that could be a loss or gain in price changes. Do you think it would be better to use rand or srand? I thought I read that srand is better to use since it is based of the timing of the computer? Thank you for all your help!!!!
JayGln,

I believe srand() is used to set the seed (Look at it as a "starting point", but if you want complete information on seed and all of its inner workings, you need to research it.) and rand() is used to actually generate a random number. Often, you will see people using the time() function to set the seed in the parameter of srand().

So it's not a question of which one to use. You probably want to use both.

But don't just take my word for it. Try doing some research on these two functions and look at their usage. That should give you an idea of how to use srand() and rand().

Here are some references to get you started.
http://www.cplusplus.com/reference/cstdlib/srand/
http://www.cplusplus.com/reference/cstdlib/rand/
Last edited on
srand sets the "stream" by setting the seed. <random> works this way also. If you reset the seed back to what it was, you get the same random values, eg
srand(10);
for(i = 0; i < 5; i++)
cout << rand() << endl;
srand(10);
for(i = 0; i < 5; i++)
cout << rand() << endl;

prints the same 5 values twice. It is very handy to know the sequence ahead of time for some algorithms and for debugging. If you want the stream randomized, you can do that by using a seed from your system (time, cpu clocks, etc).

prefer to use the <random> instead of C's tools which are not as powerful nor as random. It is a little more complex to set up but any reference on the tool will have a tiny sample that will get you going with a copy/paste.
Last edited on
Topic archived. No new replies allowed.