A-level Computing/AQA/Paper 1/Skeleton program/2020

This is for the AQA A Level Computer Science Specification.

This is where suggestions can be made about what some of the questions might be and how we can solve them.

'''Please be respectful and do not vandalise the page, as this would affect students' preparation for exams! - Martin Perdicke''' Please do not discuss questions on this page. Instead use the discussion page: Coming soon!

Section C Predictions

 * The 2020 paper 1 will contain 1 question in Section C: two parts, worth 1 and 2 marks respectively.
 * What is the function of super in the definition of the LargeSettlement class? - Not relevant to all languages - Could question be reworded to make it more realistic? (Another option could be: "Explain how Settlement is used as a superclass in the program")
 * State one additional line of code which should be added after the Ben Thor Cuisine default company definition in the Simulation class' constructor in order to make it consistent with the ModifyCompany function.
 * What relationship (composition, aggregation and inheritance) exists between each of the classes
 * What are the (i) exact chances of each of the events happening individually (ii) the chances of all of the events occurring simultaneously?

Section D Predictions
Programming Questions on Skeleton Program
 * The 2020 paper 1 will contain 4 questions: a 6 mark, an 8 mark question, a 11 mark question and one 12 mark question - these marks include the screen capture(s), so the likely marks for the coding will be 1-2 marks lower.
 * The 2019 paper 1 contained 4 questions: a 5 mark, an 8 mark question, a 9 mark question and one 13 mark question - these marks include the screen capture(s), so the marks for the coding will be 1-2 marks lower.
 * The 2018 paper 1 contained one 2 mark question, a 5 mark question, two 9 mark questions, and one 12 mark question - these marks include the screen capture(s).
 * The 2017 paper 1 contained a 5 mark question, three 6 mark questions, and one 12 mark question.

