Newbie needs help to find bug in his first Perl program

Jeff Epler jepler at
Tue Mar 27 03:19:01 CEST 2001

On Mon, 26 Mar 2001 04:24:14 GMT, Ron Stephens
 <rdsteph at> wrote:
>This is a multi-part message in MIME format.
>Content-Type: text/plain; charset=us-ascii
>Content-Transfer-Encoding: 7bit
>Thanks, Richard, you solved my problem, despite my fuzzy question ;-))) and
>to the rest of you, yes, I will try to be much more careful and precise from
>now on when asking for help! Point acknowledged.

To help introduce you to the power of Python, I have written a program with
a similar intent to yours.  It lets a user enter any number of options
and criteria, but it uses some of Python's versatile data types (mostly
the "dictionary", but a few lists), functions, and loops to reduce the
amount of code which must be repeated by the programmer (imagine when your
client asks you to make your program support 99 options and 100 criteria!
Without loops, that's well over 10,000 lines the programmer has to write).

I've tried to add comments that will explain what is going on.  I think
that almost all of the ideas in this program are present in the Tutorial
document.  The "sort" at the end is probably the hardest to understand.

Good luck with Python!

# This code is placed in the public domain

def get_list(heading, prompt):
	""" get_list(heading, prompt) -> list

This function prompts for a list of things.  The heading is printed on
a line by itself, and the prompt must have a %d substitution for the
number of the item within the list.
	print heading
	print "(enter a blank line to end the list)"
	ret = []
	i = 1
	while 1:
		line = raw_input(prompt % i)
		if not line:
	return ret

def get_number(prompt):
	""" get_number(prompt) -> float

This function prompts for a number.  If the user enters bad input, such as
"cat" or "3l", it will prompt again.
	res = None
	while res is None:
			res = float(raw_input(prompt))
		except ValueError: pass
	return res

# First, ask the user to enter the lists
options = get_list("Enter your options", "Option %d: ")
criteria = get_list("Enter your criteria ...", "Criterion %d: ")

# Next, get the user to rank his criteria.  I use a system where higher
# is better, so that an undesirable characteristic can be given a negative
# weight.
# {} is a dictionary, it can be indexed by (nearly) any expression,
# and we will index it with the names of the criteria.
# (For a more traditional program, we could use a list and index by the
# number of the criterion)

rankings = {}
print "Enter relative importance of criteria (higher is more important)"
for c in criteria:
		rankings[c] = get_number("Criterion %s: " % c)

# Next, get the user to score each option on all the criteria.
# Here, we index the dictionary on the pair (option, criterion).
# This is similar to a two-dimensional array in other languages

score = {}
print "Enter score for each option on each criterion"
for o in options:
	print "Scores for option %s" % o
	for c in criteria:
		score[o, c] = get_number("Criterion %s: " % c)

# Calculate the resulting score for each option.  This equation
# is different from Rod Stephen's original program, because I
# make more important criteria have higher rankings, and even let
# bad criteria have negative rankings.

# The "result" dictionary is indexed with the names of the options.
result = {}
for o in options:
	value = 0
	for c in criteria:
		print o, c, rankings[c], score[o, c]
		value = value + rankings[c] * score[o, c]
	result[o] = value

# Now, I want to take the dictionary result, and turn it into a ranked list.
results = result.items()	# A list of tuples (key, value)
results.sort(lambda x, y: -cmp(x[1], y[1]))
				# Sort the list using the reverse of the
				# "value" of the entry, so that higher
				# values come first

print "Results, in order from highest to lowest score"
print "%5s %s" % ("Score", "Option")

# Take the pairs out of results in order, and print them out
for option, result in results:
	print "%5s %s" % (result, option)

More information about the Python-list mailing list