繁体   English   中英

读取 csv 文件错误:sys.argv[1], IndexError: list index out of range

[英]Reading in csv file error: sys.argv[1], IndexError: list index out of range

我与一家学生经营的非营利组织合作,该非营利组织将大学生与小学生配对以进行指导。 一位老会员给我发了一个他们编写的用于创建拼车志愿者组的 python 脚本。 我正试图让它在我的笔记本电脑上再次工作。 它应该读取三个 csv 文件:一个用于新应用程序,一个用于返回应用程序,一个用于可用学校,然后它创建组并在输出文本文件中返回它们。

我无法弄清楚程序应该如何读取文件夹中的 cvs 文件。 我在下面粘贴了整个代码,但问题出在我认为的前 10 行。 我还包括了我即将结束的错误消息。

from csv import reader
import sys

# USE LIKE:
# python sealsort.py /path/to/newm/survey /path/to/retm/survey /path/to/school/doc
newm_path = sys.argv[1] #'./s18_new.csv'
returnm_path = sys.argv[2] #'./s18_return.csv'
schools_path = sys.argv[3] #'./s18_schools.csv'

def psble(schools, mems):
  # Calculates the number of people avaliable for volunteering
  avail = [0]*len(schools['schools'])
  espan = [0]*len(schools['schools'])
  engav = [0]*len(schools['schools'])
  # Ignore drivers in number of people
  for i in range(len(mems['names'])):
    if(mems['assgn'][i] or mems['drive'][i] > 0):
      continue
    for j in range(len(mems['avail'][i])):
      ts = mems['avail'][i][j]
      # Iterate over volunteering slots
      for k in range(len(schools['schools'])):
        if(schools['tid'][k] == ts):
          avail[k] += 1
          
  for i in range(len(mems['names'])):
    if(mems['assgn'][i] or mems['drive'][i] > 0):
      continue
    for j in range(len(mems['avail'][i])):
      ts = mems['avail'][i][j]
      # Iterate over volunteering slots
      for k in range(len(schools['schools'])):
        if(schools['tid'][k] == ts):
          espan[k] += mems['espan'][i]
          
  for i in range(len(mems['names'])):
    if(mems['assgn'][i] or mems['drive'][i] > 0 or mems['espan'][i] > 0):
      continue
    for j in range(len(mems['avail'][i])):
      ts = mems['avail'][i][j]
      # Iterate over volunteering slots
      for k in range(len(schools['schools'])):
        if(schools['tid'][k] == ts):
          engav[k] += 1
          
  return avail, espan, engav
        
def parsenew(newcsv, schools):
  # Parses the new member CSV file and returns a list of lists
  # Make lists to hold info
  order = []
  names = []
  avail = []
  drive = []
  espan = []
  assgn = []
  tasgn = []
  nasgn = []

  c = 0
  with open(newcsv,'rU') as f:
    for line in reader(f):
      if(line == []):
        continue
      order.append(c)
      c += 1
      names.append(line[1])
      avail.append(line[6])
      drive.append(line[7])
      espan.append(line[14])
      assgn.append(False)
      tasgn.append(-1)
      nasgn.append(-1)
  
  # Map spanish options to numbers
  for i in range(len(espan)):
    if(espan[i] == 'Not at all'):
      espan[i] = 0
      continue
    elif(espan[i] == 'Un poquito'):
      espan[i] = 0
      #names[i] += ' SPN-PQTO'
      continue
    elif(espan[i] == 'Conversational'):
      espan[i] = 2
      names[i] += ' SPN-CONV'
      continue
    elif(espan[i] == 'Fluent'):
      espan[i] = 4
      names[i] += ' SPN-FLNT'
      continue
   
  # Map time avaliability to numbers
  for i in range(len(avail)):
    alist = avail[i].split(',')
    avail[i] = [];
    for time in alist:
      time = time.split('(')[0].replace(' ','')
      if time in schools['tdict']:
        avail[i].append(schools['tdict'][time])
      else:
        print("Invalid time",time)
        
  # Map driving to numbers
  for i in range(len(drive)):
    print(drive[i])
    if(len(drive[i]) == 0):
      drive[i] = 0
      continue
    if(drive[i][0] != 'Y'):
      drive[i] = 0
    else:
      drive[i] = int(filter(str.isdigit, drive[i]))
      names[i] += ' DRIVER(' + str(drive[i]) + ')'
  
  odict = {'names': names, 'order': order, 'avail': avail, 'drive': drive, 'espan': espan, 'assgn': assgn, 'tasgn': tasgn, 'nasgn': nasgn}
  return odict

