Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

1. Check all that apply. A. Since Ying's loop pointer, p , is type Base , no compiler error will occur. B. Ying can call

1. Check all that apply.

A.

Since Ying's loop pointer, p, is type Base, no compiler error will occur.

B.

Ying can call p->func() on each object in the loop and get distinct behavior as defined by the object pointed to.

C.

Ying can call p->func() on each object in the loop and force only base class behavior of that method by using type coercion.

D.

Ying can call p->func() on each object in the loop (no coercion) and will always get the Base behavior of this function.

2.

Multiple Inheritance

Consider a derived class B that is multiply inherited from base classes A1 and A2. Which would be a reasonable example of classes A1, A2 and B. (There may be more than one correct answer.)

A.

A1 is a person who has some degree in math: DegreeHolderInMath

A2 is a person who has some degree in computer science: DegreeHolderInCS

B is DegreeHolderInBothMathAndComputerScience

B.

A1 is an Insect (animal without a backbone, body in three sections, skeleton on the outside, usually give birth as eggs)

A2 is a Mammal (animal with backbone, has hair/fur, usually give birth alive)

B is an Animal (any living being on Earth which is neither a plant (vegetable) nor fungus)

C.

A1 is a RealEstateProperty

A2 is an ItemForSale

B is a RealEstatePropertyForSale

D.

A1 is a Condominium (One unit in a condo development in which a family might own and reside)

A2 is a SingleFamilyDwelling (One house+land in which a family might own and reside)

B is a ResidentialProperty (House+land, condo unit, townhome, or any other place in which a family might own and reside)

E.

A1 is an Arm

A2 is a Leg

B is a HumanBody

3.

Select the derived class constructor definitions that represent actual constructor chaining (never mind the reason or effect, as long as it demonstrates a derived class constructor chaining to a base class constructor). There is more than one correct answer.

A.

SubClass::SubClass(int a) : BaseClass()

{

// other stuff

}

B.

SubClass::SubClass() : BaseClass(4)

{

// other stuff

}

C.

SubClass::SubClass(int a)

{

BaseClass(a);

// other stuff

}

D.

SubClass::SubClass(int a)

{

BaseClass::BaseClass(a);

// other stuff

}

E.

SubClass::SubClass(int a) : BaseClass(a)

