I’m working on the Inventory Management exercise (Pairs and Dicts), and for the final method, I need to list out the elements of a dictionary where the values are not 0. I’ve done that, but the test case is failing because the keys are in the wrong order. How do I fix this? I’ve tried importing OrderedDict but got an error
OrderedDict is an external package and (like many of Julia’s thousands of packages) it is not available in the Exercism test runner. We need to avoid bloating the Docker container that tests run in.
The final result should not be a Dict. The exercise asks for a vector of Pairs, and vectors can be sorted.
Dict to Vector conversion can be done in various ways. Pythonistas would probably use a comprehension, more functional people might use collect()
. Your choice.
Did you look at the hints? This is not especially encouraged, but can be useful if you are stuck. I ask partly because I need to know if these documents are inadequate - the syllabus is still a beta release.
We could create a Vector with the required values, and sort the Vector.
Are the Hints helpful?
Simultaneous responses…
Here’s what I have on my latest run:
function list_inventory(inventory)
empty_elems = String[]
inventory_keys = keys(inventory)
#println(inventory_keys)
for (key, value) in inventory
#specific_key = inventory_keys[i]
#println(specific_key)
if value == 0
push!(empty_elems, key)
end
end
for i in 1:length(empty_elems)
remove_item(inventory, empty_elems[i])
end
#sorted_keys = sort(collect(keys(inventory)))
#println(sorted_keys)
inventory_keys = keys(inventory)
final_inventory = Vector{Pair{String, Int64}}()
for i in 1:length(inventory_keys)
push!(final_inventory, inventory_keys[i] => inventory[inventory_keys[i]])
#println(final_inventory)
end
final_inventory = sort(inventory)
return final_inventory
end
And here’s the error I’m getting:
MethodError: no method matching getindex(::Base.KeySet{String, Dict{String, Int64}}, ::Int64)
The function getindex
exists, but no method is defined for this combination of argument types.
The immediate problem is inventory_keys[i]
, which the compiler chokes on. I’m still trying to untangle precisely why.
Looping over the index, and using that to retrieve the actual key, is an unusual thing to do in Julia. You could replace the for
statement with
for k in keys(inventory)
and use k
in place of inventory_keys[i]
. Much simpler, and it works.
Also, take a look at the end of the function. I think you’ll find you are sorting the wrong variable.
My overall recommendation is to step away from this for half an hour or so, relax, then take another look at it. We all find that this is a very important debugging technique!
Also, once you are though with this, please look at the community solutions. This function can be much simpler than you think, and learning that is a major aim of the syllabus. Actually, a major aim of Exercism as a whole.
I just looked through the community solutions, and realized that we may have things a bit out of order. Python-style comprehensions are useful here, to simplify things. They are mentioned in Vector Operations
, but that is not a prerequisite for this exercise.
I’ll raise an issue on GitHub, to discuss whether to move Pairs and Dicts
down the syllabus, or (perhaps better) move the short section on comprehensions to the Loops
concept.
Unfortunately, this is what I meant by saying that the syllabus is still a beta release. It went public 3 weeks ago.
Fixed in PR #911. We added a section on comprehensions to the Loops concept, removing it from Vector Operations.
It’s at the bottom of this document.
I got it to work! Here’s my final version of the method:
function list_inventory(inventory)
empty_elems = String[]
inventory_keys = keys(inventory)
for (key, value) in inventory
if value == 0
push!(empty_elems, key)
end
end
for i in 1:length(empty_elems)
remove_item(inventory, empty_elems[i])
end
inventory_keys = sort(collect(keys(inventory)))
final_inventory = Vector{Pair{String, Int64}}()
for k in inventory_keys
push!(final_inventory, k => inventory[k])
end
return final_inventory
end