Current questions are speculation by contributors to this page. Answers are down for maintenance, we are sorry for the inconvenience.
 * Ensure all costs are displayed in the following format £X.XX (4 Marks)
 * Add a new Small Settlement class and an option to create a Small Settlement in the simulation launch menu (6 Marks)
 * Add a Close Outlet event which results in an outlet being removed from the simulation (11 Marks)
 * ExpandOutlet add option for when the capacity is now zero
 * AlterCapacity(Change) correctly calculate the new DailyCosts when new capacity is limited to the max capacity
 * AddCompany(self) add check to see if CompanyName already exists in _Companies
 * RemoveCompany add option to remove a company instead of removing each of its outlets individually (this is likely to come up, there is no option 5 in the menu so this seems logical)
 * Add a faster option to load in the default scenario
 * Close an outlet for a specified temporary number of days
 * Merge two companies together
 * Advanced a specified number of days
 * Display how many days have passed
 * Display net gain/loss for the companies
 * Display net and average weekly gains/losses for individual outlets
 * Ensure fuel costs can never become negative
 * Increase or decrease reputation of a company by a inputted value (or predefined values)
 * Modify the CalculateDeliveryCost function so that the shortest path through all Outlets is used to minimise delivery costs (using Breadth-First graph traversal)
 * Add ability to create a new settlement and have outlets set up there
 * Validation on the initial entries for the program to run its menu
 * Validation on coordinates of Outlets, Households etc since two could randomly overlap on the x and y coordinates
 * Find, by using Djikstra's algorithm, the shortest path between a restaurant and the delivery locations. From there, calculate the total cost of delivery.
 * At day end, if any company has more than £20,000 as a balance, open another outlet at a random location and subtract £20,000 from their balance.
 * Only allow a new outlet to be created at a NEW location (i.e. one that doesn't already have an outlet of that company type)
 * At the end of the day, if a household eats out then its chance to eat out should change to another random number. However, if a household does not eat out then its probability to eat out should increase (e.g by 0.1) (4 Marks)
 * Create a random instance of a company or an outlet running a promotion, during which time its expenses go up but its reputation score also rises
 * Decrease company's balance when an outlet is closed
 * Add a class foodTruck which inherits from the class outlet and has a subroutine move
 * Add validation for any user input to ensure something is entered
 * Add validation according to type such that inputs required to be numeric are numeric
 * Create an additional category of restaurant, with a new Company of that type created as part of the default companies
 * Close an outlet that runs at a loss for five consecutive days, adding a notification that this has happened to the events
 * Display details of a restaurant, which was either the most profitable, the most visited or the one with the highest reputation reading
 * Generate a random budget and store it as an attribute within each household object; a household that eats out will only eat out will only eat out with a company whose prices are within their budget
 * Incorporate weather into the simulation; it can rain at random, in which cases the probabilities of eating out are all halved, and the presence of rain is indicated within the events
 * Add a feature in which meals can be delivered, rather than customers visiting outlets; households who choose not to eat out might, according to random chance, order food to be delivered, although this costs the company extra in fuel according to the distance of delivery
 * The name chef outlets generally make a profit while other categories make a loss; write a subroutine to determine, for each type of company, how much an outlet should have charged per meal during the previous day in order to have operated at a profit

Calculate the delivery cost to deliver between 2 outlets
Calculate the delivery cost where the user gives the company and the 2 outlets to calculate the delivery cost

for display menu for run method for calculating distance

Validation of user input so user's option is not null
Check whether user's option is not null

include in run method following code

Promotion of a company
Create a random instance of a company or an outlet running a promotion during which time its expenses go up but its reputation score also rises

for promotion method for processdayEnd method

Delivery cost using Dijkstra's Algorithm. (likely 12 mark question in my opinion)
Dijkstra's algorithm can only be used to find the shortest path between one node and another. In order to optimise delivery cost, we need to calculate the shortest path through all nodes. Djikstra's algorithm is not meant for this.

Find the shortest route to get from the first outlet to all the other outlets.

This is a generic Djikstra's algorithm I have written in Delphi. It needs to be adapted for use in the Food Magnate program.

Declare a Node class.

Construct the class

Grab the next node from the list

Find the minimum weight to traverse between two nodes

Find the shortest path between the origin (restaurant) and the destination (house).

This algorithm is by Chris | Peter Symonds College

Another Generic Dijkstras algorithm that needs to be adapted into the Skeleton Program. Dependancies: Matplotlib, NetworkX. (This is only to show a graphical version of the weighted graph). Datetime is a python3 inbuilt library so it doesn't need to be installed.
 * Written by Harry - Peter Symonds College

Change reputation with user's rating

 * change reputation method
 * add this to display menu
 * add this to run

Slight change to Simulation.Run; Just to add call to ChangeReputation procedure;

Alter Menu (corrected spelling - Chris)

Declare the procedures. Also requires procedure declarations inside simulation class.

This solution is by Alex Finch - Peter Symonds College

Power outage event

 * by Lucy W

Both of these in the simulation class, the display events at end of day is an updated version

This power outage event functions by creating a power outage for the entire 'world'. While the power outage is in progress, no companies will gain/ lose any money. At the end of the day the companies will all be reimbursed the earnings from that day. All other events will continue as normal. All new sub processes need to be declared in the class declarations.
 * Written by Harry - Peter Symonds College

Power cut event for a random company for a random amount of time in hours.

Add into Simulation class:

Edited DisplayEventsAtDayEnd subroutine:

In Company Class add:

End of world event
Within the Simulation class, make a method processEndOfWorld:

Within the displayEventsAtDayEnd method in the Simulation class, add:

The custom end of world message for each chance is not necessary for this question (This may be different if it comes up in the exam), if you're running low on time it may be possible just to have one option and leave out the random choice. New Procedures should also be declared in class definitions
 * Written by Harry - Peter Symonds College

Make a method Dropworld in the simulation class:

Within the DisplayEventsAtDayEnd sub in the Simulation class, add:

Go bankrupt event
Added event for companies to go bankrupt at -10,000 class Company:

def __init__(self, Name, Category, Balance, X, Y, FuelCostPerUnit, BaseCostOfDelivery): self._Outlets = [] self._FamilyOutletCost = 1000 self._NamedChefOutletCapacity = 50 self._Name = Name

# Added this function, which allows you to grab the balance into the "processdayend" function in the # Simulation class. def GetBalance(self): return self._Balance class Simulation: def __init__(self): self._Companies = [] self._FuelCostPerUnit = 0.0098 self._BaseCostforDelivery = 100 # Added this code at the start of the processdayend function. def ProcessDayEnd(self): for Current in self._Companies: Balance = Current.GetBalance Name = Current.GetName Index = self.GetIndexOfCompany(Name) if Balance < -10000: del (self._Companies[Index]) print("The company {} has gone into bankruptcy".format(Name))

Created by skesh
 * by Lucy W


 * Written by Harry - Peter Symonds College

i have done this slightly differently, i have made it so that after 7 days of being in debt then the company will be forced closed class Company {       private static Random rnd = new Random; protected string name, category; protected double balance, reputationScore, avgCostPerMeal, avgPricePerMeal, dailyCosts, familyOutletCost, fastFoodOutletCost, namedChefOutletCost, fuelCostPerUnit, baseCostOfDelivery; protected List outlets = new List; protected int familyFoodOutletCapacity, fastFoodOutletCapacity, namedChefOutletCapacity; protected bool isindebt;                                                                        // mmaking a bool to store if the company is in debt protected int daysindebt;

“LINE 390 to 420”

public bool GetIfInDebt                                     // function of if the company is in debt {           if (balance < 0) {               daysindebt++; // increments how many days the company has been in debt for

if (daysindebt == 7) {                   CompanyForcedClose; return true; }               return true; }           else {               daysindebt = 0; return false; }       }