{

// other stuff

4.

Consider the boolean expression (where XOR is the exclusive-or operator defined in the modules or throughout the internet):

(P OR Q) XOR (P AND Q)

Match the inputs P and Q with the output that this expression produces (assume 0 = false and 1 = true).

Choices - use a choice only once

A.

P = 1, Q = 0

B.

P = 1, Q = 1

Match each of the following to a choice

1.

1

Select

A.

P = 1, Q = 0

B.

P = 1, Q = 1

2.

0

Select

A.

P = 1, Q = 0

B.

P = 1, Q = 1

5.

The is a sum-the-data-in-the-tree question. It asks whether a method, sumAll() is a well-written recursive method. You will see three different versions of this question throughout the exam, but the opening assumptions, are identical for all such versions. The only difference between the various questions is the code that implements the method sumAll().

Assumptions:

The general tree in this problem is assumed to be physical, i.e., there is no lazy or soft deletion designed into this tree.

We are considering a recursive work-horse method to sum all the (assumed) integer data of the sub-tree.

The sub-tree is specified by the root pointer passed in. As usual, some client would pass a root to this method, then this recursive method would generate other (child or sibling) roots to pass to itself when recursing.

The members sib and firstChild have the same meanings as in our modules.

True of False:

The method, as defined below, is a good recursive method for summing the data of the sub-tree, based at the root node passed in.

To be true, it must satisfy all the following criteria. If it misses one, it is false:

It gives the right sum for the sub-tree, that is, it does not miss counting any data.

it does no unnecessary work, micro-management or superfluous testing.

It covers all situations (empty trees, NULL roots, handles all the children, etc.).

int TreeClass::sumAll(Node *root)

{

int sibSum, thisSum, childrenSum;

FHsdTreeNode *child;

if (root == NULL)

return 0;

// set to 0 for next computations

sibSum = childrenSum = 0;

if (root->sib == NULL)

sibSum = sumAll(root->sib);

for ( child = root->firstChild; child != NULL; child = child->sib )

childrenSum += sumAll(child);

thisSum = root->data;

return childrenSum + sibSum + thisSum;

}

There are three true-false questions that start out the same in this exam, but each has a different method definition. You may want to come back and review your answer to this question after seeing the other method definitions. Only one of the three is true, and the other two are false.

True

False

TRUE OR FALSE

6.

It the client requests the removal of a single node in a general tree (a tree with no limit on the number of children per node) as we have studied it, this might result in many more nodes than the one requested to be removed (from the client's perspective).

While the answer will the same for normal and lazy deletion, you can assume this tree does normal, not lazy, deletion, to avoid unnecessary thinking time.

True

False

7.

Method overriding happens when ...

A.

... a derived class method of the same name as a method in the base class takes the same number and type of parameters as the base class method.

B.

... a derived class method of the same name as a method in the base class takes a different number or type of parameters as the base class method.

8.

A class MyClass is instantiated by some client main() dynamically, using some MyClass pointers local to main(). Check all that apply.

A.

If no deep memory is used in MyClass (i.e., it contains only simple data, no pointer members), then main() does not need to manually delete the objects that it dynamically allocates.

B.

It is possible that MyClass does not need any of the following: a user defined destructor, copy constructor or assignment operator.

C.

main()is responsible for deleting the two objects it instantiated, either directly or by calling some method that deletes them.

D.

The situation described means that MyClass will always need a user defined destructor, copy constructor and assignment operator.

E.

It is MyClass's instance methods that are responsible for deleting the two objects instantiated by main().

9.

Assume MyClass defines two nested exception classes, BadNumber and BadString. Also, assume that MyClass's method doSomething() throws these exceptions under certain error conditions, and returns without throwing anything when it decides no error has occurred. We call doSomething() four times in a try/catch block:

MyClass a;

try

{

a.doSomething();

a.doSomething();

a.doSomething();

a.doSomething();

}

catch (MyClass::BadNumber)

{

cout << " bad number " << endl;

}

catch (MyClass::BadString)

{

cout << " bad string " << endl;

}

catch (...)

{

cout << " just generally bad " << endl;

}

Check the true statements (there will be more than one correct answer).

[Ignore whether spaces or ' ' are displayed - it is the words of the cout statements that we are interested in.]

A.

It is possible that doSomething() will return without error in one or more of these invocations, yet we still have one or more of "bad number", "bad string" or "just generally bad" displayed on the screen after this block.

B.

It is possible none of "bad number", "bad string" or "just generally bad" is displayed on the screen after this block.

C.

It is possible that this block will be called without anything being displayed on the screen.

D.

It is possible neither "bad number" nor "bad string" is displayed on the screen after this block.

E.

It is possible both "bad number" and "bad string" is displayed on the screen after this block.

10.

C++ STL lists have which of the following properties?

(Check all that apply.)

A.

They do not have STL iterators associated with them.

B.

They enable us to insert new. randomly generated, items into the list in some pre-determined order, without having to supply our own client-designed logic or code.

C.

They are supplied to us as a template class, meaning we can declare, in one statement, a list of user-defined class data just as easily as if we were to define a list of some primitive type.

D.

They do not require that any ordering relation (like an operator<()) be defined for the underlying data type.

11.

MyClass has an internal 2-D array of dynamically allocated doubles, pointed to by the member named data:

class MyClass

{

private:

double **data;

int width, height;

// other stuff

}

Assume width and height are set by constructors and mutators, and the class deals with them and all other data management correctly. Here is the method we are interested in analyzing:

void MyClass::allocateDynArray(int newHeight, int newWidth)

{

int row;

if ( !valid( newHeight, newWidth ) )

return;

height = newHeight;

width = newWidth;

// delete and NULLs the data

deallocateDynArray();

data = new double*[height];

for ( row = 0; row < height; row++ )

data[row] = new double[width];

setArrayToAllZeros();

}

Check the true statements (there will be one and possible more):

A.

setArrayToAllZeros() needs parameters to know what bounds to use for its (likely) internal loops.

B.

A destructor is essential for this class.

C.

We have to set data = NULL before we do our error return near the top

D.

The invocation of deallocateDynArray() needs to be repositioned to a different place in the code in order to avoid a potential crash or memory leak.

E.

It's fine as is.

12.

A C++ stl vector (check all that apply) ...

A.

... is a type of pre-defined (in stl) template class.

B.

... is a type of container.

C.

...can be accessed using notation practically identical to (or identical to) a simple array.

D.

... is a type of constructor.

13.

If a base class pointer, p, points to a derived class instance, and both base and derived classes have a method void doIt() which takes no parameters, then p->doIt() will invoke the derived class version ...:

A.

... only if both the base class method and the derived class method are declared virtual.

B.

...if the derived class method is declared virtual, but the base is not declared virtual.

C.

... if the base class method is declared virtual, even if the derived class method is not declared virtual.

14.

Consider the boolean expression (where XOR is the exclusive-or operator defined in the modules or throughout the internet):

(P OR Q) XOR (P AND Q)

Check the (one) true statement.

A.

This expression is equivalent to the simpler expression

P AND Q

B.

This expression cannot be simplified to any of the options, above.

C.

This expression is equivalent to the simpler expression

P OR Q

D.

This expression is equivalent to the simpler expression

P XOR Q

15.

Lazy Deletion, as we have implemented it in a general tree, is good for ...

(Check all that apply.)

A.

... conserving memory.

B.

... fast removal.

C.

... fast insertion.

D.

... avoiding garbage collection for a small number of removal calls.

16.

Bob defines a base class, Base, with instance method func(), but does not declare it to be virtual.

Alicia (who has no access to Bob's source code) defines three derived classes, Der1, Der2 and Der3, of the base class and overrides func().

Ying has no access to Bob or Alicia's source code and does not know anything about the derived classes, including their names or how many derived classes exist. Ying does know about the Base class and knows about its public instance function func(). She is also aware that there may be derived classes that override func().

Ying uses a Base pointer, p, to loop through a list of Base object pointers. Ying is aware that the list pointers may point to Base objects or some subclass objects of Base.

Check all that apply.

A.

Since Ying's loop pointer, p, is type Base, no compiler error will occur.

B.

Ying can call p->func() on each object in the loop (no coercion) and will always get the Base behavior of this function.

C.

Ying can call p->func() on each object in the loop and get distinct behavior as defined by the object pointed to if she uses type coercion to assist her.

D.

Ying can call p->func() on each object in the loop and get no compiler error.

E.

Ying can call p->func() on each object in the loop and get distinct behavior as defined by the object pointed to.

17.

If a Boolean function does not have a simple algebraic or logical description then it is most easily implemented by a method that has which of the following?

A.

Several user input statements with appropriate prompts to the user.

B.

A statement that uses multiplication and division.

C.

A long if statement.

D.

A for loop.

E.

An array.

18.

Assume p is a private pointer member of class DeepClass that gets assigned dynamically allocated data in one or more of DeepClass's instance methods. p controls this dynamically allocated memory.

Check all that apply to the client statement myDeepB = myDeepA; between two DeepClass objects.

A.

The default assignment operator that C++ provides will result in a compiler error.

B.

The default assignment operator that C++ provides will cause both myDeepA's and myDeepB's "p-controlled" memory be to simultaneously modified if myDeepA's is used to modify its copy of that memory (say, immediately after the assignment statement).

C.

The default assignment operator that C++ provides will immediately crash the program when the assignment statement is encountered during run-time.

D.

If DeepClass has a user-defined destructor that deallocates p's memory, but no overloaded assignment operator is provided, then the assignment statement, followed immediately by both objects going out-of-scope (as in the program or method in which both objects are defined, ending), will cause a run-time err

E.

The default assignment operator that C++ provides will result the dynamically allocated memory to be duplicated and copied over to myDeepB.

19.

The following are advantages of a linked-list over an an array:

(Check all that apply.)

A.

Even if we don't have a pointer to the proper node, a linked-list can easily access any element in the middle of the list with a single statement, but an array requires a loop to gain access to that node.

B.

A linked-list takes less memory to store a single element (a Node in the list) than an array takes to store its version of a single element (the kth item in the array).

C.

Inserting an item into an already-ordered linked-list, so as to preserve the order, requires fewer loops and/or a shorter loop than inserting an item into an ordered array so as to preserve the order.

D.

Assuming we have a pointer to the proper node, a linked-list will enable fast insertion into the middle of the list, while insertion into the middle of an array, even if we know the int index of the desired insertion point, will not be as fast or simple.

20.

A Boolean function that has four inputs and one output. The programmer decides to implement it using an array of type bool. How many elements (what size array) gives the programmer the maximum flexibility in defining the function?

A.

3

B.

4

C.

16

D.

15

E.

8

21.

Overloading the assignment operator can be done so that obj = x; can be valid, even if x is in a different class than obj.

True

False

22.

If p is a pointer member of class DeepClass that gets assigned dynamically allocated data in one or more of DeepClass's instance methods then the memory to which p controls is considered to be technically "part of the DeepClass objects."

True

False

23.

Consider the following statement:

ifstream galSource("galaxyData.txt");

Check the true statements (there may be more than one):

A.

If the file is successfully opened, and it is a plain text file, then we would use the statement getLine(galSource, someStringVar); to read a line from it.

B.

It attempts to open a file named "galaxyData.txt" for reading/input.

C.

It attempts to open a file named "galaxyData.txt" for writing/output.

D.

If the file it wants to access has too restrictive permissions, as set by the file owner or administrator, then the variable galSource will be assigned the value = NULL (i.e., 0).

E.

It attempts to open a file named "galSource" for reading/input.

F.

If the file is successfully opened, and it is a plain text file, then we would use the statement getLine(cin, someStringVar); to read a line from it.

G.

If the file it wants to access is not in the executable path (usually the same director as the program), then the variable galSource will be assigned the value = -1.

24.

Match the concept with the phrase that best describes it.

Choices - use a choice only once

A.

A Linked List data structure

B.

Stack data Structure

C.

A Queue data structure

D.

A simple Array

Match each of the following to a choice

1.

... typically uses dynamic allocation and its size grows or shrinks as needed.

Select

A.

A Linked List data structure

B.

Stack data Structure

C.

A Queue data structure

D.

A simple Array

2.

... is first-in, first-out (FIFO)

Select

A.

A Linked List data structure

B.

Stack data Structure

C.

A Queue data structure

D.

A simple Array

3.

... uses push() and pop() methods to access the data.

Select

A.

A Linked List data structure

B.

Stack data Structure

C.

A Queue data structure

D.

A simple Array

4.

... allows fast random access to the data elements.

Select

A.

A Linked List data structure

B.

Stack data Structure

C.

A Queue data structure

D.

A simple Array

25.

The is a sum-the-data-in-the-tree question. It asks whether a method, sumAll() is a well-written recursive method. You will see three different versions of this question throughout the exam, but the opening assumptions, are identical for all such versions. The only difference between the various questions is the code that implements the method sumAll().

Assumptions:

The general tree in this problem is assumed to be physical, i.e., there is no lazy or soft deletion designed into this tree.

We are considering a recursive work-horse method to sum all the (assumed) integer data of the sub-tree.

The sub-tree is specified by the root pointer passed in. As usual, some client would pass a root to this method, then this recursive method would generate other (child or sibling) roots to pass to itself when recursing.

The members sib and firstChild have the same meanings as in our modules.

True of False:

The method, as defined below, is a good recursive method for summing the data of the sub-tree, based at the root node passed in.

To be true, it must satisfy all the following criteria. If it misses one, it is false:

It gives the right sum for the sub-tree, that is, it does not miss counting any data.

it does no unnecessary work, micro-management or superfluous testing.

It covers all situations (empty trees, NULL roots, handles all the children, etc.).

int TreeClass::sumAll(Node *root)

{

int sibSum, thisSum, childrenSum;

if (root == NULL)

return 0;

sibSum = sumAll(root->sib);

childrenSum = sumAll(root->firstChild);

thisSum = root->data;

return childrenSum + sibSum + thisSum;

}

HINT: There are three true-false questions that start out the same in this exam, but each has a different method definition. You may want to come back and review your answer to this question after seeing the other method definitions. Only one of the three is true,

and the other two are false.

True

False

26.

Assume p is a private pointer member of class DeepClass that gets assigned dynamically allocated data in one or more of DeepClass's instance methods. p controls this dynamically allocated memory. Check all that apply.

A.

A non-destructor instance method of DeepClass may not deallocate the memory that p controls.

B.

The memory that p controls will be deallocated when a DeepClass object goes out of scope if an appropriately written user-defined destructor is provided for DeepClass.

C.

The memory that p controls will be deallocated when a DeepClass object goes out of scope automatically by C++'s default destructor.

D.

Memory that p controls must be allocated at object construction.

E.

A user-defined destructor of DeepClass can deallocate the memory that p controls.

27,

Which describe a design in which B is a derived class of base class A? (Check all that apply.)

A.

Class A is Building that shelters people and equipment.

Class B is a HighRise, which has a minimum of five floors (stories) with stairs and elevators and utilized by government agencies, condo complexes and companies.

B.

Class A is an AutoPart which goes into a car or truck. It has a part number, weight and price.

Class B is a Automobile -- either a Car or a Truck.

C.

Class A is Building that shelters people and equipment.

Class B is a CityVisualizer which will render one or more Buildings in 3D on a computer or smart phone screen.

D.

Class A is an AutoPart which goes into a car or truck. It has a part number, weight and price.

Class B is a FuelInjector, a special kind of part that goes into cars and trucks.

28.

Assume that a class, Deep, has a pointer member

int *somePointer;

which will be assigned some dynamically allocated (deep/heap) memory during object construction (in the constructor).

Assume, further, that we have not overloaded the assignment operator for class Deep.

Two Deep objects, deepA and deepB are involved in an assignment statement:

deepB = deepA;

Check the true statements:

(There may be more than one.)

A.

deepB's somePointer will have its own copy of int memory associated with its somePointer member after the assignment statement (distinct from deepA's)

B.

deepB's somePointer will be undefined (unaffected) by this assignment statement.

C.

This is a shallow copy; deep memory controlled by deepA is not copied and pointed to by deepB.

D.

After this assignment, both deepA and deepB will have their respective somePointers pointing to the same exact memory.

29.

Check the true statement out of the two statements below (there is only one correct choice):

A.

Without type coercion being employed, a derived class pointer can only point to a derived class object, not a base class object.

B.

Without type coercion being employed, a base class pointer can only point to a base class object, not a derived class object.

30.

Which describe a design in which B is a derived class of base class A? (Check all that apply -- there may be one or more checked box.)

A.

Class A is an MensApparelItem, which is stocked and sold by a department store like Macy's.

Class B is an InventoryItem, something a business stocks and sells to a customer. It has an item number and price.

B.

Class A is an Sleeve, something that goes into a shirt, jacket or sweater.

Class B is a Jacket.

C.

Class A is an InventoryItem, something a business stocks and sells to a customer. It has an item number and price.

Class B is an MensApparelItem, which is stocked and sold by a department store like Macy's.

D.

Class A is a Jacket something that is worn to keep a person warm.

Class B is an JacketSleeve (something that goes into a Jacket).

31.

Match each data structure with its best description.

Choices - use a choice only once

A.

Data is both LIFO and FIFO: The are potentially two data items that could be naturally fetched (returned) to the client at any given moment, either the the item most recently stored or the oldest (earliest) item stored.

B.

Data is neither LIFO nor FIFO: Client can naturally fetch (return) any of the many data items stored.

C.

Data is a FIFO: There is only one data item that is naturally fetched (returned) to the client at any given moment, and it is the oldest (earliest) item stored.

D.

Data is a LIFO: There is only one data item that is naturally fetched (returned) to the client at any given moment, and it is the item most recently stored.

Match each of the following to a choice

1.

Queue

Select

A.

Data is both LIFO and FIFO: The are potentially two data items that could be naturally fetc...

B.

Data is neither LIFO nor FIFO: Client can naturally fetch (return) any of the many data ite...

C.

Data is a FIFO: There is only one data item that is naturally fetched (returned) to the cli...

D.

Data is a LIFO: There is only one data item that is naturally fetched (returned) to the cli...

2.

Stack

Select

A.

Data is both LIFO and FIFO: The are potentially two data items that could be naturally fetc...

B.

Data is neither LIFO nor FIFO: Client can naturally fetch (return) any of the many data ite...

C.

Data is a FIFO: There is only one data item that is naturally fetched (returned) to the cli...

D.

Data is a LIFO: There is only one data item that is naturally fetched (returned) to the cli...

3.

Deque

Select

A.

Data is both LIFO and FIFO: The are potentially two data items that could be naturally fetc...

B.

Data is neither LIFO nor FIFO: Client can naturally fetch (return) any of the many data ite...

C.

Data is a FIFO: There is only one data item that is naturally fetched (returned) to the cli...

D.

Data is a LIFO: There is only one data item that is naturally fetched (returned) to the cli...

4.

Array

Select

A.

Data is both LIFO and FIFO: The are potentially two data items that could be naturally fetc...

B.

Data is neither LIFO nor FIFO: Client can naturally fetch (return) any of the many data ite...

C.

Data is a FIFO: There is only one data item that is naturally fetched (returned) to the cli...

D.

Data is a LIFO: There is only one data item that is naturally fetched (returned) to the cli...

32.

Match the diagram with the description.

Choices - use a choice only once

A.

This diagram describes multiple inheritance.

B.

This diagram describes standard, simple inheritance

Match each of the following to a choice

1.

Base1 Base2

\ /

\ /

\ /

\ /

\ /

Derived

Select

A.

This diagram describes multiple inheritance.

B.

This diagram describes standard, simple inheritance

2.

Base

/ \

/ \

/ \

/ \

Derived1 Derived2

Select

A.

This diagram describes multiple inheritance.

B.

This diagram describes standard, simple inheritance

33.

Assume base class has an overridden method called methodX(). Let baseObject and derivedObject be base class and derived class objects, respectively.

Check the true statements (there will be one or more):

A.

derivedObject.methodX() will directly invoke the base class version of methodX().

B.

baseObject.methodX() will directly invoke the derived class version of methodX().

C.

baseObject.methodX() will directly invoke the base class version of methodX().

D.

derivedObject.methodX() will directly invoke the derived class version of methodX().

34.

Searching an array using a binary search (check all that apply):

A.

... requires a pre-sorted array in order to work.

B.

... is usually faster for each search than a simple linear search.

C.

... requires more code and logic than a simple linear search.

D.

... is usually slower for each search than a simple linear search.

35.

The is a sum-the-data-in-the-tree question. It asks whether a method, sumAll() is a well-written recursive method. You will see three different versions of this question throughout the exam, but the opening assumptions, are identical for all such versions. The only difference between the various questions is the code that implements the method sumAll().

Assumptions:

The general tree in this problem is assumed to be physical, i.e., there is no lazy or soft deletion designed into this tree.

We are considering a recursive work-horse method to sum all the (assumed) integer data of the sub-tree.

The sub-tree is specified by the root pointer passed in. As usual, some client would pass a root to this method, then this recursive method would generate other (child or sibling) roots to pass to itself when recursing.

The members sib and firstChild have the same meanings as in our modules.

True of False:

The method, as defined below, is a good recursive method for summing the data of the sub-tree, based at the root node passed in.

To be true, it must satisfy all the following criteria. If it misses one, it is false:

It gives the right sum for the sub-tree, that is, it does not miss counting any data.

it does no unnecessary work, micro-management or superfluous testing.

It covers all situations (empty trees, NULL roots, handles all the children, etc.).

int TreeClass::sumAll(Node *root)

{

int sibSum, thisSum, childrenSum;

if (root == NULL)

return 0;

// set to 0 in case we don't recurse, below.

sibSum = childrenSum = 0;

if (root->sib == NULL)

sibSum = sumAll(root->sib);

if (root->firstChild == NULL)

childrenSum = sumAll(root->firstChild);

thisSum = root->data;

return childrenSum + sibSum + thisSum;

}

There are three true-false questions that start out the same in this exam, but each has a different method definition. You may want to come back and review your answer to this question after seeing the other method definitions. Only one of the three is true, and the other two are false.

True

OR

False

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Power Bi And Azure Integrating Cloud Analytics For Scalable Solutions

Authors: Kiet Huynh

1st Edition

B0CMHKB85L, 979-8868959943

Students also viewed these Databases questions

Question

5. What are the causes of brand avoidance and anti- consumption?

Answered: 1 week ago