Question

This is my script, when I try to run it there is an error

IndexError: list index out of range

for line 9 (numberOfViewers = int(sys.argv[1])).

Could someone help me with this and explain how to fix it?

import requests
import subprocess
import json
import sys
import threading
import time
from Queue import Queue

numberOfViewers = int(sys.argv[1])
builderThreads = int(sys.argv[2])
startTime = time.time()
numberOfSockets = 0
concurrent = 25
urls = []
urlsUsed = []

def getURL():
    output = subprocess.Popen(["livestreamer", "twitch.tv/spartanium", "-j"], stdout=subprocess.PIPE).communicate()[0]
    return json.loads(output)['streams']['worst']['url']

def build():
global numberOfSockets
global numberOfViewers
while True:
    if numberOfSockets < numberOfViewers:
        numberOfSockets += 1
        print "Building viewers " + str(numberOfSockets) + "/" + str(numberOfViewers)
        urls.append(getURL())

def view():
global numberOfSockets
while True:
    url=q.get()
    requests.head(url)
    if (url in urlsUsed):
        urls.remove(url)
        urlsUsed.remove(url)
        numberOfSockets -= 1
    else:
        urlsUsed.append(url)
    q.task_done()

if __name__ == '__main__':
for i in range(0, builderThreads):
    threading.Thread(target = build).start()

while True:
    while (numberOfViewers != numberOfSockets):
        time.sleep(1)

    q=Queue(concurrent*2)
    for i in range(concurrent):
        try:
            t=threading.Thread(target=view)
            t.daemon=True
            t.start()
        except:
            print 'thread error'
    try:
        for url in urls:
            print url
            q.put(url.strip())
            q.join()
    except KeyboardInterrupt:
        sys.exit(1)

`

No correct solution

OTHER TIPS

You have to call your program with at least two command-line arguments, like so:

python2 yourscript.py 23 42

Otherwise, the sys.argv array has less than 3 elements and you'll access it outside of its range.

It is good practice to explicitly check the number of command-line arguments before trying to access them:

if len(sys.argv) < 3:
  print "This program needs at least two arguments."
  sys.exit(1)

Then your program will print a useful error message instead of an ugly exception.

sys.argv list refers to command line arguments in python. On index 0, there is always your script name. Other higher indexes will contain whatever you pass as command line argument to the script. So you need to run it as

python script.py 2 4

where 2 is sys.argv[1] i.e numberOfviewers

and 4 is sys.argv[2] i.e builderThreads

python docs link : http://docs.python.org/2/library/sys.html

sys.argv is a list of command line arguments, where the first element is the script name.

In Python all lists are zero indexed, so if you try and access an element by its index (as you are doing with the square brackets after sys.argv), but the list does not have an element at that index, a IndexError is raised.

For example

>>> my_list = [1,2] 
>>> my_list[0]
1
>>> my_list[2]
IndexError: list index is out of range

So you aren't passing enough command line arguments when executing the script, hence the sys.argv list will not have a item at index 2, and Python will raise an IndexError.

So you could try and execute that line but catch the exception

try:
    builderThreads = int(sys.argv[2])
except IndexError:
    # do something appropriate after catch the exception

I also recommend you look at the argparse module, which is the "recommended command-line parsing module in the Python standard library"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top