0

My current code uses a variable "word", so word = sys.argv[1] + sys.argv[2], which works great when I have two arguments, but when I only have one argument then i get IndexError: list index out of range

I am writing a program that Defines words by pulling the info from dictionary .com. I am following very closely a video tutorial because I am just trying to learn how to get a basic dictionary to work, (long term goal being write a translation app that is independent of google translate api or anything like that). I have a code that works in that it pulls the definition when you type in the word, but not when you type in 2 words, examples will be below. SO I added an argument, which worked for 2 words but no longer works for one word.

import requests
from bs4 import BeautifulSoup as bs
import sys

url = "https://www.dictionary.com/browse/"

word = sys.argv[1] + sys.argv[2]

url+= word
r = requests.get(url)
soup = bs(r.content, "lxml")


try:
    pos = soup.findAll("span", {"class" : "luna-pos"})[0].text #luna-pos is an html tag
    definitions = soup.findAll("ol")
    meanings = definitions[0].findChildren("li", recursive=False)
    print(word + ": " + pos)
    for (i,meaning) in enumerate(meanings):
        print(str(i + 1), meaning.text)
except:
     print("Word not found")

Expected results: Print word, part of speech, and definition. I.e Define the word (being a single argument) "Proper" Also Define "Self Control" (two word argument)

2 Answers2

4

Slicing:

You can use list slicing to avoid the error:

word = ''.join(sys.argv[1:]  # joins 1st to last ..

or

word = ''.join(sys.argv[1:3]  # 1st and 2nd without error 

List slicing works even if the slice index is larger then the amount of elements in the list.


Testing:

The other way to handle it would be to test first then append:

if len(sys.argv) == 2:
    word = sys.argv[1]
elif len(sys.argv) >= 3:
    word = sys.argv[1]+sys.argv[2]
else:
    word = "" # no input given

Error handling:

Try it and handle the error if it happens (see Ask forgiveness not permission below)

try:
    word = sys.argv[1]+sys.argv[2]
except IndexError:
    word = sys.argv[1]

Readup:

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
3

This is a good use-case for slicing. You want everything after the first argument in the list, so as a slice this translates to [1:]. So just use:

word = ''.join(sys.argv[1:])

For example:

>>> args = ['scriptname.py', 'the']
>>> ''.join(args[1:])
'the'
>>> args = ['scriptname.py', 'self', 'control']
>>> ''.join(args[1:])
'selfcontrol'
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172