Problem with join in__str__() in class (newbie)

F

Fencer

Hello, I've written two classes. One class describes experts: experts
has a unique ID and a name. An expert knows topics and other experts. A
topic is described by my other class and includes a unique ID and a
name. Now I have a problem with the __str__ method in my Expert class:

def __str__(self):
output = '%s:%s' % (self.expert_id, self.name)
output += '\nKnown topics: %s' % (', '.join(str(self.topics)))
# print 'Known experts: '
# for e in self.known_experts:
# print '%s:%s' % (e.expert_id, e.name)
return output

self.topics is a list of objects of type Topic.
self.known_experts is a list of objects of type Expert, specifically the
experts known by the given expert.

When I print an object of type Expert, the output is not what I want. If
the expert knows only one topic, say polemics, the output is:
e2:Carla
Known topics: t, 5, :, P, o, l, e, m, i, c, s
If the expert knows two topics, say Polemics and The Parthenon, then the
output is:
e2:Carla
Known topics: [, <, _, _, m, a, i, n, _, _, ., T, o, p, i, c, , i, n,
s, t, a, n, c, e, , a, t, , 0, x, 0, 2, 2, 2, D, 0, 8, 0, >, ]

This is not what I want. :) I want the output like this:
e2:Carla
Known topics: t5:polemics, t6:The Parthenon

Also, notice the code I've commented out. If I can get the join above to
work (with your help) my next question is how to present the known
experts in a comma separated list with only expert_id and name? I can't
use the normal __str__() method (the one I'm writing here) because it
prints too much information. Does that mean a join is out of the question?

Thanks for any replies!

- Fencer
 
J

jon rascal

def __str__(self):
     output = '%s:%s' % (self.expert_id, self.name)
     output += '\nKnown topics: %s' % (', '.join(str(self.topics)))

You're turning your list into a string -- try this:
', '.join([str(x) for x in self.topics])
 
F

Fencer

jon said:
You're turning your list into a string -- try this:
', '.join([str(x) for x in self.topics])

Thanks for your quick reply, unfortunately it didn't quite work for me.
Say topics contain two topics: polemics, and the parthenon I get this
output:
e2:Carla
Known topics: t5:polemics

only the first topic is printed. If topics only contain a single topic I
get this error:
Traceback (most recent call last):
File "C:\Users\fencer\workspace\Find Expert\src\find_expert.py", line
57, in <module>
print experts[1]
File "C:\Users\fencer\workspace\Find Expert\src\find_expert.py", line
21, in __str__
output += '\nKnown topics: %s' % (', '.join([str(x) for x in
self.topics]))
TypeError: iteration over non-sequence

What did I do wrong?

- Fencer
 
M

MRAB

Fencer said:
jon said:
You're turning your list into a string -- try this:
', '.join([str(x) for x in self.topics])

Thanks for your quick reply, unfortunately it didn't quite work for me.
Say topics contain two topics: polemics, and the parthenon I get this
output:
e2:Carla
Known topics: t5:polemics

only the first topic is printed. If topics only contain a single topic I
get this error:
Traceback (most recent call last):
File "C:\Users\fencer\workspace\Find Expert\src\find_expert.py", line
57, in <module>
print experts[1]
File "C:\Users\fencer\workspace\Find Expert\src\find_expert.py", line
21, in __str__
output += '\nKnown topics: %s' % (', '.join([str(x) for x in
self.topics]))
TypeError: iteration over non-sequence

What did I do wrong?
Try printing self.topics. It should always be a list of topics.
 
F

Fencer

MRAB said:
Try printing self.topics. It should always be a list of topics.

Ah, yes, that made me find a bug when I was creating the Expert objects:
the lists of known topics were not created properly. I should have
posted more code I suppose! Thanks for the help, this problem has now
been solved. I guess I can't use a join to print the known experts as I
described in my first post.

- Fencer
 
P

Piet van Oostrum

Fencer said:
F> Also, notice the code I've commented out. If I can get the join above to
F> work (with your help) my next question is how to present the known experts
F> in a comma separated list with only expert_id and name? I can't use the
F> normal __str__() method (the one I'm writing here) because it prints too
F> much information. Does that mean a join is out of the question?
F> Ah, yes, that made me find a bug when I was creating the Expert objects:
F> the lists of known topics were not created properly. I should have posted
F> more code I suppose! Thanks for the help, this problem has now been solved.
F> I guess I can't use a join to print the known experts as I described in my
F> first post.

Yes, you can. But you need an additional method that gives only the id
and name. Like this:

------------------------------------------------------------------------
class Expert:
'''An expert'''
def __init__(self, id, name, topics):
self.expert_id = id
self.name = name
self.topics = topics
self.known_experts = []

def add_expert(self, expert):
self.known_experts.append(expert)

def __str__(self):
output = (self.brief_str() +
'\nKnown topics: %s' % (', '.join(map(str, self.topics))) +
('\nKnown experts: %s' %
(', '.join(exp.brief_str() for exp in self.known_experts))))
return output

def brief_str(self):
'''Gives a brief description of the expert: just the id and name.'''
return '%s:%s' % (self.expert_id, self.name)

class Topic:
'''A topic'''
def __init__(self, id, name):
self.topic_id = id
self.name = name

def __str__(self):
return '%s:%s' % (self.topic_id, self.name)

topic1 = Topic('t1', 'Relativity')
topic2 = Topic('t2', 'Math')
topic5 = Topic('t5', 'Polemics')
topic6 = Topic('t6', 'The Parthenon')

expert1 = Expert('e1', 'Albert', [topic1])
expert2 = Expert('e2', 'Leonhard', [topic2])

expert1.add_expert(expert2)

expert5 = Expert('e5', 'Carla', [topic5, topic6])
expert5.add_expert(expert1)
expert5.add_expert(expert2)

for ex in expert1, expert2, expert5:
print ex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top