BExtract the contents of the zip file to a Zoo OneDrive folder
CRename the "Zoo 2.1 LastName" folder, replacing LastName with your last name
DWithin the folder renamed in the previous step, rename the file "Zoo 2.1 LastName.sln" file, replacing LastName with your last name
ERight click the Solution and select 'Restore NuGet Packages'
Starting structure — supplied Zoo 2.1 LastName
NNew
CChanged
RRemoved
Starting references — Dolly and her unborn baby
NNew
CChanged
RRemoved
Explain Why an Animal Could Not Be Fed
Acceptance Criteria
I can feed either zoo’s animal when money and stock are available.
I receive a specific message for missing objects, invalid prices, insufficient funds, or insufficient stock.
An unsuccessful feeding leaves the animal unfed and does not keep my payment.
2.Review the Existing Food Purchase Checks
AInspect VendingMachine.cs
The starting project already checks payment, price, and available stock in SellFood and RemoveFood. Keep these methods unchanged. the FeedAnimal(...) method in Guest.cs will use their returned Food reference while reporting more specific results.
1Trace the existing methods in this order:
SellFood checks that payment and FoodPricePerPound are positive before dividing.
It checks the purchased weight against FoodStock before calling RemoveFood.
RemoveFood returns null for an invalid amount; for a valid amount, it subtracts stock and returns a Food object.
SellFood adds payment after removing the food and returns that Food reference.
BCheck Your Work
1With a newly created Como Zoo, a payment of 0.75 dispenses 1 pound, changes stock from 12 to 11, and adds 0.75 to MoneyBalance. Recreate the zoo after testing.
2Zero payment, a zero price, or insufficient stock produces no Food and does not change the machine’s stock or money balance.
3.Return a Result From the Guest
Problem
A bool only distinguishes success from failure. The window needs to know which condition prevented feeding.
Solution
Change the FeedAnimal(...) method in Guest.cs to return int. Each early return ends the method before an unsafe action. Reserve 0 for success.
AUpdate Guest.cs
Method return types for feeding and refilling
NNew
CChanged
RRemoved
1In Guest.cs, change FeedAnimal(Animal animal, VendingMachine machine) from bool to int. Replace its existing method body using the following steps.
Remove the wasFed local and its final return.
Replace the combined outer and inner conditions with the ordered checks below.
Keep the existing parameters. Use 0 only when feeding completes.
Feeding result contract
Result
Meaning
0
Success
1
Missing animal
2
Missing machine
3
Missing wallet
4
Invalid food price
5
Invalid food cost
6
Insufficient funds or incomplete payment
7
Invalid dispensed weight
8
Insufficient food stock
9
No Food returned; payment refunded
The following four activity diagrams show consecutive sections of the same FeedAnimal(...) method in Guest.cs. Continue to the next section only when its preceding checks pass. A return ends the method immediately; a continuation label only marks where the next diagram begins.
Reference and price checks
NNew
CChanged
RRemoved
2At the beginning of the FeedAnimal(...) method in Guest.cs, use if / else if checks in this order:
animal == null returns 1.
machine == null returns 2.
this.Wallet == null returns 3.
machine.FoodPricePerPound <= 0.00m returns 4.
This order prevents reading a member through a null reference.
Calculate the price and dispensed weight
NNew
CChanged
RRemoved
3After those checks, calculate the cost and weight in this order:
Define double requestedWeight and assign animal.GetPortionSize().
Define decimal foodCost and assign machine.DetermineFoodCost(requestedWeight).
Return 5 if foodCost <= 0.00m.
Define double foodWeight using the rounded price as shown below.
Check the actual dispensed weight because rounding the cost can make it differ from the animal’s requested portion.
Check funds and available food
NNew
CChanged
RRemoved
4Next use if / else if checks in this order:
this.Wallet.MoneyBalance < foodCost returns 6.
foodWeight <= 0 returns 7.
machine.FoodStock < foodWeight returns 8.
These checks happen before removing money.
Complete payment and feed the animal
NNew
CChanged
RRemoved
Result 6 has two paths: the earlier balance check detects insufficient funds before payment; the payment check detects an incomplete payment and refunds the amount removed. Both report the same unsuccessful-payment result.
5After the checks, complete the purchase in this order:
Assign this.RemoveMoney(foodCost) to decimal payment.
If payment != foodCost, refund payment with this.AddMoney(payment) and return 6.
Assign machine.SellFood(payment) to Food food.
If food == null, refund payment and return 9.
Call animal.Eat(food), then return 0.
Use the payment-and-feeding activity diagram to place these checks after the stock check. A refund must happen before its return. The final call to Eat runs only after food is confirmed to exist.
4.First Display Success or an Error Code
Problem
the FeedAnimal(...) method in Guest.cs now returns an integer instead of a bool. Before selecting a separate message for each error, use that integer to distinguish a successful feeding from an unsuccessful feeding.
Solution
Store the returned result in feedResult. Display the success message when it is 0. Otherwise, display a general failure message followed by the error code.
AUpdate the FeedAnimal(...) method in MainWindow.xaml.cs
1In MainWindow.xaml.cs, update the existing public void FeedAnimal(Zoo zoo, string zooName, string animalName, string guestName) method using the intermediate diagrams and steps below. Keep the two feeding button handlers calling this method with their existing arguments.
Use the intermediate activity and sequence diagrams to update the existing method. Keep the signature and the outer zoo check. Inside its valid-zoo branch:
Assign the visitor’s returned result to an int local named feedResult.
If feedResult == 0, assign the existing success message to message.
Otherwise, assign the general failure message shown below, ending with the result code.
message = guestName + " was unable to feed " + animalName
+ " at " + zoo.Name + ". EC = " + feedResult;
Keep the existing create-zoo message in the outer else, and call DisplayMessage once after the outer if / else.
The outer check handles a zoo that has not been created. The inner check interprets the result returned by the visitor. EC labels the error code; use the result table above to identify its meaning. DisplayMessage remains after the checks so every path displays its selected message.
Intermediate if / else message selection
NNew
CChanged
RRemoved
Intermediate window behavior — success or an error code
NNew
CChanged
RRemoved
BCheck Your Work
1Create Como Zoo and feed Dolly. Confirm the message is "Darla fed Dolly at Como Zoo." and feedResult is 0.
2Recreate Como Zoo, temporarily set Darla’s wallet balance to 0 in the debugger, and feed Dolly. Confirm "Darla was unable to feed Dolly at Como Zoo. EC = 6" and no food or money is removed.
3Recreate San Diego Zoo, temporarily set FoodStock to 0, and feed Patti. Confirm "Dave was unable to feed Patti at San Diego Zoo. EC = 8" and Dave keeps his money.
4Restart the application and click a feeding button before creating its zoo. Confirm the existing create-zoo message appears.
5Recreate both zoos to restore their starting values before continuing.
5.Select the Window Message With switch
AUpdate MainWindow.xaml.cs
1In the FeedAnimal(...) method in MainWindow.xaml.cs, keep the outer zoo != null check, the int feedResult assignment, and the create-zoo else message from the intermediate version. Replace only the inner if (feedResult == 0) / else message selection with a switch guided by the diagram and message table below. This replaces the general EC message with a specific explanation for each result and completes this section’s final behavior.
Follow the switch activity diagram and the result table. Each case assigns message and ends with break. Use this case as the pattern, then write the remaining cases yourself:
guestName + " does not have enough money to feed " + animalName + "."
7
"The requested food weight is invalid."
8
"The vending machine does not have enough food in stock."
9
"Food could not be dispensed
default
"An unexpected error occurred while feeding the animal."
2Keep DisplayMessage(message) after the outer if/else. Keep darlaFeedDingoButton_Click and daveFeedPlatypusButton_Click calling this window helper with their existing arguments. Do not duplicate the purchase sequence in those handlers.
Final switch cases and message selection
NNew
CChanged
RRemoved
The diagram shows the first two cases and default. The single [...] branch abbreviates cases 2 through 9; keep all of those cases in your code.
Feeding calls, returned results, and refund paths
NNew
CChanged
RRemoved
BCheck Your Work
1Create Como Zoo, then feed Dolly once. Expect "Darla fed Dolly at Como Zoo." The first price is 0.53; Darla’s balance becomes 4.72. Stock decreases by 0.53 / 0.75 pounds.
2Create San Diego Zoo, then feed Patti once. Expect "Dave fed Patti at San Diego Zoo." The first price is 0.08; Dave’s balance becomes 3.67.
3Recreate a zoo before each failure test. Temporarily set its visitor wallet balance to 0, then feed: result 6, no stock or animal-weight change.
4Set FoodStock to 0 with enough wallet money: result 8, no payment removed. Set price to 0: result 4, no division or payment.
5Temporarily set FeaturedAnimal, AnimalSnackMachine, or Visitor.Wallet to null one at a time: results 1, 2, and 3. Set animal Weight to 0: result 5. Restore values by recreating the zoo.
6Results 7 and 9 and the incomplete-payment refund are defensive paths. With normal synchronous calls and valid positive values they are not naturally reached. Inspect them in the debugger; to test refund handling, temporarily change the local food to null just after SellFood returns and step through AddMoney. This simulation already dispensed stock, so recreate the zoo immediately afterward.
Refill With Whole Food Bags
Acceptance Criteria
One fill click adds every whole bag that fits.
Refilling stops when full or when the next whole bag would exceed capacity.
I see how many whole bags were added: seven for a fresh Como machine and ten for a fresh San Diego machine.
6.Count Whole Bags Added With a while Loop
AUpdate VendingMachine.cs
The starting project already sets the machine sizes. Keep these assignments in both zoo creation methods:
Starting machine settings
Zoo
FoodStock
BagSize
FoodCapacity
Como Zoo
12.0
5.0
50.0
San Diego Zoo
17.0
4.0
60.0
1Change AddFoodBag() from void to bool and implement the behavior shown in the activity diagram:
If FoodStock + BagSize <= FoodCapacity, add BagSize to FoodStock and return true.
Otherwise, return false without changing FoodStock.
Use the AddFoodBag activity diagram to implement the two branches. The class diagram below shows the changed return type.
Adding a whole bag with if / else
NNew
CChanged
RRemoved
2Add public int Fill() to VendingMachine.cs. Build its body in this order:
Declare int bagsAdded = 0 before the loop. This local counts successful additions during this call.
Repeat while !this.IsFull().
Before adding a bag, break if FoodStock + BagSize > FoodCapacity.
Use if (this.AddFoodBag()) and increment bagsAdded inside that check.
After the loop, return bagsAdded.
Use the Fill activity diagram for statement order and loop exits. Use the sequence diagram to trace the returned count back to the window. Write the method from the diagram and the steps above.
The returned bool from AddFoodBag is the condition of the if statement. bagsAdded++ increases the count by one only after a bag was added. break leaves the loop and execution continues at return bagsAdded. IsFull stays unchanged. Keep the supplied positive BagSize values so successful iterations make progress.
3In MainWindow.xaml.cs, update the two fill handlers while keeping their create-zoo checks:
In floraFillVendingMachineButton_Click, replace the final AddFoodBag call with int bagsAdded = this.ComoZoo.AnimalSnackMachine.Fill();.
Immediately afterward, display Flora’s message using bagsAdded.
In bettyFillVendingMachineButton_Click, do the same for this.SanDiegoZoo and Betty’s message.
In the Como handler, after the create-zoo check:
In the Como handler, store the returned int in bagsAdded, then call DisplayMessage with this exact expression:
"Flora filled the vending machine by adding " + bagsAdded + " bag(s) of food."
In the San Diego handler, after the create-zoo check:
Repeat the same pattern in the San Diego handler, using this exact message expression:
"Betty filled the vending machine by adding " + bagsAdded + " bag(s) of food."
Fill calls and returned bag count
NNew
CChanged
RRemoved
Whole-bag loop, count, and early exit
NNew
CChanged
RRemoved
BCheck Your Work
1Create Como Zoo without feeding Dolly first. Fill once: seven bags raise stock from 12 to 47. The next bag would reach 52, so break ends the loop. Expect "Flora filled the vending machine by adding 7 bag(s) of food."
2Create San Diego Zoo without feeding Patti first. Fill once: ten bags raise stock from 17 to 57. The next bag would reach 61. Expect "Betty filled the vending machine by adding 10 bag(s) of food."
3Fill either machine again: stock stays unchanged and the message reports 0 bags.
4Temporarily set Como stock to 40: two bags reach 50 exactly, then IsFull ends the loop. Start at 50: the body does not run and Fill returns 0.
5Call AddFoodBag when a whole bag will not fit: it returns false and leaves stock unchanged. Recreate both zoos afterward.
Create a Baby for a Supported Animal Type
7.Use switch in MakePregnant
AUpdate Animal.cs
1In the MakePregnant() method in Animal.cs, keep the existing early return and replace the single baby creation with a switch on Type:
Keep the return when Sex != "Female" or GetIsPregnant() is true.
For "Dingo", create a new Animal and assign Baby.Type = "Dingo"; end the case with break.
For "Platypus", create a new Animal and assign Baby.Type = "Platypus"; end the case with break.
In default, return without creating a baby.
After the switch, keep the shared Baby.Sex and Baby.Weight assignments.
Use the MakePregnant activity diagram to implement the cases. Both supported cases create an Animal, set its Type, and end with break. The default branch returns before the shared Sex and Weight assignments.
Keep Reproduce unchanged. The baby is still an Animal; the selected case assigns its Type, and the existing birth handler assigns its Name after birth.
Pregnancy guard and type selection
NNew
CChanged
RRemoved
8.Verify the Existing Birth Workflow
AReview the unchanged birth methods
1Keep the existing the BirthAnimal(...) method in BirthingRoom.cs checks, returned baby, and window birth handlers. These are already present in LastName:
BirthAnimal checks the passed mother, her pregnancy, and Doctor before changing temperature or delivering.
Reproduce clears the mother’s Baby field and returns the newborn.
The handler assigns exactly "Baby" and chooses the success or no-baby message.
The San Diego handler refreshes the temperature display.
Birth checks and the returned baby
NNew
CChanged
RRemoved
The baby reference while the handler runs
NNew
CChanged
RRemoved
BCheck Your Work
1Create Como Zoo and give birth once: the message begins "A dingo was born." The local baby is named "Baby", the mother’s Baby is null, and both mother paths still reach Dolly. A second click gives "No dingo was born."
2Create San Diego Zoo and give birth once: the message begins "A platypus was born." Temperature changes from 77.0 to 77.5 and the display refreshes. A second click gives "No platypus was born." without another increase.
3Before birth, call MakePregnant again on an already pregnant animal: the existing Baby reference is preserved. Test a nonpregnant male and an unsupported Type: neither receives a baby.
4Temporarily set Doctor to null, or pass null as mother: BirthAnimal returns null and does not change temperature. Recreate the zoo after testing.
Complete Zoo 2.1
9.Review the Completed Design
ARemove the Unused Guest PortionSize Field
1The animal supplies its food portion through GetPortionSize(). Remove the unused guest data in these locations:
In Guest.cs, remove public double PortionSize and its associated comment.
In the CreateComoZoo() method in MainWindow.xaml.cs, remove this.ComoZoo.Visitor.PortionSize = 1.0;.
In the CreateSanDiegoZoo() method in MainWindow.xaml.cs, remove this.SanDiegoZoo.Visitor.PortionSize = 1.0;.
Keep Animal.PortionSizePercentage and Animal.GetPortionSize unchanged; these still determine the animal’s portion.
Completed Zoo 2.1 — new, changed, and removed signature
NNew
CChanged
RRemoved
BCheck Your Work
1Build the solution and resolve errors. Confirm the FeedAnimal(...) method in Guest.cs returns int and the window handles its result with switch.
2Run successful feeding and failure cases in both zoos, then test refill and both first-birth and no-baby results.
3Restore all values changed in the debugger. New zoos must start with the machine settings listed above and their original guest balances, prices, mothers, and temperatures.
10.Submit Zoo 2.1
AClose Visual Studio and ZIP your complete Zoo 2.1 solution folder, including its solution and project files.