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 |