def parsereturn(returncsv, schools):
    # Parses the new member CSV file and returns a list of lists
  # Make lists to hold info
  order = []
  names = []
  avail = []
  drive = []
  espan = []
  assgn = []
  tasgn = []
  nasgn = []

  c = 0
  with open(returncsv,'rU') as f:
    for line in reader(f):
      if(line == []):
        continue
      order.append(c)
      c += 1
      names.append(line[2])
      avail.append(line[5])
      drive.append(line[6])
      espan.append(line[7])
      assgn.append(False)
      tasgn.append(-1)
      nasgn.append(-1)
  
  # Map spanish options to numbers
  for i in range(len(espan)):
    if(espan[i] == 'Not at all'):
      espan[i] = 0
      continue
    elif(espan[i] == 'Un poquito'):
      espan[i] = 0
      #names[i] += ' SPN-PQTO'
      continue
    elif(espan[i] == 'Conversational'):
      espan[i] = 2
      names[i] += ' SPN-CONV'
      continue
    elif(espan[i] == 'Fluent'):
      espan[i] = 4
      names[i] += ' SPN-FLNT'
      continue
   
  # Map time avaliability to numbers
  for i in range(len(avail)):
    alist = avail[i].split(',')
    avail[i] = [];
    for time in alist:
      time = time.split('(')[0].replace(' ','')
      if time in schools['tdict']:
        avail[i].append(schools['tdict'][time])
      else:
        print("Invalid time",time)
        
  # Map driving to numbers
  for i in range(len(drive)):
    if(len(drive[i]) == 0):
      drive[i] = 0
      continue
    if(drive[i][0] != 'Y'):
      drive[i] = 0
    else:
      drive[i] = int(filter(str.isdigit, drive[i]))
      names[i] += ' DRIVER(' + str(drive[i]) + ')'
  
  odict = {'names': names, 'order': order, 'avail': avail, 'drive': drive, 'espan': espan, 'assgn': assgn, 'tasgn': tasgn, 'nasgn': nasgn}
  return odict
  
def parseschools(schoolcsv):
  # Parses the schools CSV file and returns a list of lists
  # Make lists to hold info
  nvolu = []
  voday = []
  vtime = []
  schools = []
  
  with open(schoolcsv,'rU') as f:
    for line in reader(f):
      schools.append(line[1])
      nvolu.append(int(line[2]))
      voday.append(line[3].replace(' ',''))
      vtime.append(line[4].replace(' ',''))
  
  tidc = 0    
  tid = []
  tdict = {} 
  
  for i in range(len(voday)):
    key = voday[i]+vtime[i]
    if(key in tdict):
        tid.append(tdict[key])
    else:
      tdict[key] = tidc
      tidc += 1
      tid.append(tdict[key])
  
  odict = {'schools': schools, 'nvolu': nvolu, 'voday': voday, 'vtime': vtime, 'tid': tid, 'tdict': tdict}
  return odict
  
# Parse schools and make data structure
schools = parseschools(schools_path)
#for i in range(len(schools['schools'])):
#  print(schools['schools'][i],schools['nvolu'][i],schools['voday'][i],schools['vtime'][i],schools['tid'][i])
# Parse new members
newm = parsenew(newm_path, schools)

# Parse returning members
retm = parsereturn(returnm_path, schools)

print('total vols',len(retm['names'])+len(newm['names']))
mems = dict(retm)

for i in range(len(newm['names'])):
  mems['names'].append(newm['names'][i])
  mems['order'].append(newm['order'][i])
  mems['avail'].append(newm['avail'][i])
  mems['drive'].append(newm['drive'][i])
  mems['espan'].append(newm['espan'][i])
  mems['assgn'].append(newm['assgn'][i])
  mems['tasgn'].append(newm['tasgn'][i])
  mems['nasgn'].append(newm['nasgn'][i])

