-3

This code works so that when I give an input word, if it matches with a term stored in a dictionary, it prints the definition of asked term. I am trying to add a feature where if I give an input that is not a term in the dictionary, I do a little check to see if any part of the word, is stored as termin the dictionary.

word = input("Enter a programming term you want to know about: ")
terms = {
    "tuple" : "Variables are containers for storing data (storing data values)."
}


def return_definition(word):
    output = ""
    for term, value in terms:
        if word == term :
            output += terms.get(key)
        elif term in word:
            output += terms.get(value)
    return output

print(return_definition(word))

The elif conditional tests if the user inputs something not in the dictionary e.g. "tuples". I would like to return the definition of tuple to them, so I check term in word, to make it so that program returns the definition for tuple. However, instead of returning the definition, the program causes this error

Traceback (most recent call last):
  File "e:\Code\Python Code\Exercises\dictionary.py", line 48, in <module>        
    print(returnDefinition(word))
  File "e:\Code\Python Code\Exercises\dictionary.py", line 41, in returnDefinition
    for term, value in terms:
ValueError: too many values to unpack (expected 2)
  • 2
    Why are you iterating through a dictionary to look up a key? Why not just use `terms[termToKnow]`? – khelwood Jul 30 '22 at 08:38
  • 1
    Why use `terms[key]` over `value`? – Filip Müller Jul 30 '22 at 08:38
  • 2
    @Illusioner_ Yes you can do that. It is the whole point of a dictionary. – khelwood Jul 30 '22 at 08:40
  • 1
    @Illusioner_ I suspect you're learning Python for the first time! Keep up the good work. Here is a StackOverflow thread that goes into [how to use dictionaries](https://stackoverflow.com/a/45073048/7662085). It is also worth looking at some tutorials (on Google), and if you're interested you can read up on [how a dictionary actually works under the hood](https://stackoverflow.com/a/44509302/7662085). – stelioslogothetis Jul 30 '22 at 08:41
  • this bit of code check if the user has accidentally typed an extra character at the end, but the rest of the input is still matching with the term, this breaks after a non-iterative approach – Illusioner_ Jul 30 '22 at 08:43
  • `terms[value]` won't work as you can only do `Dictionary[something]` when `something` is a *key* in the dictionary. Not when `something` is a *value* in the dictionary. In this `for` loop you've written, you're going through all the keys and values (and naming them accordingly). So you can't try and do `term[value]`, it won't work. It is similar to a real dictionary (a physical book with definitions of words) in real life. You can look up a word (the key) and get its meaning. However, you can't look for a meaning and find the word it belongs to! – stelioslogothetis Jul 30 '22 at 08:46
  • so i can still do ```term[termToKnow]```? – Illusioner_ Jul 30 '22 at 08:48
  • @Illusioner_ You can try. If `termToKnow` is a key in the dictionary `terms`, it will give you back the value. If it is *not* a key, then you will get a `KeyError`. Because it tried to find it in the dictionary but couldn't! For this, you need to add a check: `if termToKnow in terms`. – stelioslogothetis Jul 30 '22 at 08:50
  • I am confused more than ever now, for first, this worked just fine outside a function, second, what if the user might have mistyped the last character, but i still want my code to work, this functionality works fine in for loops as well, but not in functions – Illusioner_ Jul 30 '22 at 08:54
  • @Illusioner_ Simple thing I thought to ask. Did you remember to do `return output` at the end? – stelioslogothetis Jul 30 '22 at 08:58
  • Yes, it works after that, but not that mistype functionality, in your answer – Illusioner_ Jul 30 '22 at 09:04

2 Answers2

1

If you really need to iterate through the dictionary, you should do like so:

for key, value in terms.items():
    if key in termToKnow:
        output += value

Note that this can lead to you outputting multiple different values. What if user for examples just types "a"? How many results could that possibly yield? What do you want to do in that case? Return the first value that has an "a" in it? You will need to think about these questions to find the best approach.

Filip Müller
  • 1,096
  • 5
  • 18
1

Here is what I would do:

def returnDefinition(termToKnow, terms):
    output = ""
    # We loop through the words in termToKnow instead of looping through the dictionary
    for word in termToKnow.split(' '):
        if word in terms:
            output += terms[word]
    return output

If you want to match if there is a random character before or after the term (pythonk instead of python):

def returnDefinition(termToKnow, terms):

    # Check if there is an exact match
    if termToKnow in terms:
        return terms[termToKnow]
    else:
        # Check for match with a mistyped character
        for key in terms.keys():
            if key in termToKnow:
                return terms[key]

    return "Didn't find anything"    
stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
  • I feel like OP is trying to have it work in a case where there is a random mistyped character at the end. E.g. "pythonk" and he still wants to find the description of python – Filip Müller Jul 30 '22 at 08:59
  • @FilipMüller Maybe so, however that quickly makes the task much more complicated. That requires implementing an algorithm for [fuzzy string matching](https://en.wikipedia.org/wiki/Approximate_string_matching) (or using a library like [fuzzywuzzy](https://www.geeksforgeeks.org/fuzzywuzzy-python-library/)). – stelioslogothetis Jul 30 '22 at 09:02
  • However, it breaks if i type tuples, because the key in the dictionary is stored as tuple – Illusioner_ Jul 30 '22 at 09:03
  • Can you give an example? What does a key in the dictionary look like? – stelioslogothetis Jul 30 '22 at 09:04
  • @stelio Yeah I understand that it makes it much more complicated. Perhaps the best answer is "Just have the user retype the name if `termToKnow not in terms`" – Filip Müller Jul 30 '22 at 09:05
  • I did this earlier with a simple, iteration over all the keys, and asked ```key in termToKnow```. This essentially asks if python is in pythonk, which is true, and proceeds with returning the output – Illusioner_ Jul 30 '22 at 09:06
  • a key in the dictionary is tuple, and the input i want to give is tuples, this used to work with ```key in termToKnow``` but again would require iterating over the dictionary which we dont want to do – Illusioner_ Jul 30 '22 at 09:07
  • @Illusioner think about what that code does when user types "javascript" and you have definitions "java", "javascript", and "javadoc" in you dictionary – Filip Müller Jul 30 '22 at 09:08
  • @FilipMüller No , that would not mess anything up, as, javadocs is not in java. however if the user typed javadocs, that could mess something up, to make sure that doesn't happen, we could sort the dictionary where java, with len(4) would be placed after javadocs with len(8) – Illusioner_ Jul 30 '22 at 09:09
  • What if "script" is also in the dictionary? I hope you see how this gets complicated. – Filip Müller Jul 30 '22 at 09:11
  • You cannot sort dictionaries. Their intended use is for you to get precise matches only. If you want to allow for searching "similar" terms, this becomes a different type of task which I wouldn't do for just learning for the first time. See my earlier comment responding to Filip – stelioslogothetis Jul 30 '22 at 09:12
  • Yes I see that, but this is only for practice, not a database where I would be required to use OOP, and probably more complex stuff – Illusioner_ Jul 30 '22 at 09:12
  • @stelioslogothetis I could just ask the user to type it again, but decided to give myself a challenge, by your comment, I have an idea, that I could check for all the terms matching with my input, list them and ask the user to choose which one they want to check the definition for – Illusioner_ Jul 30 '22 at 09:14