public void CompanyForcedClose                          // procedure for a company to close when in debt for more than a week. could be changed to close outlets down at first. {           if (isindebt == true && daysindebt ==7) {               while (outlets.Count > 0) // calls the other subroutines while there are more than one outlet {                   CloseOutlet(0); }                        }

}

Process day end subroutine updated

public string ProcessDayEnd {           string details = ""; double profitLossFromOutlets = 0; double profitLossFromThisOutlet = 0; double deliveryCosts; if (outlets.Count > 1) {               deliveryCosts = baseCostOfDelivery + CalculateDeliveryCost; }           else {               deliveryCosts = baseCostOfDelivery; }           details += "Daily costs for company: " + dailyCosts.ToString + "\nCost for delivering produce to outlets: " + deliveryCosts.ToString + "\n"; for (int current = 0; current < outlets.Count; current++) {               profitLossFromThisOutlet = outlets[current].CalculateDailyProfitLoss(avgCostPerMeal, avgPricePerMeal); details += "Outlet " + (current + 1) + " profit/loss: " + profitLossFromThisOutlet.ToString + "\n"; profitLossFromOutlets += profitLossFromThisOutlet; }           details += "Previous balance for company: " + balance.ToString + "\n"; balance += profitLossFromOutlets - dailyCosts - deliveryCosts; details += "New balance for company: " + balance.ToString; isindebt = GetIfInDebt; // calling the subroutines that i have made return details; }

Get details subroutine

public string GetDetails {           string details = ""; details += "Name: " + name + "\nType of business: " + category + "\n"; details += "Current balance: " + balance.ToString + "\nAverage cost per meal: " + avgCostPerMeal.ToString + "\n"; details += "Average price per meal: " + avgPricePerMeal.ToString + "\nDaily costs: " + dailyCosts.ToString + "\n"; details += "Delivery costs: " + CalculateDeliveryCost.ToString + "\nReputation: " + reputationScore.ToString + "\n"; details += "Number of outlets: " + outlets.Count.ToString + "\nOutlets\n"; details += "\nIs the company in debt? " + isindebt.ToString + "\n";                                                                                    // puts whether the company is in debt in the details if (isindebt == true)                                                                                                                         // displays how many days in debt if the company is in debt {               details += "\n Days the company has been in debt for " + daysindebt.ToString + " days \n\n"; }           for (int current = 1; current < outlets.Count + 1; current++) {               details += current + ". " + outlets[current - 1].GetDetails + "\n"; }           return details; }

This needs to be in the simulation class. public void DeleteCompany(int index) // new subroutine to delete a company which has had all its outlets closed {           int outlets = companies[index].GetNumberOfOutlets;

if (outlets == 0) {                   Console.WriteLine("That company has now closed down as it has no outlets."); companies.RemoveAt(index); }       }

and it is called in process day end which is shown here

public void ProcessDayEnd {           int index = 0; do                                             // calls the other subroutine while the company count is changing {               DeleteCompany(index); index++;

} while (index < companies.Count);

double totalReputation = 0; List reputations = new List ; int companyRNo, current, loopMax, x = 0, y = 0; foreach (var c in companies) {               c.NewDay; totalReputation += c.GetReputationScore; reputations.Add(totalReputation); }           loopMax = simulationSettlement.GetNumberOfHouseholds - 1; for (int counter = 0; counter < loopMax + 1; counter++) {               if (simulationSettlement.FindOutIfHouseholdEatsOut(counter, ref x, ref y)) {                   companyRNo = rnd.Next(1, Convert.ToInt32(totalReputation) + 1); current = 0; while (current < reputations.Count) {                       if (companyRNo < reputations[current]) {                           companies[current].AddVisitToNearestOutlet(x, y); break; }                       current++; }

}           }            DisplayCompaniesAtDayEnd; DisplayEventsAtDayEnd; dayCounter++;                                                               //incrementing the days

}


 * By Michael Tomkinson*

Remove Company
make a new method called RemoveCompany. modify the Run method to add a new case for option 5