# Dict to hold assignments
assign = {}
assign['schools'] = schools['schools']
assign['voday'] = schools['voday']
assign['vtime'] = schools['vtime']
assign['vters'] = [ [] for i in range(len(schools['vtime']))]
assign['drvrs'] = [0]*len(schools['vtime'])
assign['cspot'] = [0]*len(schools['vtime'])
assign['espan'] = [0]*len(schools['vtime'])
assign['tid'] = schools['tid']

# Greedy algorithm to optimize driving assignment
# Iterate over their avaliable times, find the volunteering loc
# with the minimum number of people avaliable to fill it, but
# still equal to or greater than the number of people the car
# can carry
psvol, psesp, pseng = psble(schools, mems)
for i in range(len(mems['drive'])):
  #for i in range(len(assign['schools'])):     
  #  print(assign['schools'][i], assign['voday'][i], assign['vtime'][i], psvol[i], psesp[i])
  # If they cant drive, or ar assigned don't assign them
  if(mems['drive'][i] == 0) or mems['assgn'][i]:
    continue
  #print(mems['names'][i])
  minp = 999999
  minpi = -1
  for j in range(len(mems['avail'][i])):
    ts = mems['avail'][i][j]
    # Iterate over volunteering slots
    for k in range(len(schools['schools'])):
      # Find the loc with the minimum possible people, 
      if(schools['tid'][k] == ts and psvol[k] < minp and psvol[k] >= mems['drive'][i] and psesp >= 4 and schools['nvolu'][k] > mems['drive'][i] and pseng[k] > (mems['drive'][i] - 2)):
        minp = psvol[k]
        minpi = k
  #print("CHOICE")
  if(minpi == -1):
    #print("NO SOLUTION")
    continue
  #print(assign['schools'][minpi], assign['voday'][minpi], assign['vtime'][minpi], psvol[minpi], psesp[minpi])
  # Assign driver to place with min spots      
  assign['drvrs'][minpi] += 1
  #print(assign['cspot'][minpi], mems['drive'][i])
  assign['cspot'][minpi] += mems['drive'][i]
  schools['nvolu'][minpi] -= 1
  assign['vters'][minpi].append(mems['names'][i])
  assign['espan'][minpi] += mems['espan'][i]
  mems['assgn'][i] = True
  mems['tasgn'][i] = schools['tid'][minpi]
  mems['nasgn'][i] = minpi
  #print(assign['schools'][minpi], assign['voday'][minpi], assign['vtime'][minpi], assign['vters'][minpi],schools['nvolu'][minpi],assign['cspot'][minpi],psvol[minpi],psesp[minpi])
  
  # Assign non driving spanish speakers if necessary, first look for 1 fluent, then 2 conversational
  if(assign['espan'][minpi] < 4*assign['drvrs'][minpi]):
    for i1 in range(len(mems['espan'])):
      # If they can drive, are assigned, or are not fluent, skip them
      if(mems['drive'][i1] != 0 or mems['espan'][i1] != 4 or mems['assgn'][i1]):
        continue
        
      if(schools['tid'][minpi] in mems['avail'][i1]):
        assign['cspot'][minpi] -= 1
        schools['nvolu'][minpi] -= 1
        assign['vters'][minpi].append(mems['names'][i1])
        assign['espan'][minpi] += mems['espan'][i1]
        mems['assgn'][i1] = True
        mems['tasgn'][i1] = schools['tid'][minpi]
        mems['nasgn'][i1] = minpi
        break
        
  # Now try twice to put a conversational spanish person inif necessary
  if(assign['espan'][minpi] < 4*assign['drvrs'][minpi]):
    for i1 in range(len(mems['espan'])):
      # If they can drive, are assigned, or are not fluent, skip them
      if(mems['drive'][i1] != 0 or mems['espan'][i1] != 2 or mems['assgn'][i1]):
        continue
        
      if(schools['tid'][minpi] in mems['avail'][i1]):
        assign['cspot'][minpi] -= 1
        schools['nvolu'][minpi] -= 1
        assign['vters'][minpi].append(mems['names'][i1])
        assign['espan'][minpi] += mems['espan'][i1]
        mems['assgn'][i1] = True
        mems['tasgn'][i1] = schools['tid'][minpi]
        mems['nasgn'][i1] = minpi
        break
        
  # Second time on conversational
  if(assign['espan'][minpi] < 4*assign['drvrs'][minpi]):
    for i1 in range(len(mems['espan'])):
      # If they can drive, are assigned, or are not fluent, skip them
      if(mems['drive'][i1] != 0 or mems['espan'][i1] != 2 or mems['assgn'][i1]):
        continue
        
      if(schools['tid'][minpi] in mems['avail'][i1]):
        assign['cspot'][minpi] -= 1
        schools['nvolu'][minpi] -= 1
        assign['vters'][minpi].append(mems['names'][i1])
        assign['espan'][minpi] += mems['espan'][i1]
        mems['assgn'][i1] = True
        mems['tasgn'][i1] = schools['tid'][minpi]
        mems['nasgn'][i1] = minpi
        break
        
  # Fill in with non spanish speakers, try one time for each open seat
  for i in range(assign['cspot'][minpi]):
    #print("NEED MORE PEOPLE")
    for i1 in range(len(mems['espan'])):
      # If they can drive, are assigned, or are spanish speaking, skip them
      if(mems['drive'][i1] != 0 or mems['espan'][i1] > 0 or mems['assgn'][i1]):
        continue
        
      if(schools['tid'][minpi] in mems['avail'][i1]):
        assign['cspot'][minpi] -= 1
        schools['nvolu'][minpi] -= 1
        assign['vters'][minpi].append(mems['names'][i1])
        assign['espan'][minpi] += mems['espan'][i1]
        mems['assgn'][i1] = True
        mems['tasgn'][i1] = schools['tid'][minpi]
        mems['nasgn'][i1] = minpi
        break
    
  psvol, psesp, pseng = psble(schools, mems) 
  #print(assign['schools'][minpi], assign['voday'][minpi], assign['vtime'][minpi], psvol[minpi], psesp[minpi])
    
