|
From: Ronald D S. <rd...@ea...> - 2001-09-04 10:33:27
|
Thanks, Kevin. I will be quietly working on this in the background. Your pointers will be of help to me. Once I get a reasonable
facsimile of this running, I'll share it with the group.
And I'll probably have specific questions along the way.
Ron Stephens
----- Original Message -----
From: "Kevin Altis" <al...@se...>
To: <pyt...@li...>
Sent: Monday, September 03, 2001 9:04 PM
Subject: RE: [Pythoncard-users] Decision Analysis , a Python script to be re-coded in PythonCard
> The short answer is that you should be able to do this in PythonCard. When
> you run into specific problems related to PythonCard, just post the
> questions here. It sounds like a lot of your journey is going to be learning
> to design a non-modal visual interface for a program that was previously a
> linear series of steps. Off the top of my head I'm not sure what resources
> to point you towards, hopefully someone else on the list can provide some
> pointers.
>
> Validators:
> One thing that PythonCard definitely doesn't provide you with right now are
> 'validators' which are sort of like your 'get_number' function below. We'll
> probably have validators later, wxPython even provides a hook for them, but
> for now you'll probably want to make it more like an HTML form where the
> user enters input in a bunch of fields, and then presses a "Submit" or
> "Calculate" button and if one of the fields has invalid input you will
> present an error message and they can redo the input.
>
> You could also check the input with a 'loseFocus' handler and when we have a
> closeField messages being generated this will be even simpler; closeField
> means that not only did the field lose focus, but that the text changed too.
> Turn on the Message Watcher and uncheck 'Hide unused' to see these events
> occurring as you tab and click between fields.
>
> Anyway, in the short term what you can do is have a 'gainFocus' handler
> which saves the current value of the field in variable, then a 'loseFocus'
> handler which compares the original value to the current value and if they
> are different (text changed), then it will do your validation test and if
> the data isn't valid, you present an error dialog and then set the focus
> back to the field and select all the text. That is a very common user
> interface for text validation in GUIs. Other people on the list can probably
> suggest other methods.
>
> This is the kind of thing I'll try and add to one of the samples, unless
> someone beats me to it.
>
> ka
>
> > -----Original Message-----
> > From: pyt...@li...
> > [mailto:pyt...@li...]On Behalf Of Ronald
> > D Stephens
> > Sent: Monday, September 03, 2001 12:34 PM
> > To: pyt...@li...
> > Subject: [Pythoncard-users] Decision Analysis , a Python script to be
> > re-coded in PythonCard
> >
> >
> > Well, my first Python script or applet was a simple weighted
> > average type of program to help in making decisions that can be
> > analyzed by comparing various options for various criteria,
> > weighted by importance for each criteria, and scored by calculating a
> > simple weighted average for each option and then comparing the
> > scores for various options, with higher scores representing better
> > options.
> >
> > This program is a commnad line Python program that runs OK in
> > IDLE or Pythonwin.
> >
> > My goal is to make it work with a gui user interface. My thinking
> > is that this will be a good learning exercise for me in learning
> > PythonCard.
> >
> > I have previosuly tried to code a gui version of this in Tkinter,
> > but I became frustrated before I had a working version.
> >
> > I think PythonCard is already up to the task of coding a version
> > of my Decision Analysis. Am I right or is it too early for this?
> >
> > I realize that I will need to start from scratch and re-code this
> > completely, since the gui version is so much different; although I
> > welcome any comments to the contrary.
> >
> > I am thinking of using sliders for data entry, although I could
> > use other forms of data input, obviously.
> >
> > If any one has any comments, or general suggetions before I get
> > too far along on this project, please let me know.
> >
> > Since I am a newbie and busy with a full time job, this task may
> > take me awhile, so don't expect immediate results. But once I do
> > get it, maybe the results will be of use somehow. I doubt it
> > would be usefull enough to include in the samples of PythonCard, but
> > anyway, here I go....it's all about learning at this point.
> >
> > I caught on to Python easier than I expected, and I was pleased
> > to be able to do this simple program. But learning gui event driven
> > programming has been hard for me (I suppose learning to really
> > use classes, OOP, gui's and event driven programming all at once is
> > causing me confusion ;-)))). Anyway, I am determined to stick it
> > out with PythonCard though.
> >
> >
> > Ron Stephens
> >
> > #
> > # This is a decision analysis program that was my first real
> > Python program, based on weighted
> > # averages of scores on several criteria for various questions
> > that need to be decided.
> > # There is a general program for any kind of decision, allowing
> > user input of options
> > # to be decided amongst and criteria to use for decisions; and
> > then there are a few
> > # examples of specific options to be decided amongst with
> > pre-coded "values' or scores
> > # for the various options for various criteria.
> > # It is my goal to code this program using PythonCard.
> >
> >
> >
> > print "A General Decision Analysis Program."
> > print
> > print "Have You Ever Had to Make Up Your Mind?"
> > print
> >
> > import sys
> >
> > def get_number(prompt, lower=sys.maxint * -1, upper=sys.maxint):
> > """ 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.
> > Now checks for upper and lower bounds.
> > """
> > res = None
> > while res is None:
> > try:
> > res = float(raw_input(prompt))
> > try:
> > assert lower <= res <= upper
> > except AssertionError:
> > print "Value must be between", lower, \
> > "and", upper
> > res = None
> > except ValueError: pass
> >
> >
> > return res
> >
> >
> > def get_list(heading, prompt):
> >
> > print heading
> > print
> > print "(enter a blank line to end the list)"
> > ret = []
> > i = 1
> > while 1:
> > line = raw_input(prompt % i)
> > if not line:
> > break
> > ret.append(line)
> > i=i+1
> > print
> > return ret
> >
> > def get_user_rankings(criteria):
> > # 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.
> >
> > rankings = {}
> > print
> > print "Enter relative importance of criteria (higher is more
> > important)"
> > print
> > for c in criteria:
> > rankings[c] = get_number("Criterion %s: " % c)
> > return rankings
> >
> > def get_user_scores(options, criteria):
> > # Next, get the user to score each option on all the criteria.
> > # Scores are stored as a two-dimensional dictionary, like so:
> > # {'option1': {'criteria1': 100, 'criteria2': 10},
> > # 'option2': {'criteria1': 50, 'criteria2': 10}
> > # }
> > scores = {}
> > print
> > print "Enter score for each option on each criterion"
> > print
> > for o in options:
> > scores[o] = {}
> > print
> > print "Scores for option %s" % o
> > print
> > for c in criteria:
> > scores[o][c] = get_number("Criterion %s: " % c)
> > return scores
> >
> > def calculate_results(options, scores, rankings):
> > # 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 = {}
> > # Criteria can be found automatically, doesn't need to be
> > # passed as an argument.
> > criteria = scores[options[0]].keys()
> > for o in options:
> > value = 0
> > for c in criteria:
> > # print o, c, rankings[c], scores[o][c]
> > value = value + rankings[c] * scores[o][c]
> > result[o] = value
> > return result
> >
> > def ranked_list(results):
> > # Now, I want to take the dictionary result, and turn it into
> > a ranked list
> >
> > results = results.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
> > return results
> >
> >
> > def generic_decision_analyzer(options, criteria):
> > pass
> >
> > def decisionanalysis():
> > # This code is placed in the public domain
> > print
> > print "This is a general decision program, and you can define
> > your choices and criteria."
> > print
> > print "When prompted, please enter the options or choices
> > that you need to decide amongst."
> > print
> > print "Then, when prompted, enter the criteria for making
> > this decision."
> >
> >
> > # First, ask the user to enter the lists
> > options = get_list("Enter your options:", "Option %d: ")
> > criteria = get_list("Now, enter your criteria:", "Criterion %d: ")
> >
> > print "A program to help you make decisions."
> > rankings = get_user_rankings(criteria)
> > scores = get_user_scores(options, criteria)
> > results = ranked_list(calculate_results(options, scores, rankings))
> > print
> > print "Results, in order from highest to lowest score"
> > print
> > print "%5s\t%s" % ("Score", "Option")
> >
> > # Take the pairs out of results in order, and print them out
> > for option, result in results:
> > print "%5s\t%s" % (result, option)
> >
> >
> >
> > # Here's the scores used by the language-choice functions.
> > language_scores = {"Python": {"ease of learning":100,
> > "ease of use":100,
> > "speed of program execution":10,
> > "quality of available tools":70,
> > "popularity":50,
> > "power & expressiveness":100,
> > "cross platform?":100,
> > "cost":100},
> > "Perl": {"ease of learning":50,
> > "ease of use":60,
> > "speed of program execution":20,
> > "quality of available tools":50,
> > "popularity":85,
> > "power & expressiveness":70,
> > "cross platform?":100,
> > "cost":100},
> > "Ruby": { "ease of learning":50,
> > "ease of use":100,
> > "speed of program execution":20,
> > "quality of available tools":20,
> > "popularity":10,
> > "power & expressiveness":100,
> > "cross platform?":80,
> > "cost":100},
> > "Tcl": {"ease of learning":100,
> > "ease of use":100,
> > "speed of program execution":10,
> > "quality of available tools":50,
> > "popularity":40,
> > "power & expressiveness":10,
> > "cross platform?":100,
> > "cost":100},
> > "JavaScript": {"ease of learning":70,
> > "ease of use":75,
> > "speed of program execution":10,
> > "quality of available tools":50,
> > "popularity":100,
> > "power & expressiveness":40,
> > "cross platform?":50,
> > "cost":100},
> > "Visual Basic": {"ease of learning":50,
> > "ease of use":100,
> > "speed of program execution":20,
> > "quality of available tools":100,
> > "popularity":100,
> > "power & expressiveness":50,
> > "cross platform?":1,
> > "cost":1},
> > "Java": {"ease of learning":15,
> > "ease of use":50,
> > "speed of program execution":50,
> > "quality of available tools":100,
> > "popularity":90,
> > "power & expressiveness":100,
> > "cross platform?":100,
> > "cost":100},
> > "C++": {"ease of learning":10,
> > "ease of use":25,
> > "speed of program execution":90,
> > "quality of available tools":90,
> > "popularity":80,
> > "power & expressiveness":100,
> > "cross platform?":90,
> > "cost":100},
> > "C": {"ease of learning":15,
> > "ease of use":20,
> > "speed of program execution":100,
> > "quality of available tools":80,
> > "popularity":80,
> > "power & expressiveness":80,
> > "cross platform?":110,
> > "cost":100},
> > "Lisp": {"ease of learning":40,
> > "ease of use":50,
> > "speed of program execution":80,
> > "quality of available tools":60,
> > "popularity":25,
> > "power & expressiveness":110,
> > "cross platform?":80,
> > "cost":90},
> > "Delphi": {"ease of learning":50,
> > "ease of use":110,
> > "speed of program execution":85,
> > "quality of available tools":100,
> > "popularity":30,
> > "power & expressiveness":100,
> > "cross platform?":80,
> > "cost":10}
> > }
> >
> >
> >
> > def ProgramLanguageFinal():
> > print "This is a program to help give you an idea which
> > programming languages you should consider learning."
> > print "While there are any number of languages you might
> > consider, this program considers only 11 of the most popluar ones."
> > print
> > print "The program will ask you to input a ranking or
> > weighting for a number of criteria that may be of importance"
> > print "in choosing your next programming language."
> >
> > # First look up the criteria listed in the scores.
> > # To do that, we need a language name, which can also
> > # be looked up from the scores.
> > languages = language_scores.keys()
> > some_language = languages[0]
> > criteria = language_scores[some_language].keys()
> > rankings = get_user_rankings(criteria)
> > results = ranked_list(calculate_results(languages,
> > language_scores, rankings))
> > # Take the pairs out of results in order, and print them out
> > for option, result in results:
> > print "%5s\t%s" % (result, option)
> >
> >
> > def ProgramLanguageScript():
> > print
> > print "This is a program to help you choose a scripting language."
> > print
> > print "You will be asked to rank some important criteria as
> > to their relative importance to you."
> > print "These criteria are 'ease of learning', 'ease of use',
> > 'speed of program execution'"
> > "'quality of available tools', 'popularity', and 'power &
> > expressiveness'"
> > print
> > print "Please rank each of the criteria with a number from 1
> > to 100 when prompted."
> > print
> > print "100 means of highest relative importance, 1 means of
> > least importance."
> >
> > # This time we want a subset of languages, so I'm going to
> > specify them.
> > options = ["Python", "Perl", "Ruby", "Tcl", "JavaScript",
> > "Visual Basic"]
> > criteria = language_scores[options[0]].keys()
> > rankings = get_user_rankings(criteria)
> > results = ranked_list(calculate_results(options,
> > language_scores, rankings))
> > # Take the pairs out of results in order, and print them out
> > for option, result in results:
> > print "%5s %s" % (result, option)
> >
> >
> > def Basketball():
> > print "This is a program to help you decide which team will
> > win a basketball game"
> > print
> > print "When prompted, enter a number ranking each team on the
> > prompted team skill"
> > print "on a scale from 1 to 100, with 1 being terrible and
> > 100 being the best imaginable"
> > print
> > team_one = raw_input ("What is the name of team one: ")
> > team_two = raw_input ("What is the name of team two: ")
> > teams = (team_one, team_two)
> >
> > rankings = {"speed":100, "size":66, "jumping_ability":50,
> > "defense":60, "shooting":75, "ballhandling":50, "rebounding":50}
> > criteria = rankings.keys()
> > scores = {team_one: {},
> > team_two: {}}
> > for c in criteria:
> > for team in (team_one, team_two):
> > scores[team][c] = get_number("rank the team %s of %s
> > on a scale of 1 to 100: " % (c, team), 1, 100)
> >
> > results = calculate_results(teams, scores, rankings)
> > for team in teams:
> > print "%s has a power ranking of %d" % (team, results[team])
> > # Now, who won?
> > ranked_results = ranked_list(results)
> > # Compare the scores.
> > if ranked_results[0][1] == ranked_results[1][1]:
> > print "the two teams are a toss-up!!!"
> > else:
> > print "%s wins!!" % ranked_results[0][0]
> >
> >
> > def YesNo():
> > print "Program to help you make a Yes or No decision."
> > options = ["Yes", "No"]
> > criteria = get_list("Enter your criteria ...", "Criterion %d: ")
> >
> > rankings = get_user_rankings(criteria)
> > scores = get_user_scores(options, criteria )
> > print `scores`
> > results = ranked_list(calculate_results(options, scores, rankings))
> > print
> > print "The results are"
> > print
> > print "%5s %s" % ("Score", "Option")
> >
> > for option, result in results:
> > print "%5s %s" % (result, option)
> >
> > if results[0] > results[1]:
> > print "You should decide Yes!!!"
> >
> > else:
> > print
> > print "You should decide No!!!"
> > print
> >
> >
> > ###### MAIN LOOP ############
> >
> > while 1: # loop forever
> >
> > print "Please enter the number for the type of decision you
> > wish to analayze:"
> > print "1. General Decision Analysis, you choose the options,
> > criteria, etc."
> > print "2. Help in Choosing Programming Language amongst 11
> > popular languages"
> > print "3. Help in choosing scripting programming language
> > amongst 6 scripting languages"
> > print "4. Which Basketball Team will win the Game???"
> > print "5. Questions with Yes or No type answers"
> > choice = get_number("Please type in the number of the type of
> > decision-program you wish to run from above and hit enter:", 1, 5)
> >
> > if choice ==1:
> > decisionanalysis()
> > elif choice ==2:
> > ProgramLanguageFinal()
> > elif choice ==3:
> > ProgramLanguageScript()
> > elif choice ==4:
> > Basketball()
> > elif choice ==5:
> > YesNo()
> > elif choice =="quit":
> > break # exit from infinite loop
> > else:
> > print "Invalid operation"
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > _______________________________________________
> > Pythoncard-users mailing list
> > Pyt...@li...
> > https://lists.sourceforge.net/lists/listinfo/pythoncard-users
> >
>
>
> _______________________________________________
> Pythoncard-users mailing list
> Pyt...@li...
> https://lists.sourceforge.net/lists/listinfo/pythoncard-users
|