lastly, modify the DisplayMenu method to write the option to the console.

Slight change to Simulation.Run; Just to add call to RemoveCompany; procedure.

Slight change to menu to show new option

Add Simulation.RemoveCompany; procedure. Also ensure you declare this within the simulation class deceleration.

This solution is by Alex Finch - Peter Symonds College

Shows list of companies to be removed Obviously add the option for 7 in the menu so they know to press it. Solution by Owain Bestley

'method in java to remove a company from given user input

'displaying menu option to remove a company in java 'adding remove company under run

Alternative Solution:

Run for many days
Add an option to run simulation for many days (>1)

This is the subroutine for the menu. in this i have also validated the menu choice. public void Run {           string choice = ""; int index; while (choice != "Q") {               DisplayMenu; do {                                                                                                // validation for the menu choice choice = Console.ReadLine; switch (choice) {                       case "1": simulationSettlement.DisplayHouseholds; break; case "2": DisplayCompanies; break; case "3": string companyName; index = -1; while (index == -1) {                               Console.Write("Enter company name: "); companyName = Console.ReadLine; index = GetIndexOfCompany(companyName); }                           ModifyCompany(index); break; case "4": AddCompany; break; RemoveCompany; break; case "6": ProcessDayEnd; break; case "7": AdvanceMultipleDays; // added a new case that will advance many days break; case "Q": Console.WriteLine("Simulation finished, press Enter to close."); Console.ReadLine; break; }                   if((int.Parse(choice) > 0 && int.Parse(choice) < 8) || choice != "Q")                             // repeats untill this = true {                       Console.WriteLine("Pleas Re Enter a valid choice");

}               } while ((int.Parse(choice) > 0 && int.Parse(choice) < 8) || choice != "Q"); } }   }

This is the subroutine for advancing many days

public void AdvanceMultipleDays    // new subroutine to advance many days {           Console.WriteLine("How many days would you like to advance?"); int AdvancingDays = int.Parse(Console.ReadLine); for (int i = 0; i < AdvancingDays ; i++) {               ProcessDayEnd; }

}
 * By Michael Tomkinson


 * Written by Harry - Peter Symonds


 * by Benny

Day Counter
Display a counter of how many days have passed

make a new int varible in the simulation class and initlise it in constructor.

modify the ProcessDayEnd method to increment the counter

modify the menu to display the day number


 * Written by Harry - Peter Symonds College

add integer days to Simulation class and set it to zero 'under Simulation class, add following methods: '1. to increment days 2. to output no of days passed 'add this to run method as well in right order and correct use of methods

Display Costs (£x.xx)
Display the costs in the format £x.xx, as opposed to just an integer value.

Please note: RoundValue was chosen as the name for this function as round is a taken keyword in Pascal, when copying code don't change the function name to round or it will break other areas of this program. To Apply this to the program, simply replace all applicable FloatToStr functions with this RoundValue one.
 * Written by Harry - Peter Symonds College

'for given currency format, add in each class: 'to display any of the costs in £x.xx, eg:

Check if company name is taken
AddCompany(self) add a check to see if CompanyName already exists in _Companies

By Lawrence Dennison-Hall | Peter Symonds College

This is just an edit to the addCompany function in the Simulation Class. Created by the one and only Jorge Bishop

Fuel cost always positive
Ensure fuel costs can never become negative

The fuel costs go negative because: DeliveryCosts = Distance * FuelCostPerUnit So when FuelCostPerUnit becomes negative, the fuel cost will very quickly break. Just make sure FuelCostPerUnit does not go negative.

By Lawrence Dennison-Hall | Peter Symonds College

Small settlement
Add small settlement class and provide an option in the launch menu

Small settlement class: Small settlement constructor: Updated menu options (Simulation constructor) By Lawrence Dennison-Hall | Peter Symonds College

By changing the Settlement class to 0 instead of just taking away an integer we can avoid having any issues where we may get a negative integer. We can also now create a custom sized Settlement.

You also have to alter the simulation class to accomodate for the change, calling the default simulation class instead of just simulation.

Solution made by Owain Bestley (Listen to Hachiko)

Doesn't accept integers with ExtraX/Y
Question description

Add a Close Outlet event
Adds a random event function which removes an outlet from a company

New functions and procedures added need to be declared in class definitions.
 * Written by Harry - Peter Symonds College


 * Under Simulation class add following method
 * also under displayEventsAtDayEnd method, add some of the extra lines of code below:

Add a faster option to load in the default scenario
Add a faster option to load in the default scenario


 * Written by Harry - Peter Symonds College