with open('output.txt','w') as f:
  for i in range(len(assign['schools'])):     
    f.write(assign['schools'][i] + " ")
    f.write(assign['voday'][i] + " ") 
    f.write(assign['vtime'][i] + "\n") 
    for j in range(len(assign['vters'][i])):
      f.write("\t" + assign['vters'][i][j] + "\n")
    f.write("\n")
  f.write("\n\nUNASSIGNED:\n")
    #print(assign['vters'][i], schools['nvolu'][i],assign['cspot'][i])
    #print(assign['cspot'][i])
    #print(schools['nvolu'][i])
    
  for i in range(len(mems['names'])):
    if(not mems['assgn'][i]):
      f.write(mems['names'][i] + "\n")

这是错误:

Traceback (most recent call last):
  File "/Users/myname/Desktop/sealsort/sealsort.py", line 9, in <module>
    newm_path = sys.argv[1] #'./s18_new.csv'
IndexError: list index out of range

您似乎正在尝试在 macOS 机器上运行此脚本。 我假设您将三个 CSV 文件与 Python 脚本放在同一个文件夹中。

您需要通过终端导航到存储文件的文件夹。 因此,首先打开终端应用程序,然后使用以下命令导航到文件夹: cd /Users/myname/Desktop/sealsort (这里我使用的路径与您的问题相同),然后您需要执行脚本如第一条评论所述:

# USE LIKE:
# python sealsort.py /path/to/newm/survey /path/to/retm/survey /path/to/school/doc

假设文件是​​:s18_new.csv、s18_return.csv、s18_schools.csv,执行脚本,指定这些文件的名称作为程序的参数。 如果您未指定任何必需的参数,则将找不到索引123处的元素之一,并且您将收到该错误( IndexError: list index out of range )。

所以,正确的命令是: python sealsort.py ./s18_new.csv ./s18_return.csv ./s18_schools.csv

这样,( argv的)索引0处的元素将是sealsort.py ,元素1将是s18_new.csv2将是s18_return.csv3将是s18_schools.csv

我希望这有帮助。

如 mkrieger1 发布的链接中所述, sys.argv[1] 引用了第一个命令行参数。 所以不要运行这样的命令:

蟒蛇程序.py

您需要使用以下三个参数运行它:

python program.py /path/To/first.csv /path/To/second.csv /path/To/third.csv




注意:第 5 行给出了一个使用示例

python sealsort.py /path/to/newm/survey /path/to/retm/survey /path/to/school/doc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM