Instructions for trainInventory

(produced at 21:40 UTC on 2024-10-23)

This task is part of project07 which is due at 23:00 EDT on 2024-10-29.

You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.

You can download the starter code for this task using this link.

You can submit this task using this link.

Put all of your work for this task into the file trainInventory.py
(you will create this file from scratch)

Overview

In this task, you will practice nested loops by implementing a program to manage inventory on trains. Each train is represented as a list of train cars, and each train car is a list of tuples indicating the name and total weight (in kilograms) of each item stored in that car. For example, the following train is carrying grain in one car and some furniture in another.

train = [
    [('grain', 100000)],
    [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)]
]

We've written it split across multiple lines for easy reading, but note that if you printed it, it would appear on one line.

Functions to Define

Note that as usual, we require that you include docstrings in every function and we expect that you will complete the project faster if you write these first, before you start to write any code.

Part A: Printing the inventory

Your first goal is define a function printInventory that displays the inventory in a train split across multiple lines of output so that it's easier to read. It takes a single argument, which is a train (i.e., a list of lists of tuples which contain strings an numbers). It must use print to display the contents of the train such that

  • Each train car is labeled as 'Car #' followed by the index of that car (starting from 0).
  • After each train car label, the items in that car appear on separate lines, with their weight first, then the suffix 'kg', and finally their name. Each item starts with two spaces of indentation (whereas the car names aren't indented).

These printInventory examples demonstrate how it should work.

Notes:

  • Your printInventory function must use a nested loop
  • You can test printInventory and the other trainInventory functions by running the file test_trainInventory.py.

Part B: Summing weights

Next, you must define a function totalWeightOf which, given a train and a specific item name, counts the total weight of items with that name anywhere on the train. Remember that each item is stored as a tuple with a name and a weight; you need to add up those weights, but only for items whose name matches.

These totalWeightOf examples demonstrate how it should work.

Notes:

Part C: Listing items

Define a function listItems which, given a train and a specific item name, returns a list containing each item with that name from throughout the train. Remember that each item is stored as a tuple with a name and a weight, your goal here is to create a list containing all such tuples whose names match the specified name. The items in the list should appear in the same order that they appear in the train.

These listItems examples demonstrate how it should work.

Notes:

Part D: Listing the weight of each car

Define a function listWeights which, given a train, returns a list containing the total weight of each car in the train. Remember that each item is stored as a tuple with a name and a weight, your goal here is to sum up the weights within each car, and then append those sums to a list.

These listWeights examples demonstrate how it should work.

Notes:

Part E: Finding the heaviest car

Write a function heaviestCar which when given a train, returns the index within that train of the heaviest single car, or the index of the earliest heaviest car if several are tied for heaviest. Although you may choose to use a nested loop to solve this problem, you do not have to.

These heaviestCar examples demonstrate how it should work.

Part F: Repacking the cars

Define a function named repackCars which takes a train and a weight limit, and then tries to re-pack the items from the train into new cars so that each of them is below the weight limit, returning a new train list-of-lists. This function must work as follows:

  1. It must consider each item from the original train in order, starting with the first item in the first car, then the second item in that car, etc.
  2. It should add each item to a single new train car until adding the next item would exceed the specified weight limit, when it will place that next item into another new car and then start packing more items there next.
  3. It will NOT go back to try to fill up earlier gaps.
  4. If a single item from the original train is above the weight limit by itself, it should be put into its own car, and then the next item will go into a second new car after that.

There are more efficient ways to repack things in terms of using fewer train cars, but this algorithm only requires considering each item once, and only considers one or two places to put that item.

These repackCars examples demonstrate how it should work.

Note that:

Ungraded Challenge

If you'd like a completely optional and un-graded challenge, we've included some tests in the test_trainInventory.py file which will test the following function:

Challenge A: Removing Items

A function called removeItems can be written which takes a train and an item name, and removes all items with that name from the train, putting them into a separate list which it returns, preserving their order from the train. It needs to both return the result list and modify the original train.

This is quite challenging to do correctly and is not part of the rubric for this task, so only attempt it if you want an extra challenge. As a hint, it will be useful to iterate using a backwards index loop as part of this problem.

Examples

printInventory examples

These examples demonstrate how printInventory should word. Note the indentation and added units ('kg').

In []:
printInventory( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ] )
Prints
Car #0 100000 kg grain Car #1 2000 kg chairs 2300 kg sofas 1000 kg chairs 4000 kg tables
In []:
printInventory( [ [('electronics', 2000), ('cloth', 40000), ('toys', 8000)], [('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82)], [('steel', 22000), ('iron', 45000), ('cobalt', 12000)], [('helium', 4000), ('electronics', 50)], ] )
Prints
Car #0 2000 kg electronics 40000 kg cloth 8000 kg toys Car #1 8 kg racoons 5 kg opossum 37 kg rabbits 82 kg deer Car #2 22000 kg steel 45000 kg iron 12000 kg cobalt Car #3 4000 kg helium 50 kg electronics

totalWeightOf examples

These examples demonstrate how totalWeightOf should word.

In []:
totalWeightOf( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ], 'grain' )
Out[]:
100000
In []:
totalWeightOf( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ], 'chairs' )
Out[]:
3000
In []:
totalWeightOf( [ [('electronics', 2000), ('cloth', 40000), ('toys', 8000)], [('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82)], [('steel', 22000), ('iron', 45000), ('cobalt', 12000)], [('helium', 4000), ('electronics', 50)], ], 'electronics' )
Out[]:
2050

listItems examples

These examples demonstrate how listItems should word. Note that items are listed in the same order they appear in within the train.

In []:
listItems( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ], 'chairs' )
Out[]:
[('chairs', 2000), ('chairs', 1000)]
In []:
listItems( [ [('wheat', 122000)], [('wheat', 148000)], [('semolina', 90000)], [('semolina', 93000)], [('semolina', 89000)], [('spelt', 91000), ('barley', 24000)], ], 'barley' )
Out[]:
[('barley', 24000)]
In []:
listItems( [ [('electronics', 2000), ('cloth', 40000), ('toys', 8000)], [('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82)], [('steel', 22000), ('iron', 45000), ('cobalt', 12000)], [('helium', 4000), ('electronics', 50)], ], 'electronics' )
Out[]:
[('electronics', 2000), ('electronics', 50)]

listWeights examples

These examples demonstrate how listWeights should word.

In []:
listWeights( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ] )
Out[]:
[100000, 9300]
In []:
listWeights( [ [('wheat', 122000)], [('wheat', 148000)], [('semolina', 90000)], [('semolina', 93000)], [('semolina', 89000)], [('spelt', 91000), ('barley', 24000)], ] )
Out[]:
[122000, 148000, 90000, 93000, 89000, 115000]
In []:
listWeights( [ [('electronics', 2000), ('cloth', 40000), ('toys', 8000)], [('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82)], [('steel', 22000), ('iron', 45000), ('cobalt', 12000)], [('helium', 4000), ('electronics', 50)], ] )
Out[]:
[50000, 132, 79000, 4050]

heaviestCar examples

These examples demonstrate how heaviestCar should word. Note that the return value is an index, starting from 0.

In []:
heaviestCar( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ] )
Out[]:
0
In []:
heaviestCar( [ [('wheat', 122000)], [('wheat', 148000)], [('semolina', 90000)], [('semolina', 93000)], [('semolina', 89000)], [('spelt', 91000), ('barley', 24000)], ] )
Out[]:
1
In []:
heaviestCar( [ [('electronics', 2000), ('cloth', 40000), ('toys', 8000)], [('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82)], [('steel', 22000), ('iron', 45000), ('cobalt', 12000)], [('helium', 4000), ('electronics', 50)], ] )
Out[]:
2

repackCars examples

These examples demonstrate how repackCars should word.Note how we pack items in order and don't go back to earlier cars even if they have room for a new item.

In []:
repackCars( [ [('grain', 100000)], [('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000)], ], 200000 )
Out[]:
[ [ ('grain', 100000), ('chairs', 2000), ('sofas', 2300), ('chairs', 1000), ('tables', 4000), ], ]
In []:
repackCars( [ [('wheat', 122000)], [('wheat', 148000)], [('semolina', 90000)], [('semolina', 93000)], [('semolina', 89000)], [('spelt', 91000), ('barley', 24000)], ], 300000 )
Out[]:
[ [('wheat', 122000), ('wheat', 148000)], [('semolina', 90000), ('semolina', 93000), ('semolina', 89000)], [('spelt', 91000), ('barley', 24000)], ]
In []:
repackCars( [ [('electronics', 2000), ('cloth', 40000), ('toys', 8000)], [('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82)], [('steel', 22000), ('iron', 45000), ('cobalt', 12000)], [('helium', 4000), ('electronics', 50)], ], 48000 )
Out[]:
[ [('electronics', 2000), ('cloth', 40000)], [ ('toys', 8000), ('racoons', 8), ('opossum', 5), ('rabbits', 37), ('deer', 82), ('steel', 22000), ], [('iron', 45000)], [('cobalt', 12000), ('helium', 4000), ('electronics', 50)], ]

Rubric

Group goals:
 
unknown All functions are documented
Each function you define must include a non-empty documentation string as the very first thing in the function.
 
unknown printInventory must print the correct output
The output printed when your printInventory function is run must match the solution output.
 
unknown totalWeightOf must return the correct result
The result returned when your totalWeightOf function is run must match the solution result.
 
unknown listItems must return the correct result
The result returned when your listItems function is run must match the solution result.
 
unknown listItems must not modify the train.
We will call listItems to make sure it does not alter values in the train it is given.
 
unknown listWeights must return the correct result
The result returned when your listWeights function is run must match the solution result.
 
unknown listWeights must not modify the train.
We will call listWeights to make sure it does not alter values in the train it is given.
 
unknown heaviestCar must return the correct result
The result returned when your heaviestCar function is run must match the solution result.
 
unknown repackCars must return the correct result
The result returned when your repackCars function is run must match the solution result.
 
unknown repackCars must not modify the train.
We will call repackCars to make sure it does not alter values in the train it is given.
 
unknown totalWeightOf must return the correct result
The result returned when your totalWeightOf function is run must match the solution result.
 
unknown heaviestCar must return the correct result
The result returned when your heaviestCar function is run must match the solution result.
 
unknown repackCars must return the correct result
The result returned when your repackCars function is run must match the solution result.
 
unknown Define printInventory
Use def to define printInventory
 
unknown Use any kind of loop
Within the definition of printInventory, use any kind of loop in at least one place.
 
unknown Use any kind of loop
Within the loop within the definition of printInventory, use any kind of loop in at least one place.
 
unknown Call print
Within the definition of printInventory, call print in at least one place.
 
unknown Define totalWeightOf
Use def to define totalWeightOf
 
unknown Use any kind of loop
Within the definition of totalWeightOf, use any kind of loop in at least one place.
 
unknown Use any kind of loop
Within the loop within the definition of totalWeightOf, use any kind of loop in at least one place.
 
unknown Define listItems
Use def to define listItems
 
unknown Use any kind of loop
Within the definition of listItems, use any kind of loop in at least one place.
 
unknown Use any kind of loop
Within the loop within the definition of listItems, use any kind of loop in at least one place.
 
unknown Define listWeights
Use def to define listWeights
 
unknown Use any kind of loop
Within the definition of listWeights, use any kind of loop in at least one place.
 
unknown Use any kind of loop
Within the loop within the definition of listWeights, use any kind of loop in at least one place.
 
unknown Define heaviestCar
Use def to define heaviestCar
 
unknown Define repackCars
Use def to define repackCars
 
unknown Use any kind of loop
Within the definition of repackCars, use any kind of loop in at least one place.
 
unknown Use any kind of loop
Within the loop within the definition of repackCars, use any kind of loop in at least one place.