Class inheritance

I’m learning class inheritance. Below is the code I copied from MIT tutorial. I can see the professor data was added to course6 one by one, but for some reason the print() command in the loop fails to iterate the course6 class. For your info, if I type print(grimson), it prints correctly. However, when I add a “for” loop before print, iteration doesn’t work. Can someone help?

class Prof(MITPerson): 
 def __init__(self, familyName, firstName, rank): 
  MITPerson.__init__(self, familyName, firstName) 
  self.rank = rank 
  self.teaching = {} 
 def addTeaching(self, term, subj): 
  try: 
    self.teaching[term].append(subj) 
  except KeyError: 
    self.teaching[term] = [subj] 
 def getTeaching(self, term): 
  try: 
    return self.teaching[term] 
  except KeyError: 
    return None 
 def lecture(self,toWhom,something): 
  return self.say(toWhom,something + ' as it is obvious') 
 def say(self,toWhom,something): 
  if type(toWhom) == UG: 
    return MITPerson.say(self,toWhom,'I do not understand why you say ' + something) 
  elif type(toWhom) == Prof: 
    return MITPerson.say(self,toWhom,'I really liked your paper on ' + something) 
  else: 
    return self.lecture(something)

class Faculty(object): 
 def __init__(self): 
  self.names = [] 
  self.IDs = [] 
  self.members = [] 
  self.place = None 
 def add(self,who): 
  if type(who)!= Prof: raise TypeError('not a professor') 
  if who.getIdNum() in self.IDs: raise ValueError('duplicate ID') 
  
  self.names.append(who.familyName()) 
  self.IDs.append(who.getIdNum()) 
  self.members.append(who) 
 def __iter__(self): 
  self.place = 0 
  return self 
 def next(self): 
  if self.place >= len(self.names): 
    raise StopIteration 
  self.place += 1 
  return self.members[self.place-1]

grimson = Prof('Grimson','Eric', 'Full') 
lozano = Prof('Lozano-Perez', 'Tomas', 'Full') 
guttag = Prof('Guttag', 'John', 'Full') 
barzilay = Prof('Barzilay', 'Regina', 'Associate') 
course6 = Faculty() 
course6.add(grimson) 
course6.add(lozano) 
course6.add(guttag) 
course6.add(barzilay)

for p in course6: 
  print(p)

Change the name of the method next to __next__

Also please don’t be cruel to your readers. Use four spaces for indents, not one.

If you are using a proper programmer’s editor (not Notepad), you can use the TAB key to indent to the next multiple of four spaces, and SHIFT-TAB to reduce the indentation.

Leaving a blank line between methods is nice too.

Thank you so much! The change from next to __next__ solved the problem.

1 Like

Note taken. I copied codes from pdf to colab notebook, the tab key generates 1 space in some cases. Not sure about the reason.

May I ask another question: in the Faculty class, some new variables are created. How can I print out those variable?
Here is my try which doesn’t work:
step 1. add a function in Faculty class

def getNames(self):
   return self.names

step 2. write a print command

for p in course6:
  print(p.getnames())

You’ve added that getNames method to the Faculty class, but the objects returned while iterating over a faculty come from its members list, so it should be:

print(course6.getNames())

I still got an error message by following your code - print(course6.getNames()).

Here is the full script from MIT tutorial. Maybe that can be of help.

You didn’t say what error message you got. It worked for me!

By the way, that tutorial is dated “Fall 2008” and it’s written in Python 2, which has since reached its end-of-life. That’s why, for Python 3, you needed to change the print calls to include parentheses and change def next(self): to def __next__(self):. Also, you don’t need to give the base class as object any more, so class Person(object): can now be class Person:.

Many thanks, Matthew.

My bad, print(course6.getNames()) works on my side now. I didn’t remove the line “for p in course6:” before the print() command, that caused the previous error.