Author Topic: BEGINNING COMPUTER PROGRAMMING (using HLA and Python 3 and C++)  (Read 44221 times)

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
BEGINNING COMPUTER PROGRAMMING
(using HLA and Python and C/C++)


Update:  FREE homework help NOW available ...

You can contact me via:
http://sites.google.com/site/andeveryeyeshallseehim/home/he-comes
(See e-mail link near bottom of front page)
http://developers-heaven.net/forum/index.php?topic=2587.0
http://developers-heaven.net/forum/index.php/board,9.0.html



Chapter 1 (with HLA - a very user friendly High Level Assembly) STARTS at this
NOW, (2013-05-23 ), NEW link ...
http://developers-heaven.net/forum/index.php?topic=2607.0


Chapter 1 (with C++) STARTS at this link ...
http://developers-heaven.net/forum/index.php/topic,127.0.html

     Also see ...  Six Fast Steps to Programming in C 
http://developers-heaven.net/forum/index.php/topic,2022.0.html

     Also see ... Six Fast Steps to Programming in C++
http://developers-heaven.net/forum/index.php/topic,2019.0.html


Chapter 1 (with Python) STARTS below ...


(And here is the main HLA download page/link so that you can get HLA installed right now on your computer ...
http://216.92.238.133/Webster/

The HLA download/install links are also given at the top of Chapter 1 with HLA.

The Python download link is given below.)


Below is a copy of the introduction to Beginning Computer Programming (with HLA) ...


BEGINNING COMPUTER PROGRAMMING
 
(Using a Try it and See it approach)

(AND ... a Computer Student's/Teacher's DREAM Introductory Computer Language - HLA)

Introduction:

To facilitate the solid insights provided in learning about computing by some exposure to Assembly Language, but also to provide a friendly and facile start for new programmers, HLA provides all the facility and power of Assembly Language, but with a user friendly syntax, yet offers many of the elegant structures of an HLL (High Level Language) like Pascal or C or even the OOP of a language like C++.  And so, going on to C, or C++, or any other modern HLL, will be more readily enabled, and with some real appreciation of what’s going on under the hood and inside the machine.

The author has successfully taught Computer Programming at a Canadian grade 7/8 Junior High and 9 to 12 High School level when PCs first became available using varied approaches, including using a personally authored simulated SIMPLE SIMON compiler running on a PC.   But his final approach, after which this course is being patterned, was the most fun, and also the most successful, for both students ... and teacher.

Please enjoy and profit from your work. Don't be afraid to make changes and see what happens.  Now dig in ... You may be surprised how much you will learn.

Shalom shalom,

David W. Zavitz
Toronto, Ontario, CANADA
dwzavitz@gmail.com

For arrangements to use this text beyond individual personal use, please contact the author at the above e-mail.

© (C) 2007-08-17

Acknowledgements:

This course and text would not be possible without the very gifted insights, teaching experiences, and programming skills of Randall Hyde,

http://en.wikipedia.org/wiki/Randall_Hyde

the Author, Creator, and so far, the Sustainer of HLA. I also would like to acknowledge the tremendous encouragement given by my youngest son Matthew, who's recent Engineering need to know a little C++, and then Assembly ... provided the incentive for a little more then that, from dad, (which led to HLA and now this attempt to benefit beginning computer students in general.)  Also, I would like to thank my students at Scarborough Christian High School, who besides being very promising young ladies and gentlemen, provided exemplary feedback as we went along into some not yet fully charted territory.

Table of Contents:

Chapter 01: The Computer prints a message
Chapter 02: The Computer gets some input
Chapter 03: The Computer adds some numbers
Chapter 04: The Computer repeats a procedure
Chapter 05: The Basic Elements of computer programming … and low level example(s)
Chapter 06: The Computer rolls the dice … a first simulation
Chapter 07: First Memory Flow Lab
Chapter 08: Memory Flow Lab2
Chapter 09: Memory Flow Lab3
Chapter 10: HLA Data Types
Chapter 11: The Computer does some Algebra with real numbers ... and Input Data Validation
Chapter 12: Pointers, Strings, your own Types, Records, Arrays, and dynamic things on the fly!
Chapter 13: The Computer files its Records
Chapter 14: The Computer reads its Files
Chapter 15: The Computer updates (edits, deletes, sorts, chops-duplicates-in) its Files
Chapter 16: The Computer … vast OS’s … and the garbage collects?  (Operating Systems ... what is DOS?)
Chapter 17: The Computer delivers daily Manna ... (gui Canadien ... eh?)
Chapter 18: OOP ... goes the computer?
Chapter 19: OOP 2
Chapter 20: Shaping Moving OOP ...

More to follow …  ?


Go to this link to continue ...

http://developers-heaven.net/forum/index.php?topic=2607.0


(Or ...  the first beta Google Doc ...)

http://docs.google.com/View?docID=d674v6b_21hfm8nm&revision=_latest&pli=1




« Last Edit: November 13, 2013, 09:52:48 AM by David »

Offline admin

  • Administrator
  • Sr. Member
  • *****
  • Posts: 296
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA)
« Reply #1 on: August 25, 2008, 10:14:39 PM »
Thanks David.

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #2 on: August 26, 2008, 05:51:00 AM »
I've been thinking that this FREE online e-book Beginning Computer Programming might be more useful to Beginning Computer Science Students ... and thus have a much broader appeal ... IF ... it compared/contrasted many of the HLA (High Level Assembly) programs given there ... with a comparable program ... programmed in Python ... because Python seems to be increasingly popular, and used by both Computer Science types AND NON Computer Science types, for a Beginning Computer Programming Language ...  This would give Computer Science types, (or possible Computer Science types), an easy and excellent and early and FREE taste of the most portable and powerful Machine Language Programming software presently available - HLA - High Level Assembly ... and a jump-start and a much broader exposure and depth of insight into Computer Programming in general ... by some 'hands on' contrasting the very High Level Python programming language with High Level Assembly - HLA.

So ... here goes an attempt :)

(Note: This new link, added March 2009, for even further enrichment for eager beginning CS students ...

http://developers-heaven.net/forum/index.php/topic,127.0.html

... to see the recently added C/C++ version(s) of Beginning Computer Programming ... since C/C++ is still very widely taught/used in many Universities and Colleges.)
« Last Edit: March 20, 2009, 08:39:12 PM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #3 on: August 26, 2008, 09:33:50 AM »
Here are the Python versions of the programs in the first 4 chapters of ...

BEGINNING COMPUTER PROGRAMMING

Note how much is done for you by this very High Level Language.  By comparing it with the HLA versions ... you may start to see how much is really going on 'under the hood' inside your computer :)

Note: In Python, you do NOT need to place a ; (semi-colon) character to indicate you have finished a statement, but you may if you wish, since Python permits it.  However the only place a semi-colon is commonly used to end a statement in Python, is to end preceding statements, when you place more than one (short) statement on a line.  See this next example:

myRealTotal = 0.0; myIntCountBak = myIntCounter = 0 # initialize these values to 0.0 and 0 respectively #


Here is the Download Link to the most recent version of Python for you to install,

(with the GUI Python IDE ... IDLE),

in the folder, (if using Windows ),

C:\Python


Then from IDLE ...  you can use File -> New -> Edit -> Paste to create

and then ...

run/save each Python program.


Now ... Here are those promised Python versions of the programs, for the first 4 chapters ...




Chapter 01: The Computer prints a message


Code: [Select]
# print_message.py
print("Hello World!")

Now copy and paste the above two lines into a New Window in Idle. In Idle use: File -> New -> Edit -> Paste

Then Run/Save with the file name: print_message.py

Simple ... eh?




Chapter 02: The Computer gets some input


Code: [Select]
# getInput.py
# comments may be inserted into Python programs after a '#'

first_name = input( "Please enter your first name : " )
last_name = input( "Now enter your last name     : " )
print("Are you really", last_name, ",", first_name, "?") # default formatting
print("Are you really {0}, {1}?".format(last_name, first_name)) # exact formatting
print("Are you really ", last_name, ", ", first_name, "?", sep='')

# Notes: See the use of {0} inside a Python formatting STRING  like " ... {0} ... "
# Each '{n}' is replaced by the string that follows in the .format(str1, str2, strn ... ) part of the statement.
# If you want to insert numbers, instead of 's', use 'd' for integers or 'f' for floating point decimal numbers
# You could use the Python supplied IDE, i.e the IDLE Shell, to enable yourself to quickly
# SEE the effect of the format string in the following Python print statement:

# ...................... < for left justify is new in Python 3
print("***{0:10.2f} = {1:<14.5f} = negative of {2:<+14.5f}***".format( 12345.6789, 12345.6789, -12345.6789 ))

# Try it ... and see what happens ?


The following was my 'output' using the IDLE 'Python Shell' :

Code: [Select]
IDLE 3.0      
>>> print("***{0:10.2f} = {1:<14.5f} = negative of {2:<+14.5f}***".format( 12345.6789, 12345.6789, -12345.6789 ))
***  12345.68 = 12345.67890    = negative of -12345.67890  ***
>>>





Chapter 03: The Computer adds some numbers


Code: [Select]
# add_nums.py

# Declare three integer variables in the Python memory space
# Note: Variables are dynamically assigned a type in Python

num1 = 23 # initialize num1 to 23
print(num1, "is type({n}) =".format(n=num1), type(num1))
num2 = 77 # initialize num2 to 77
newSum = num1 + num2
print(num1, "+", num2, "=", newSum)

num1 = input("\nEnter an integer : ") # num1 is type str
print("type({n}) =".format(n=num1), type(num1))
num2 = input( "Enter an integer : " ) # num2 is type str
print(num1, "+", num2, "=", num1 + num2, "(as strings)")
print(num1, "+", num2, "=", int(num1) + int(num2), "(as integers)")

num1 = float(input( "\nEnter a decimal : ")) # num1 is type float
print("type({n}) =".format(n=num1), type(num1))
num2 = int(input( "Enter an integer : " ))
print(num1, "+", num2, "=", num1 + num2)
print("type({0}+{1}) =".format(num1,num2), type(num1+num2))

dummy = input( "\nPress 'Enter' to continue ... ")
import sys
try:
    print("type(num3) =", type(num3)) # error ... 'num3' is not defined
except:
    print(sys.exc_info()) # prints error info and doesn't crash

num1 = int(input( "\nEnter an integer : " )) # num1 is type int
print("type({n}) =".format(n=num1), type(num1))
num2 = input( "Enter an integer : " )
print("type({n}) =".format(n=num2), type(num2))
print(num1, "+", num2, "=", num1 + num2) # error, mixed types
print ("type({0}+(1}) =".format(num1,num2), type(num1+num2)) # error ...




Chapter 04: The Computer repeats a procedure


Code: [Select]
# repeat_procedure.py

done = False
print("type(done) =", type(done))

# The following Python function asks for two integers to be entered ...
# and then prints out the two integers that were input ... and their sum.

def get_nums_find_sum(): # This marks the START line of a Python FUNCTION definition. #
    num1 = eval(input( "Enter an integer : " ))
    num2 = eval(input( "Enter an integer : " ))
    print("The sum of", num1, "and", num2, "is", num1 + num2) # END indicated by DEdent of next line. #


while not done: # This marks the top line of the Python WHILE LOOP structure #
    get_nums_find_sum() # now execute the function we defined above
    reply = input("\nMore (y/n) ? ")
    if  reply[0:1] == 'n' or reply[0:1] == 'N':
        done = True


# NB! Indentation is critical to Python.
# Each level of indentation [b]must be the same.[/b]
# Either use all spaces or all tabs.

# It is an error if both tabs and spaces are used ... If your indents don't line up,
# your program WILL CRASH with an error message.  THIS, unfortunately, may be a recurring
# PROBLEM when programming in Python. It may be managed better, by writing your code using the
# Python IDE ... the IDLE Shell ... and after the : (i.e. the semi-colon) ends a beginning statement line
# in a block ... then press the RETURN/ENTER key to have IDLE automatically go in to the NEXT INdent level.
# Then ... when your block of code is finished ... press the BACKSPACE key to DEdent to the PREVIOUS.

# A Python BLOCK of code is DELIMITED by its indentation ...
# INDENT to NEXT level IN ... to indicate the START of the block of code
# DEDENT to PREVIOUS level OUT ... to indicate a BLOCK is FINISHED.

# NOTE how the indentation DELIMITS the BLOCKS in the above Python program.

# Adding blank lines in your code, especially at the end of blocks, though not necessary,
# may help make your program more readable, ... and thus much easier to maintain.




You can also try going to a command line and running your xxxx.py scripts from there.  Here is an example of a Python script (program) run from the command line ...

Code: [Select]
C:\Python>print_message.py
Hello World!

C:\Python>




Note: For Chapter 05, please see the HLA Chapter 05 at ...

http://docs.google.com/View?docID=d674v6b_21hfm8nm&revision=_latest&pli=1

Or the C++ version of Chapter 05 here ....

http://developers-heaven.net/forum/index.php/topic,127.msg234.html#msg234

BEGINNING COMPUTER PROGRAMMING (using C++ or C)
   
Chapter 05 : The Basic Elements of a program ...


So far … we have

1. executed instructions in sequence,
2. executed a block of instructions if and only if a certain condition was met using an if... elif... else... structure,
3. repeatedly executed a block of instructions until a condition was met
4. labelled a block of instructions with a function name, and called for the execution of that block of instructions by using the function name as a command to execute that block, at the place where it is called from, in our program.

You may be surprised that all programs are mostly just various combinations of the above.

...
« Last Edit: December 30, 2009, 01:02:05 PM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #4 on: August 26, 2008, 12:57:48 PM »
This is the Python version of the programs for ...




Chapter 06: The Computer rolls the dice … a first simulation


I.   Announce what the program is about.
II.  Ask the user to input a guess in the range 2-12.
III. Get the computer to select randomly a number in that range.
IV.  See if the number guessed matches the total on the die that the computer rolled
V.   Report the results
VI.  Ask if user wants to try again … or quit




Ok ... let's get a 'shell' or 'bare-bones' program ... started:
 
Code: [Select]
# guessIt.py
 
def playgame(): # Note: function playgame is the main game. #
    print("\nTHE COMPUTER will roll the dice AFTER" \
          " YOU ENTER a number in the RANGE 2..12" \
          "\nOk ... what is your guess:", end=' ')
    userNum = input()
    print("You entered", userNum)
'''
    The following tasks are yet to be coded:
    1. get two random numbers in range 1..6, (one number for each die)
    2. see if sum of die matches the number the user guessed
    3. report success or falure
'''


done = False
while not done:
    playgame()
    reply = input( "\nPlay again (y/n) ? " )
    if reply[0:1] == 'n' or reply[0:1] == 'N':
        done = True



Yes ... It runs ok so far, but did you notice that the user can enter numbers that are way out of range?

Let’s fix that this way: (We will pass the value to a function to validate it.)

Code: [Select]
def isValid( x ): # This 'function' returns 'True' if x <= 12, otherwise it returns 'False'. #
    if x <= 12:
        return True
    # if didn't exit above ...
    return False



Now let’s plug that in and check it out so far ...

Code: [Select]
# guessIt2.py

def isValid( x ): # This 'function' returns 'True' if x <= 12, otherwise it returns 'False'. #
    if x <= 12:
        return True
    # if didn't exit above ...
    return False

def playgame(): # Note: function playgame is the main game. #
    print("\nTHE COMPUTER will roll the dice AFTER" \
          " YOU ENTER a number in the RANGE 2..12" \
          "\nOk ... what is your guess:", end=' ')
    while 1: # i.e. repeat forever ... until break reached inside
        userNum = int(input())
        if isValid( userNum ):
            break
        # else ...
        print("Your guess 2..12 :", end=' ')
    print("You entered", userNum)
'''
    The following tasks are yet to be coded in this function:
    1. get two random numbers in range 1..6, (one number for each die)
    2. see if sum of die matches the number the user guessed
    3. report success or failure
'''


done = False
while not done:
    playgame()
    reply = input( "\nPlay again (y/n) ? " )
    if reply[0:1] == 'n' or reply[0:1] == 'N':
        done = True


 
So far ... so good. But let’s do some research on the Python random function ...

When I did a web search using the key words Python random, here is what came up near the top, just now (2008-08-26):


http://effbot.org/pyfaq/how-do-i-generate-random-numbers-in-python.htm


How do I generate random numbers in Python?

The standard random module implements a random number generator. Usage is simple:

import random
print random.random()

This prints a random floating point number in the range [0, 1) (that is, between 0 and 1, including 0.0 but always smaller than 1.0).

There are also many other specialized generators in this module, such as:

    * randrange(a, b) chooses an integer in the range [a, b).
    * uniform(a, b) chooses a floating point number in the range [a, b).
    * normalvariate(mean, sdev) samples the normal (Gaussian) distribution.



 
Now let’s see if we can plug it in and get it working in our program ... (and notice some changes? / deletions? / improvements? ... that were made also.)


Code: [Select]
# guessIt3.py

def isValid( x ): # This 'function' returns 'True' if 2<= x <= 12, otherwise it returns 'False'. #
    if x >= 2 and x <= 12:
        return True
    # if didn't exit above ...
    return False

def playgame(): # Note: function playgame is the main game. #
    import random
    print("\nTHE COMPUTER will roll the dice AFTER" \
          " YOU ENTER a number in the RANGE 2..12" \
          "\nOk ... what is your guess:", end=' ')
    while 1: # i.e. repeat forever ... until break reached inside
        userNum = int(input())
        if isValid( userNum ):
            break
        # BUT ... if we did NOT 'break' out of the 'while' loop just above ... THEN ...
        print("Your guess 2..12 :", end=' ')
    # Get two random numbers 1..6 for each die.
    die1 = random.randrange( 1, 7 ) # returns random num 1..6 in die1
    die2 = random.randrange( 1, 7 ) # returns random num 1..6 in die2
    sumdie = die1 + die2      
    print("You entered", userNum, "and the computer rolled", \
          die1, "and", die2, "or", sumdie)
'''
    The following tasks are yet to be coded in this function:
    2. see if sum of die matches the number the user guessed
    3. report success or falure
'''


done = False
while not done:
    playgame()
    reply = input( "\nPlay again (y/n) ? " )
    if reply[0:1] == 'n' or reply[0:1] == 'N':
        done = True

 

Well, these functions are working ok ... but let’s make some more enhancements:

Let’s add a counter to keep track of the number of games. And suppose that you started out with so many cents, say 100, at the beginning and win the number of cents, (the value you guessed), when there is a match ... but lose the number (the same number of cents) you guess for the sum of the dice if there is NO match ...

The game will be over when all your starting cents are used up, ... or ... if you choose to quit, (or if by some long shot, the computer loses all its cents!)

Make a final report of the success or failure. (What you started out with. How much you were up/down. Your new total and the computers new total. The number of games played.)

Are you ready to start programming?



Code: [Select]
# guessIt4.py

def isValid( x ): # This 'function' returns 'True' if 2 <= x <= 12, otherwise it returns 'False'. #
    if  2 <= x <= 12:
        return True
    # if didn't exit above ...
    return False

def playgame(): # Note: function playgame is the main game. #
    global cCents, pCents # This GLOBAL declaration is used here so that
                                  # cCents, pCents are NOT new LOCAL variables
    import random
    print("\nTHE COMPUTER will roll the dice AFTER" \
          " YOU ENTER a number in the RANGE 2..12" \
          "\nOk ... what is your guess:", end=' ')
    while 1: # i.e. Repeat forever ... until break reached inside.
        userNum = int(input())
        if isValid( userNum ):
            break
        # BUT ... if we did NOT 'break' out of the 'while' loop just above ... THEN ...
        print("Your guess 2..12 :", end=' ')
    # Get two random numbers 1..6 for each die.
    die1 = random.randrange( 1, 7 ) # returns random num 1..6 in die1
    die2 = random.randrange( 1, 7 ) # returns random num 1..6 in die2
    sumdie = die1 + die2
    if sumdie == userNum:
        print("MATCH!") # report
        pCents = pCents + userNum # player wins                          
        cCents = cCents - userNum # computer loses
    else:
        print("NO match!") # report failure
        pCents = pCents - userNum # player loses
        cCents = cCents + userNum # computer wins        
    print("You entered", userNum, "and the computer rolled", \
          die1, "and", die2, "or", sumdie)



print("\nComputer stakes 100..1000 (cents) :", end=' ')
cCents = int(input())
if cCents < 100:
    cCents = 100  # don't allow values less than 100
if cCents > 1000:
    cCents = 1000 # don't allow values more than 1000
cStake = cCents

print("Player stakes 100..1000 (cents) : ", end=' ')
pCents = int(input())
if pCents < 100:
    pCents = 100
if pCents > 1000:
    pCents = 1000
pStake = pCents


done = False
numGames = 0
while not done:
    numGames = numGames +1
    playgame()
    reply = input( "\nPlay again (y/n) ? " )
    if reply[0:1] == 'n' or reply[0:1] == 'N' \
       or pCents <= 0 or cCents <= 0:
        done = True


# Don't allow, (i.e. correct for), 'in-hole' situations ...
if pCents < 0:               # player in hole
    cCents = cCents + pCents # i.e. decrease computer balance
    pCents = 0               # so now can up balance of player to zero
else:
    if cCents < 0:          # computer in hole
        pCents = pCents + cCents # decrease player balance
        cCents = 0          # so now can up balance of computer to zero

print("\nAfter", numGames, "games, the computer has", cCents, "cents", \
      "\nand the player has", pCents, "cents")

cWins = cCents - cStake # calculate the computer winnings

pWins = pCents - pStake # calculate the player winnings


if( cWins > 0 ): # computer wins
    print("The computer wins", cWins, "and the player loses", -pWins)

else: # computer loses
    print("The player wins", pWins, "and the computer loses", -cWins)



Code: [Select]
# guessIt5.py

'''
   This version passes in values to the function playgame AND RETURNs the UPDATED
   values ... to then update the values, outside, that were passed in.  Note the method
   used here ... instead of declaring variables inside a Python function, as GLOBAL, as above.
   Recall that "guessIt4.py" declared 2 variables inside the function playgame as GLOBAL.
'''

def isValid( x ): # This 'function' returns 'True' if 2 <= x <= 12, otherwise it returns 'False'. #
    if 2 <= x <= 12:
        return True
    # if didn't exit above ...
    return False

'''
Some more particulars about Python Functions (Edited from):

http://www.poromenos.org/tutorials/python

Functions are declared with the "def" keyword. Parameters are
passed by reference, but immutable types (tuples, ints, strings,
etc) cannot be changed. This is because only the memory location
of the item is passed, and binding another object to a variable
discards the old one, so immutable types are replaced. For named
arguments, the name of the argument is assigned a value.

Functions may return several values ... (see example in "guessIt5.py" ... above.)

Lambda functions are ad hoc functions that are comprised of a single statement.  
See the following example:

# def f(x): return x + 1
# is the same as ...
f2 = lambda x: x + 1
>>> print f2(1)
2
'''


'''
   Note: Function playgame is the main game. Note that the values of
   cCents and pCents get updated, and the new values are returned.
'''

def playgame( cC, pC ): # # # # # # # START of function playgame  # # # # # # #

    import random # calls to 'random.randrange( v1, v2 )', etc., are NOW available here
    print("\nTHE COMPUTER will roll the dice AFTER" \
          " YOU ENTER a number in the RANGE 2..12" \
          "\nOk ... what is your guess:", end=' ')
    while 1: # i.e. repeat forever ... until break reached inside
        userNum = int(input())
        if isValid( userNum ):
            break
        # BUT ... if we did NOT 'break' out of the 'while' loop just above ... THEN ...
        print("Your guess 2..12 :", end=' ')

    # get two random numbers 1..6 for each die
    die1 = random.randrange( 1, 7 ) # returns random num 1..6 in die1
    die2 = random.randrange( 1, 7 ) # returns random num 1..6 in die2
    sumdie = die1 + die2

    if sumdie == userNum:
        print("MATCH!")    # report
        pC = pC + userNum  # player wins                          
        cC = cC - userNum  # computer loses
    else:
        print("NO match!") # report failure
        pC = pC - userNum  # player loses
        cC = cC + userNum  # computer wins
        
    print("You entered", userNum, "and the computer rolled", \
          die1, "and", die2, "or", sumdie)
    return cC, pC # # # # # # # END of the function playgame # # # # # # #



# # # # # # # The 'Main' program code, (that uses the above functions), is here # # # # # # #

print("\nComputer stakes 100..1000 (cents) :", end=' ')
cCents = int(input())
if cCents < 100:
    cCents = 100  # don't allow values less than 100
if cCents > 1000:
    cCents = 1000 # don't allow values more than 1000
cStake = cCents

print("Player stakes 100..1000 (cents) : ", end=' ')
pCents = int(input())
if pCents < 100:
    pCents = 100
if pCents > 1000:
    pCents = 1000
pStake = pCents


done = False # See example use of a Python multi-line comment below ...
'''
                     Initialize 'done' to ... Python type 'bool' ... and value ... 'False'.
               N.B. Python uses CAPS on F and T in its use of values 'False' and 'True'
'''

numGames = 0
while not done:
    numGames = numGames +1
    cCents, pCents = playgame( cCents, pCents )
    reply = input( "\nPlay again (y/n) ? " )
    if reply[0:1] == 'n' or reply[0:1] == 'N' \
       or pCents <= 0 or cCents <= 0:
        done = True

# don't allow, (i.e. correct for), 'in-hole' situations ...
if pCents < 0:               # player in hole
    cCents = cCents + pCents # i.e. decrease computer balance
    pCents = 0               # so now can up balance of player to zero
else:
    if cCents < 0:          # computer in hole
        pCents = pCents + cCents # decrease player balance
        cCents = 0          # so now can up balance of computer to zero

print("\nAfter", numGames, "games, the computer has", cCents, "cents", \
      "\nand the player has", pCents, "cents")

cWins = cCents - cStake # calculate the computer winnings

pWins = pCents - pStake # calculate the player winnings


if( cWins > 0 ): # computer wins
    print("The computer wins", cWins, "and the player loses", -pWins)

else: # computer loses
    print("The player wins", pWins, "and the computer loses", -cWins)



For a cleaned up version that will not crash on non-integer input see this link:

http://developers-heaven.net/forum/index.php/topic,46.msg467.html#msg467




This following Python program demonstrates some of Pythons fine points concerning passing parameters to functions ... and returning them from functions ... so that the variables get updated outside the function.

Code: [Select]
# function_demo.py

'''
   In the following example Python function, passing in values to
   an_int and a_string are optional. They have default values of 2 and
   "A default string", respectively, if a value is not passed in.
'''

def passing_example(a_list, an_int=2, a_string="A default string"):
    a_list.append("A new item")
    an_int = 4
    print("Now inside: a_string =", a_string)
    print()
    return a_list, an_int, a_string

my_list = [1, 2, 3]
my_int = 10
my_str = "abc"
print("Note: Type 'list' is mutable, but 'int' (integers) and 'str' (strings) are immutable in Python")
print()
print("Before passed to function.")
print(my_list, my_int, my_str)

passing_example(my_list, my_int )
print("After returning from function.")
print(my_list, my_int, my_str)
print("Note: my_int (and my_str) were NOT re-assigned outside the function.")

print(passing_example(my_list ))
print("But see here that these updated values are returned though.")
print()
my_list, my_int, my_str = passing_example(my_list, my_int, my_str )

print("After returning from function AND assignment.")
print(my_list, my_int, my_str)

print("Note: Since my_str is NOT re-assigned a value inside the function," \
      "\n... thus it is returned unchanged.")

def passing_example2(a_list, an_int=2, a_string="A default string"):
    a_list.append("A new item")
    an_int = 4
    a_string = "A NEW string"
    print("Now inside passing_example2: a_string =", a_string)
    print()
    return a_list, an_int, a_string

print()
my_list, my_int, my_str = passing_example2(my_list, my_int, my_str )

print("After returning from function2 AND assignment.")
print(my_list, my_int, my_str)

print()
# def inc(x): return x + 1
# is the same as ...
inc = lambda x: x + 1
v=1
print("v =", v, "and inc(v) =", inc(v))


An even simpler demo ...


Code: [Select]
# function_demo2.py

my_list = [1, 2, 3]
my_tuple = (4, 5, 6)
my_int = 10
my_str = 'abc'

print('Before passing to functions ...')
print('my_list =', my_list, ': my_tuple =', my_tuple, \
      ': my_int =', my_int, ': my_str =', my_str)

print()
def passing_example(a_list):
    a_list.append("A new item")
    print('inside value is', a_list)
    
passing_example(my_list)
print("After returning from function.", my_list)
print("Note: my_list WAS updated outside also ...")

print()
def passing_examplet(a_tuple):
    a_tuple = a_tuple[:2]
    print('inside value is', a_tuple)
    
passing_examplet(my_tuple)
print("After returning from function.", my_tuple)
print("Note: my_tuple was NOT updated outside ...")

print()
def passing_example2(an_int):
    an_int = 2;
    print('inside value is', an_int)
    
passing_example2(my_int)
print("After returning from function.", my_int)
print("Note: my_int was NOT updated outside ...")

print()
def passing_example3(a_str):
    a_str = "XYZ"
    print('inside', a_str)

passing_example3(my_str)
print("After returning from function.", my_str)
print("Note: my_str was NOT updated outside ... ")


Here is a little test of random number generation in Python ...

It uses an array, (actually a Python list), to keep count of how many times each tested value of 0, 1, 2, 3, 4, 5, 6 is generated in a 100,000 random numbers, that are supposed to be generated, in the range from 1 to 5 inclusive ... And then ... from 1..6 inclusive:


Code: [Select]
# randomTest.py

def testRand():
    import random
    array=[0]*7 # Make 7 'int' elements in a 'list' named 'array' ... Initialize each to value 0 #
    for count in range ( 100000 ):
        rnum = random.randrange( 1, 6 ) # returns random numbers 1..5
        array[ rnum ] += 1
    for count in range ( 7 ):
        print("  {0:<3d}  {1:5d}".format(count, array[count]))

print('Testing random number generation ... ')
print("Value  Times")
print("=====  =====")
for x in range ( 3 ):
    testRand()
    if x < 2:
        print()

# Now demonstrate the difference in a call to random.randint( a, b ) ...
# Note the difference in the range of the random generated numbers here .

def testRand2():
    import random
    array=[0]*7
    for count in range ( 100000 ):
        rnum = random.randint( 1, 6 ) # returns random numbers 1..6
        array[ rnum ] += 1
    for count in range ( 7 ):
        print("  {0:<3d}  {1:5d}".format(count, array[count]))


print('Testing random number generation ... ')
print("Value  Times")
print("=====  =====")
for x in range ( 3 ):
    testRand2()
    if x < 2:
        print()

« Last Edit: January 19, 2010, 08:46:19 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #5 on: August 27, 2008, 05:08:01 AM »
With respect to ...


Chapter 07: First Memory Flow Lab
Chapter 08: Memory Flow Lab2
Chapter 09: Memory Flow Lab3
Chapter 10: HLA Data Types


This section will feature a few small Python programs to illustrate comparable things, and differences, in Python.

(See also the Python Tutorial - Learn Python in 10 minutes - featured below ...
for info on Python Data Types and program Flow Control.)


But first, try this little demo, and see what happens ...


Code: [Select]
# join_list_demo.py

a=[] # initial list
print(a)

for x in range( ord('a'), ord('z')+1 ):
    a.append( chr(x) )

print(x)

s='' # Initial string; Try an other value, say s='TEST', to see result #
print(s)

s=s.join(a) # See what happens here also ... if changed as suggested above.
print(s)

t='A' + s[1:]
print(t)



Now here is memLab1.py ....

Code: [Select]
# memLab1.py

print("\n\n                       Python memory Lab 1\n")

'''
        Compare this HLA ... with the Python program that follows ...
               
static
myCharArray: char[255]; // reserve 255 bytes of memory for 255 char's
myChr: char;            // reserve 1 byte of memory for 1 character
myInt: int32:=   12345; // reserve 4 bytes, i.e. 32 bits, for an int

// the following shows how to declare a 'pointer' type variable ...
myP:    pointer to int32:= &myInt; // now myP holds address of myInt
'''

print("Recall Python 'x in range(0,10)' means ... x gets values", end=' ')
for x in range(0,10):
               print(x, end=' ')
print(); print()

a=[] # initial list
for x in range( ord('a'), ord('z')+1 ):
               a.append( chr(x) )
s='' # Initial string; Try an other value, say s='TEST', to see result #
s=s.join(a) # See what happens here also ... if changed as suggested above.
t='A' + s[1:]

print('a =',a)
print('s =',s)
print('t =',t)
print()
headStr = 'x id(a)    id(a[0]) id(a[1]) id(a[2]) ... id(a[len(a)-1])'
print(headStr)
print("="*len(headStr))
print('a', id(a), id(a[0]), id(a[1]), id(a[2]), '...', id(a[len(a)-1]))
print('s', id(s), id(s[0]), id(s[1]), id(s[2]), '...', id(s[len(s)-1]))
print('t', id(t), id(t[0]), id(t[1]), id(t[2]), '...', id(t[len(t)-1]))

print("Note which values have the same address location (ID) !")
print("So ... 'same value points to same location' ... to conserve memory.")


# also try this ...

s = ''
for x in range( ord('a'), ord('z')+1 ):
    s = s + chr(x)

print("\nNote these NEW assigments of 's' also ...\n")
print('s =',s)
print()
headStr = 's id(a)    id(s[0]) id(s[1]) id(s[2]) ... id(s[len(a)-1])'
print(headStr)
print("="*len(headStr))
print('s', id(s), id(s[0]), id(s[1]), id(s[2]), '...', id(s[len(s)-1]))


s = 'X'
for x in range( ord('a'), ord('z')+1 ):
    s = s + chr(x)

print("\nAnd ...")
print('s =',s)
print()

print(headStr)
print("="*len(headStr))
print('s', id(s), id(s[0]), id(s[1]), id(s[2]), '...', id(s[len(s)-1]))

print("\n\nDo you see any order emerging ? ")

print("\n\nBUT ... don't count on some regular memory order in Python.")
print("See the next demo ... to see some 'jumps' in memory assigments.")

input( "\nPress 'Enter' to continue ... " )


Code: [Select]
# memLab2_ID.py

title = "Python memory allocation  ID  lab"
lenTitle = len(title)
# note integer division in Python 3 is now // ... ( / is now float division )
print("-"*((78-lenTitle)//2), title, "-"*((78-lenTitle)//2))

print("\nNote how memory allocation sometimes jumps around in Python ...")
print("... But, sometimes seems quite regular.  But WATCH out!")
print("Can you see the JUMP in memory allocation in the very last section?\n")

w0 = "1234567"
w1 = "abcdefg"
w2 = "hijklmn"
w3 = "7654321"
w4 = w0 + w1 + w2+ w3

print("Note ID's of ...")
print("Character strings, of same length, assigned one right after the other ...")
print("len(w0), len(w1), len(w2), len(w3), len(w4) =", end=' ')
print(len(w0), ", ", len(w1), ", ", len(w2), ", ", len(w3), ", ", len(w4))
print(id(w0), id(w1), id(w2), id(w3), id(w4))


print()

myList=[]
for x in range (0, 10):
    myList.append( str(x) )

print("Strings in list ...")
print("x   id(x)    mem gap between")
print("============================")
xold = 0
for x in myList:
    print(x, id(x), id(x) - id(xold))
    xold = x
   

myList = [0,1,2,3,4,5,6,7,8,9]
xold = 0 # So won't crash on first (here NOT representative) case ...
print("Now integers in list ...")
for x in myList:
    print(x, id(x), id(x) - id(xold))
    xold = x


input( "\nPress 'Enter' to continue ... " )

print("\n  x in range 0..78 inclusive ... ")
print(" id(array[x]), array[x], (id(array[x+1])-id(array[x])) <- 5 values/row")
print(" ======================================================================")
array = [ 0 ] * 80

for x in range (79):
    print(id(array[ x ]), array[ x ], id(array[ x+1 ]) - id(array[ x ]), end=' ')
    if (x +1) % 5 == 0: print()

print("\nNote how all array elements above have same value 0, so all use same mem (ID)")


for x in range (80):
    array[ x ] = x
   
print();print()

for x in range (79):
    print(id(array[ x ]), array[ x ], id(array[ x+1 ]) - id(array[x ]), end=' ')
    if (x +1) % 5 == 0: print()

print("\nBut here ... each element has an unique value ... so each have an unique mem (ID)")
print("Contiguous in v3...(but I had a BIG JUMP at 76 in old v2.5 You may not.)\n\n")

input( "\nPress 'Enter' to continue ... " )



If you have completed most of BEGINNING COMPUTER PROGRAMMING with HLA ....


then ...


Here is quick online Python Tutorial, (somewhat edited), to Fast Track / Overview and to ... 

Learn Python in 10 minutes 

http://www.poromenos.org/tutorials/python

Properties

Python is ***strongly typed*** (i.e. types are enforced), dynamically and implicitly typed (i.e. you don't have to declare variables), case sensitive (i.e. var and VAR are two different variables) and object-oriented (i.e. everything is an object).


*** But see this next link ***
Python is a weakly-typed language, which means it puts the minimum possible requirements on typing. For example, you could pass and return different types from the same function ...

But see ...

http://mindview.net/Books/TIPython/BackTalk/A2_0015

The discussions I read on strong vs. weak typing on c.l.py led me to think of python as being strongly, but dynamically typed, rather than weakly typed.


Actually Python is a dynamically typed language, meaning that variables don't have a type, values (objects) have types (or are instantiations of classes). Variables are bound to these objects.

C is a weakly typed language (it will perform various forms of implicit casting or "coercion" on some types, such as chars to ints) while some other languages are more strongly typed (and require explicit conversion or casting for any operation that crosses type boundaries.

I've heard that Python is a bit more like Lisp/Scheme, Dylan, and Icon in this respect (dynamic, late binding of variables to value).

I think it's going to be important to stress this and the fact that Python distinguishes between mutable and immutable types, passing mutable types by reference and immutables by value/copy and allowing only immutable types to be used as dictionary keys. These seem to be some of the most confusing aspects of Python to people coming from C, Perl, and Java. ...



Syntax

Python has no mandatory statement termination characters and blocks are specified by indentation. Indent to begin a block, dedent to end one. Statements that expect an indentation level end in a colon :. Comments start with the pound (#) sign and are single-line. Three quote characters are used around multi-line comments. Values are assigned (in fact, objects are bound to names) with the equals sign ("="), and equality testing is done using two equals signs ("=="). You can increment and decrement values using the += and -= operators respectively by the right-hand amount. This works on many datatypes, strings included. You can also use multiple variables on one line. For example:

>>> myvar = 3
>>> myvar += 2
>>> myvar
5
>>> myvar -= 1
>>> myvar
4
"""This is a multiline comment.
The following lines concatenate the two strings."""
>>> mystring = "Hello"
>>> mystring += " world."
>>> print(mystring)
Hello world.
# This swaps the variables in one line(!).
# It doesn't violate strong typing because values aren't
# actually being assigned, but new objects are bound to
# the old names.
>>> myvar, mystring = mystring, myvar


Data types

The data structures available in python are lists, tuples and dictionaries. Sets are available in the sets library (but are built-in in Python 2.5 and later). Lists have limited similarity to one-dimensional arrays (but you can also have lists of other lists), dictionaries are associative arrays (a.k.a. hash tables) and tuples are immutable one-dimensional arrays (Python "arrays" can be of any type, so you can mix e.g. integers, strings, etc in lists/dictionaries/tuples). The index of the first item in all array types is 0. Negative numbers count from the end towards the beginning, -1 is the last item. Variables can point to functions. The usage is as follows:

>>> sample = [1, ["another", "list"], ("a", "tuple")]
>>> mylist = ["List item 1", 2, 3.14]
>>> mylist[0] = "List item 1 again"
>>> mylist[-1] = 3.14
>>> mydict = {"Key 1": "Value 1", 2: 3, "pi": 3.14}
>>> mydict["pi"] = 3.15
>>> mytuple = (1, 2, 3)
>>> myfunction = len
>>> print(myfunction(mylist))
3


You can access array ranges using a colon ( a : b ) . Leaving the start index (a) empty assumes the first item, leaving the end index (b) empty assumes the last item. Negative indexes count from the last item backwards (thus -1 is the last item) like so:

>>> mylist = ["List item 1", 2, 3.14]
>>> print(mylist[:])
['List item 1', 2, 3.1400000000000001]
>>> print(mylist[0:2])
['List item 1', 2]
>>> print(mylist[-3:-1])
['List item 1', 2]
>>> print(mylist[1:])
[2, 3.14]


Strings

Python strings can use either single or double quotation marks, and you can have quotation marks of one kind inside a string that uses the other kind (i.e. "He said 'hello'." is valid). Multiline strings are enclosed in triple double (or single) quotes (""").


Flow control statements

Flow control statements are 'while', 'if', and 'for'. Use 'for' to enumerate through members of a list. To obtain a list of numbers, use 'range( number )'. The syntax is like this:

rangelist = range(10)
>>> print(rangelist)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in rangelist:
    # Check if number is one of
    # the numbers in the tuple.
    if number in (3, 4, 7, 9):
        # "Break" terminates a for without
        # executing the "else" clause.
        break
    else:
        # "Continue" starts the next iteration
        # of the loop. It's rather useless here,
        # as it's the last statement of the loop.
        continue
else:
    # The "else" clause is optional and is
    # executed only if the loop didn't "break".
    pass # Do nothing

if rangelist[1] == 2:
    print("The second item (lists are 0-based) is 2")
elif rangelist[1] == 3:
    print("The second item (lists are 0-based) is 3")
else:
    print("Dunno")


Functions

Functions are declared with the "def" keyword. Optional arguments are set in the function declaration after the mandatory arguments by being assigned a default value. For named arguments, the name of the argument is assigned a value. Functions can return a tuple (and using tuple unpacking you can effectively return multiple values). Lambda functions are ad hoc functions that are comprised of a single statement. Parameters are passed by reference, but immutable types (tuples, ints, strings, etc) cannot be changed. This is because only the memory location of the item is passed, and binding another object to a variable discards the old one, so immutable types are replaced. For example:
# Same as def f(x): return x + 1
functionvar = lambda x: x + 1
>>> print(functionvar(1))
2

# an_int and a_string are optional, they have default values
# if one is not passed (2 and "A default string", respectively).
def passing_example(a_list, an_int=2, a_string="A default string"):
    a_list.append("A new item")
    an_int = 4
    return a_list, an_int, a_string

>>> my_list = [1, 2, 3]
>>> my_int = 10
>>> print(passing_example(my_list, my_int))
([1, 2, 3, 'A new item'], 4, "A default string")
>>> my_list
[1, 2, 3, 'A new item']
>>> my_int
10


Exceptions

Exceptions in Python are handled with try-except [exceptionname] blocks:
def some_function():
    try:
        # Division by zero raises an exception
        10 / 0
    except ZeroDivisionError:
        print("Oops ... Can't divide by zero.")
    else:
        # Exception didn't occur, we're good.
        pass
    finally:
        # This is executed after the code block is run
        # and all exceptions have been handled, even
        # if a new exception is raised while handling.
        print("We're done with that.")

>>> some_function()
Oops ... Can't divide by zero.
We're done with that.


Importing

External libraries are used with the import [libname] keyword. You can also use from [libname] import [funcname] for individual functions. Here is an example:
import random
from time import clock

randomInt = random.randint(1, 100)
>>> print(randomInt)
64


File I/O

Python has a wide array of libraries built in. As an example, here is how serializing (converting data structures to strings using the pickle library) with file I/O is used:
import pickle
mylist = ["This", "is", 4, 13327]
# Open the file C:\binary.dat for writing. The letter r before the
# filename string is used to prevent backslash escaping.
myfile = file(r"C:\binary.dat", "w")
pickle.dump(mylist, myfile)
myfile.close()

myfile = file(r"C:\text.txt", "w")
myfile.write("This is a sample string")
myfile.close()

myfile = file(r"C:\text.txt")
>>> print(myfile.read())
'This is a sample string'
myfile.close()

# Open the file for reading.
myfile = file(r"C:\binary.dat")
loadedlist = pickle.load(myfile)
myfile.close()
>>> print(loadedlist)
['This', 'is', 4, 13327]

Miscellaneous

    * Conditions can be chained. 1 < a < 3 checks that a is both less than 3 and more than 1.
    * You can use del to delete variables or items in arrays.

>>> del lst1[0]
>>> print(lst1)
[2, 3]
>>> del lst1

    * Global variables are declared outside of functions and can be READ without any special declarations, but IF you want to WRITE to them, (and have the new values reflected after the function is exited), ... then, you CAN declare them at the beginning of the function with the "global" keyword, otherwise Python will bind the objects to new local variables (be careful of that, it's a small catch that can get you if you don't know it). For example:

number = 5

def myfunc():
    # This will print 5.
    print(number)

def anotherfunc():
    # This raises an exception because the variable has not
    # been bound before printing. Python knows that an
    # object will be bound to it later and THUS creates a new, local
    # object instead of accessing the global one.
    print(number)
    number = 3

def yetanotherfunc():
    global number
    # This will correctly change the global.
    number = 3

« Last Edit: December 29, 2008, 12:41:57 PM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #6 on: August 27, 2008, 10:13:13 AM »
Here are the Python versions for Chapter 11 of the programs in the e-Book ...

BEGINNING COMPUTER PROGRAMMING

Note:  Although these Python versions of the programs may be shorter, ... and faster to write and test/debug, ... in Python you would not face the details of such a thing as the FPU (the Floating Point Unit) ... and would not gain 'hands on' experience into how real numbers are actually stored in 32 bit, or 64 bit, or 80 bit, ... and how the details of the bits in memory are interpreted for floating point numbers, ... and how significant errors may be introduced into your math calculation results by using limited number of bits to represent an approximation to the values you present for the calculations ...

Note that one MUST also HAVE the Python INTERPRETER installed on their computer to run these Python program 'text file' scripts ...  instead of the compiled xxx.exe files that HLA produces ... (in case you want to distribute your Python Program Scripts) ... And if speed of execution is vital,  (for processes that may involve LONG processing time), nothing can compare to the speed of well designed Assembly Language code that has been optimally compiled to an executable file for your computer.  This may be an appropriate time for you to research and compare Compiled vs Interpreted Programs ... and their respective speeds of execution and production cost both in time and maintenance.  Here are some links to get stated on your research ...

(Also see the Python program, timeIt.py, and the comparable HLA program, timeIt.hla, at the end of THIS Python version of Chapter 11.  If you run these two versions on your PC, you will see an example of how HLA can be over 400 times faster than Python.)


(Edit: link removed here since it was no longer available.)


Compiled versus interpreted languages


During the design of an application, you might need to decide whether to use a compiled language or an interpreted language for the application source code.

Both types of languages have their strengths and weaknesses. Usually, the decision to use an interpreted language is based on time restrictions on development or for ease of future changes to the program. A trade-off is made when using an interpreted language. You trade speed of development for higher execution costs. Because each line of an interpreted program must be translated each time it is executed, there is a higher overhead. Thus, an interpreted language is generally more suited to ad hoc requests than predefined requests.

Advantages of compiled languages

Assembler, COBOL, PL/I, C/C++ are all translated by running the source code through a compiler. This results in very efficient code that can be executed any number of times. The overhead for the translation is incurred just once, when the source is compiled; thereafter, it need only be loaded and executed.

Interpreted languages, in contrast, must be parsed, interpreted, and executed each time the program is run, thereby greatly adding to the cost of running the program. For this reason, interpreted programs are usually less efficient than compiled programs.

Some programming languages, such as REXX™ and Java™, can be either interpreted or compiled.

Advantages of interpreted languages

There are reasons for using languages that are compiled and reasons for using interpreted languages. There is no simple answer as to which language is "better"—it depends on the application. Even within an application we could end up using many different languages. For example, one of the strengths of a language like CLIST is that it is easy to code, test, and change. However, it is not very efficient. The trade-off is machine resources for programmer time.

Keeping this in mind, we can see that it would make sense to use a compiled language for the intensive parts of an application (heavy resource usage), whereas interfaces (invoking the application) and less-intensive parts could be written in an interpreted language. An interpreted language might also be suited for ad hoc requests or even for prototyping an application.

One of the jobs of a designer is to weigh the strengths and weaknesses of each language and then decide which part of an application is best served by a particular language.



http://www.vanguardsw.com/dphelp4/dph00296.htm


Compiled vs. Interpreted Languages

Programming languages generally fall into one of two categories: Compiled or Interpreted. With a compiled language, code you enter is reduced to a set of machine-specific instructions before being saved as an executable file. With interpreted languages, the code is saved in the same format that you entered. Compiled programs generally run faster than interpreted ones because interpreted programs must be reduced to machine instructions at runtime. However, with an interpreted language you can do things that cannot be done in a compiled language. For example, interpreted programs can modify themselves by adding or changing functions at runtime. It is also usually easier to develop applications in an interpreted environment because you don't have to recompile your application each time you want to test a small section.

So, which is DScript, compiled or interpreted?  Actually, DScript is both. When you enter definitions in DScript, they are immediately reduced to a set of basic primitives. If you enter

x:=2+3

DScript reduces this to

_DEF(x,_ADD(2,3))

The original code you enter is discarded and only this simplified code is saved. When you open a saved application and view its node definitions, DScript decompiles the simplified code to generate a presentation that is similar to the code you originally entered.

When you execute an application, DScript interprets the reduced code at runtime. Therefore, DScript is partly an interpreted language. However, code is interpreted only the first time it is executed. Every time after that, the compiled code is executed.

For example, consider the following loop:

for(var n=0; n<1000; n++)
total+=n;

In executing this code, each separate expression will be evaluated 1000 times. However, DScript will interpret the code only on the first iteration and use the compiled code for the remaining 999 iterations. Since virtually all CPU time a program consumes is used inside loops, this execution strategy significantly improves performance while maintaining the flexibility of an interpreted language.



http://msdn.microsoft.com/en-us/library/aa240840(VS.60).aspx


Visual Basic Concepts
Compiled vs. Interpreted Applications

By default, applications created in Visual Basic are compiled as interpreted or p-code executables. At run time, the instructions in the executables are translated or interpreted by a run-time dynamic-link library (DLL). The Professional and Enterprise editions of Visual Basic include the option to compile a native code .exe. In many cases, compiling to native code can provide substantial gains in speed over the interpreted versions of the same application; however, this is not always the case. The following are some general guidelines regarding native-code compilation.

    * Code that does a lot of primitive operations on hard-typed, nonstring variables will yield a maximum ratio of generated native code to displaced p-code operations. Complex financial calculations or fractal generation, therefore, would benefit from native code.

    * Computationally intensive programs, or programs that shuffle a lot of bits and bytes around within local data structures, will gain very visibly with native code.

    * For many programs, especially those doing a lot of Windows API calls, COM method calls, and string manipulations, native code will not be much faster than p-code.

    * Applications that consist primarily of functions from the Visual Basic for Applications run-time library are not going to see much if any advantage from native code, because the code in the Visual Basic for Applications run-time library is already highly optimized.

    * Code that involves a lot of subroutine calls relative to inline procedures is also unlikely to appear much faster with native code. This is because all the work of setting up stack frames, initializing variables, and cleaning up on exit takes the same time with both the p-code engine and generated native code.

Note that any calls to objects, DLLs or Visual Basic for Applications run-time functions will negate the performance benefits of native code. This is because relatively little time is spent executing code — the majority of time (usually around 90–95%) is spent inside forms, data objects, Windows .dlls, or the Visual Basic for Applications run time, including intrinsic string and variant handling.

In real-world tests, client applications typically spent about 5% of their total execution time executing the p-code. Hence, if native code was instantaneous, using native code for these programs would provide at most a 5% performance improvement.

What native code does is to enable programmers to write snippets of code or computationally intensive algorithms in Basic that were never possible before because of performance issues. Enabling these "snippets" to run much faster can also improve the responsiveness of certain portions of an application, which improves the perceived performance of the overall application.






Chapter 11: The Computer does some Algebra with real numbers ... and Input Data Validation


Code: [Select]
# realMath.py

# finds the running average of test scores

print("The following program asks for input of test scores\n" \
      "and then finds the average of the scores todate:\n")

totOutOf = totScore = 0.0; count = 0
while 1:
    count += 1
    score = eval(input("Enter score: "))
    totScore += score

    outOf = eval(input("Enter outOf: "))
    totOutOf += outOf

    print("The average of", count, "test(s) with", \
          totScore, "marks out of", totOutOf, \
          "is:", totScore/totOutOf)
   
    reply = input("\nAnother (y/n) ?")
    if reply[0:1] == 'n' or reply[0:1] == 'N':
        break


Code: [Select]
# realMath2.py

# finds the running average of test scores
# this version checks for/and handles non-numeric input

print("The following program asks for input of test scores\n" \
      "and then finds the average of the scores todate:\n")

def getNumber(message):
    while 1:
        try:
            number = eval(input(message))
            return number
        except:
            print("Must enter a number")


totOutOf = totScore = 0.0; count = 0
while 1:
    count += 1
    score = getNumber("Enter score: ")
    totScore += score

    outOf = getNumber("Enter outOf: ")
    totOutOf += outOf

    print("The average of", count, "test(s) with", \
          totScore, "marks out of", totOutOf, \
          "is:", totScore/totOutOf)
   
    reply = input("\nAnother (y/n) ? ")
    if reply[0:1] == 'n' or reply[0:1] == 'N':
        break


Code: [Select]
# realMath3.py

# finds the running average of test scores
# this version checks for/and handles non-numeric input ... and
# also limits the range of user input to proscribed values/logic

print("The following program asks for input of test scores\n" \
      "and then finds the average of the scores todate:\n")

def getNumber(message):
    while 1:
        try:
            number =0
            number = eval(input(message))
            # don't accept numbers less than 0 or more than 100
            if number < 0 or  number > 100:
                raise ValueError
            return number
        except ValueError:
            print("Out of acceptable input range 0..100")
        except:
            print("Must enter a number")

totOutOf = totScore = 0.0; count = 0
while 1:
    count += 1
    score = getNumber("Enter score: ")
    totScore += score

    # Don't allow zero entry for 'outOf'
    # Also ... Don't allow divide by zero
    # Also make sure outOf >= score
    while 1:
        outOf = getNumber("Enter outOf: ")
        if outOf > 0 and outOf >= score:
            break
        if outOf <= 0:
            print("Numbers <= 0 not valid ... Entry must be > 0")
        elif outOf < score:
            print("Number not valid ... Entry must be >=", score)
       
    totOutOf += outOf

    print("The average of", count, "test(s) with", \
          totScore, "marks out of", totOutOf, \
          "is:", totScore/totOutOf)
   
    reply = input("\nAnother (y/n) ? ")
    if reply[0:1] == 'n' or reply[0:1] == 'N':
        break



To round out this little introduction to REAL Arithmetic in Python vs HLA ... here is a little "Bonus" program, in Python, that demos the use of real numbers (Python type 'float'), and integer numbers (Python type 'int'), and a common way of rounding off of dollars.cents.... to the nearest cent.  It also demos a way to write a file in Python ... close that file, when you are finished ... then to call, from within your running Python program, a system command to open that file into some program available on your system for that purpose. ( Here, we used the Windows System supplied Text Editor ... notepad.exe )

You may actually like to use this little Python script, as you contemplate how little the Banks pay in interest these days on ordinary savings ... or even special interest bearing Bank Accounts.

A good little project here, to test your understanding, would be to modify/enhance this program to make it "crash proof" if "bad data" is entered. (Hint: you may try using Python exception handling.)  And you may like to restrict and validate each item of data input, to some more meaningful range. (For example ... restrict negative numbers from being entered, and/or zero for the interest rate, etc. ... ) Python dynamic typing lends itself, like HLA macros also do, to 'function overloading' ... so that one function can handle several types of user input, for example 'int' and 'float' input.  You might want to review the 'data validation' examples given in the 'first simulation' programs in 'Chapter 06' ... and the Python exception handling examples in the programs realMath2.py and realMath3.py above.



Code: [Select]
# interestTable.py

def interestTable():
  print("This program prints an interest table")
  print()
  principal = eval(input("Enter the initial principal (ex 100000.00) : "))
  rate =      eval(input("Enter the yearly interest rate   (ex 0.06) : "))
  periods =   int(input("Enter the compounding periods/year (ex 12) : "))
  years =     eval(input("Enter the years to be compounded  (ex 3.5) : "))

  f = open("InterestTable.txt", "w") # create/overwrite the file
                                     # and a handle/object to this file named 'f'
  f.write("Principle=" + str(principal) + " Rate=" + str(rate) + \
          " Periods=" + str(periods) + " Years=" + str(years) + "\n\n")
  f.write("Year Period  Principal at END\n\n") # table header
 
  for period in range(int(periods*years)):
    principal = int(principal * (1 + rate/periods) *100 +.5)/100.0
    # note // used now for integer division on Python 3 ... / for float division
    f.write("  {0:<3d} {1:3d} {2:19.2f}\n".format((period//periods+1), period+1, principal))

  f.close()
  import os
  os.system( "notepad InterestTable.txt " )


interestTable() # This line calls forth the production of your Interest Table
# You will find that TABLE stored in the text file you named InterestTable.txt in your
# C:\Python folder. Note the use of the () even if no parameter is passed.


Addendum:

Here are two comparable programs to run, one in Python, the other in HLA.  When you run them, you will SEE the relative execution times ... for your PC.



Code: [Select]
# timeIt.py

# Show time to loop 10 Million times in Python release 2.5.2
# It averaged 2.2 sec on my Pentium 4 2.4 GHz PC with WinXP

# It averaged 2.0 sec for the HLA version to loop 400 x 10 Million.

from time import time

numLoops = 10*1000*1000       # or ... as a formated string, as below ...
numLoops_str = "10,000,000"   # Note the Python type 'str' variable.

print("Time for Python to count through just", numLoops_str, "loops is ...\n")

t1=time()
for i in range( numLoops ):
    pass
t2=time()

print("{0:5.2f} seconds.".format(t2-t1))

input("\nPress 'Enter' to continue ...")


Code: [Select]
program timeIt; // Show time for HLA program to loop 400 x 10 Million times. On my PC it took 2.0 secs //
                      // On my PC ... the camparable Python program looped ONLY 10 Million times in 2.2 secs //

#include( "stdlib.hhf" )

const
numLoops:= 10_000_000; // HLA accepts this format also ...
hla_numLoops:= numLoops * 400; // HLA loops 400 times faster than Python in the same 2 sec run.

static
    r_1000:              real64:= 1000.0;

var
    my_i32:              int32;
my_r64:              real64;
clock:                 timer;


begin timeIt;

conv.setUnderscores( true ); // to turn ON output print format style of 1_234_567

stdout.put( "Time for HLA to count through 400 x ", numLoops, " loops is ...", nl nl );

mov( hla_numLoops, ecx );    // Use 32 bit ecx register as counter and initialize to hla_numLoops

clock.create();
clock.start();

startLoop:
sub( 1, ecx );
jnz startLoop; // Jump to instruction at the 'startLoop' label while ecx is NOT zero

clock.stop();
mov( eax, my_i32 );    // move accumulated milliseconds into my_i32

finit();                      // initialize the FPU (Floating Point Unit)
fild( my_i32 );            // load the int32 stored in memory variable my_i32
fdiv( r_1000 );           // divide by 1000.0, a real64 value stored in memory
fstp( my_r64 );          // store the top value in the FPU stack in memory variable my_r64

        stdout.put(
                                 " ", my_i32, " milliseconds or ...", nl,
                                 my_r64:5:2, " seconds.", nl
                      );

stdout.puts( nl "Press Enter to continue ... " );
stdin.readLn();

end timeIt;

« Last Edit: February 13, 2009, 11:00:23 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #7 on: August 31, 2008, 10:27:41 AM »
Here are the Python versions of the programs for Chapter 12 in the e-Book ...

BEGINNING COMPUTER PROGRAMMING

Chapter 12: Pointers, Strings, my own Types, Records, Arrays, and dynamic things on the fly ...

Python is great at dynamic typing and assigning new memory on the fly for the values presented.  It uses automatic 'garbage collection' ( try a Google search using keywords: Python garbage collection ) .... so you do not have to worry about freeing up memory.  But for 'mission critical' operations, you wouldn't want a reactor to explode while the processor slows and waits during some unexpected and unplanned CPU downtime during routine Python garbage collection :( Ce sera très très mal, ici :

(The above may not be a fair example so much anymore ... given the present speeds of CPU's ... and one hopes ... the fail safe reactor shut down mechanisms?)




See the following Python classEntry.py program that parallels the HLA program records.hla ...


Code: [Select]
# classEntry.py

# a way to implement records in Python that is parallel to records in HLA
# use class Entry and a Python list to be like an array of records in HLA

class Entry:
    pass

def showBook():
    for item in book:
        print("{0:20} {1}".format( item.name, item.phone ))
    #for n in range ( len(book) ):
        #print "%-20s %s" % ( book[n].name, book[n].phone )
       
def addBook():
    tmp = Entry() # next entry ... This 'tmp' entry has scope 'addBook'
    while 1:
        tmp.name = input ("Name (or press 'Enter' to exit) : ")
        if len( tmp.name ) == 0:
            break
        tmp.phone = int(input( 'Phone : ' ))
        reply = input(tmp.name + ', ' + str(tmp.phone) + ' Ok (y/n) ? ')
        if len(reply) == 0:
            pass
        elif reply[0] == 'y' or reply[0] == 'Y':
            book.append(tmp) # copy appended to Global 'book' type 'list'
            break
        print("Try entry again ...\n")


rec = Entry() # Create an empty Entry object

# Dynamically Create and Fill the fields of the record
rec.name = 'David '
rec.phone = 123456789

# Note: 'book' is a global variable that has a scope of this whole module
book = [rec] # book has Python type LIST, here simulating an array of records

# next entry ...
tmp = Entry() # Create an other empty Entry object
tmp.name = 'Matthew'
tmp.phone = 4567890123
book.append(tmp) # append to LIST
       
print("Your Book at present is ...\n")
showBook()
print()

more = True
while more:
    addBook()
    reply = input('More (y/n) ? ')
    if len(reply) > 0 and (reply[0] == 'n' or reply[0] == 'N'):
        more = False
   
print("\nYour Book at present is ...\n")
showBook()


So … what has been happening above?

   1. We defined our own type of object/variable and gave it the name Entry, and created an instance 'rec' of this new object type that we named 'Entry'.
   2. We further defined this 'rec' object, on the fly, in the first instance of the object 'Entry', ... to be a record composed of a string, 'rec.name', ... and an integer, 'rec.phone' ...

Pretty cool ... eh?



Now to  further refine our program ... (but it's not yet very useful) .... See the following Python 'classEntry2.py' program that parallels the HLA program 'records3.hla' ... with a little more data input checking/validation:


Code: [Select]
# classEntry2.py

# A way to implement records in Python that is parallel to records in HLA
# use class Entry and a Python list to be like an array of records in HLA
# A little more input data checking/validation going here ...

class Entry:
    pass

def showBook():
    for person in book:
        print("{0:20} {1}".format(person.name, person.phone ))

def addBook():
    tmp = Entry() # next entry ... This 'tmp' entry has scope 'addBook'
    while 1:
        tmp.name = input("Name (or press 'Enter' to exit) : ")
        if len(tmp.name) == 0:
            break
        temp = input('Phone : ')
        if len(temp) != 10:
            print("Error: Phone number must have 10 digits.")
            continue
        isInt = True
        for character in temp:
            if character not in "0123456789":
                print("Error: Must be integer only input for Phone number.")
                isInt = False
                break
        if not isInt:
            break
        tmp.phone = int(temp)
           
        reply = input(tmp.name + ', ' + str(tmp.phone) + ' Ok (y/n) ? ')
        if len(reply) == 0:
            pass
        elif reply[0] == 'y' or reply[0] == 'Y':
            book.append(tmp) # copy appended to Global 'book' type 'list'
            break

        print("Try entry again ...\n")


rec = Entry() # Create an empty Entry object

# Dynamically Create and Fill the fields of the record
rec.name = 'David '
rec.phone = 1234567890

# Note: 'book' is a global variable that has a scope of this whole module
book = [rec] # book has Python type LIST, here simulating an array of records

# next entry ...
tmp = Entry() # Create an other empty Entry object
tmp.name = 'Matthew'
tmp.phone = 4567890123
book.append(tmp) # append to LIST
       
print("Your Book at present is ...\n")
showBook()
print()

more = True
while more:
    addBook()
    reply = input('More (y/n) ? ')
    if len(reply) > 0 and (reply[0] == 'n' or reply[0] == 'N'):
        more = False
   
print("\nYour Book at present is ...\n")
showBook()
« Last Edit: December 28, 2008, 12:54:36 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #8 on: August 31, 2008, 11:53:05 AM »
Here are the Python versions of the programs for Chapter 13 in the e-Book ...

BEGINNING COMPUTER PROGRAMMING

Chapter 13: The Computer files its Records ...



Code: [Select]
# fileRecords.py

# A way to implement records in Python that is parallel to records in HLA
# use class Entry and a Python list to be like an array of records in HLA

# This module files its records (to retain updates to 'book') ... but
# doesn't yet read back the updated file on any repeated run ...  See
# the next program, ... 'fileRecords2.py' ... to see that feature added.

# I've retained some 'debugging' output here for you to observe.

class Entry:
    pass

def showBook():
    for person in book:
        print("{0:20} {1}".format(person.name, person.phone))

def addToBook():
    tmp = Entry() # next entry ... This 'tmp' entry has scope 'addBook'
    while 1:
        tmp.name = input("Name (or press 'Enter' to exit) : ")
        if len(tmp.name) == 0:
            break
        temp = input('Phone : ')
        if len(temp) != 10:
            print("Error: Phone number must have 10 digits.")
            continue
        isInt = True
        for character in temp:
            if character not in "0123456789":
                print("Error: Must be integer only input for Phone number.")
                isInt = False
                break
        if not isInt:
            break
        tmp.phone = int(temp)
           
        reply = input(tmp.name + ', ' + str(tmp.phone) + ' Ok (y/n) ? ')
        if len(reply) == 0:
            pass
        elif reply[0] == 'y' or reply[0] == 'Y':
            book.append(tmp) # copy appended to Global 'book' type 'list'
            break

        print("Try entry again ...\n")


def moreBookLoop():
    moreNeeded = True
    while moreNeeded:
        addToBook()
        reply = input('More (y/n) ? ')
        if len(reply) > 0 and (reply[0] == 'n' or reply[0] == 'N'):
            moreNeeded = False


def fileBook():
    f = open("records.dat", "w");
    for tmp in book:
        f.write(tmp.name + "\n")
        f.write(str(tmp.phone) + "\n")
    f.close()



rec = Entry() # Create an empty 'Entry' object

# Dynamically Create and Fill the fields of the record
rec.name = 'David '
rec.phone = 1234567890

# Note: 'book' is a global variable that has a scope of this whole module
book = [rec] # book has Python type LIST, here simulating an array of records

# next entry ...
tmp = Entry() # Create an other empty Entry object
tmp.name = 'Matthew'
tmp.phone = 4567890123
book.append(tmp) # append to LIST
       
print("Your Book at present is ...\n")
showBook()
print()

moreBookLoop()
fileBook()
   
print("\nYour Book File at present is ...\n")
showBook()
input("Press 'Enter' to show file in notepad ...")
import os
os.system("notepad records.dat")

« Last Edit: December 23, 2008, 03:59:47 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #9 on: August 31, 2008, 01:59:03 PM »
Chapter 14: The Computer reads its Files ...

Notice that we are again starting out with the same program with which we ended in the previous chapter. For a simple start … we will just add to it.  We will add another function, inputBook(), to read these records into an array of records, when we first run our program, (if there is an existing file, that is … with records to read.)  Then we will just show them ...

BUT … if the records.dat file does NOT exist in the default directory, i.e. our working folder, we will just report that possibility and then ask if the user wishes to start a new one.  If so, we can just call our previously defined function moreBookLoop() ... Let’s give it a different name of newBook().  However we must not forget to then, right away, write these new records to the disk.  To do so … we just call the function that we made in the last chapter: fileBook().

NOTE:  In our programs we have NOT been specifying any path to the file that we write to or read from the disk. Thus, the Python script just then reads/writes its data files from/to the default working directory … which is the same as the folder that we have just made … the folder where we have been putting each chapter’s files.

Here then, is our next step in this mini data base type program:


Code: [Select]
# fileRecords2.py

# An implementation of records in Python, (in a way that is parallel to HLA),
# using a Python 'class' I named 'Entry', and a Python 'list', I named 'book',
# as an array, of 'Entry' objects to mimic holding an array of records, like in HLA.

# This module both 'reads' and 'files' its records ...
# And permits new additions to the file in 'myDataFile'

myDataFile = "myRecords.dat"

class Entry:
    def __init__(self, theName, thePhoneNumber):
        self.name = theName
        self.phone = thePhoneNumber

# Note: 'book' is a global variable that has the 'scope' of this whole module.
# 'book' has Python type 'list'
book = []

def addToBook():
    while 1:
        thisName = input( "Name (or press 'Enter' to exit) : " )
        if len( thisName ) == 0:
            break # exit if 'Enter' pressed to exit
        thisPhone = input( 'Phone : ' )

        # check that phone number is TEN DIGITS ...
        if len( thisPhone ) != 10:
            print("Error: Phone number must have 10 digits.")
            continue # ... so start while loop again to get another chance
        isInt = True
        for character in thisPhone:
            if character not in "0123456789":
                print("Error: Must be integer only input for Phone number.")
                isInt = False
                break # break out of this inner 'for loop'
        if not isInt:
            break # break out of while (forever) loop

        # If we reach here ... it's ok to convert raw 'str' input to 'int'
        thisPhone = int( thisPhone )

        # Must reply 'yY' or ... will repeat while loop again ...
        reply = input( thisName + ', ' + str(thisPhone) + ' Ok (y/n) ? ' )
        if reply[0] == 'y' or reply[0] == 'Y':
            book.append( Entry(thisName, thisPhone) ) # copy appended to Global 'book' type 'list'
            print() # blank line to space to next entry
            break
        # else ...
        print("Try entry again ...\n")
       
def newBook():
    while 1:
        addToBook()
        reply = input( 'More (y/n) ? ' )
        if reply in 'Nn' and reply != '':
            break

def fileBook():
    f = open( myDataFile, "w" );
    for person in book:
        f.write( person.name + "\n" )
        f.write( str(person.phone) + "\n" )
    f.close()

def inputBook():
    # see if such a file exists ...
    try:
        f = open( myDataFile, "r" )   
    except:
        print("\nThere was some problem reading your file. " \
              "Perhaps it doesn't exist?" \
              "\nDo you want to start a new contact book", end=' ')
        reply = input( "(y/n)? ", )
        if reply in 'Yy' and reply !='':
            newBook()
            fileBook()
            return
        else:
            import sys
            sys.exit("No new data/file added/changed at this time ...")
           
    #ok ... file is there ... or a new book and file were created ...

    lines = f.readlines()
    f.close() # now ...
   
    num = len(lines) # num is number of lines, (always an even number)
    num = num//2 # note new Python integer divide is now //, not /
    for n in range (num):
        name = lines[n*2].rstrip() # take off '\n' char at end
        phone = int( lines[n*2+1].rstrip() ) # and ... make an 'int'       
        book.append( Entry( name, phone ) ) # NEW copy in global and mutable Python list object 'book'
     
def showBook():
    for person in book:
        #print "%-20s %s" % ( person.name, person.phone )
        print("{0:20} {1}".format(person.name, person.phone))



# --- main stuff begins here --- #

inputBook() # from file myDataFile
print("\nYour contact book, (from data file {0}), now in memory is ...\n".format(myDataFile))
showBook()

import os
# visual check on file structure using a System Text Editor
os.system( "notepad " + myDataFile )

upDated = False
while 1: # forever loop ... until break
    # EXIT while loop IF anything other than 'yY' entered ...
    reply = input("Would you like to add some more records (y/n)? ", )
    if reply in "yY" and reply !='':
        addToBook()
        upDated = True
    else:           
        break

if upDated:
    print("\n>>>> Updated to >>>> ")
    showBook()
    fileBook()

« Last Edit: December 25, 2008, 12:08:55 PM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #10 on: September 01, 2008, 09:05:42 AM »
Code: [Select]
# addToContacts.py

# Chapter 15:
# The Computer updates (edits, deletes, sorts, chops-duplicates-in) its files ...

'''           
    Study the comments that are in the program, as well as the output
    that appears on the screen when you run the program.  We will add
    new functions and make changes ...

    Notice that we are again starting out with the same program with which
    we ended in the previous chapter. For a simple start, we will just add
    to it. We will add another function, showMenu() ... and make a few
    other changes ... (see the comments in the program).

    The name 'newBook' was changed to 'updateBook' to make it more generic.

    The name of the book input function changed to 'inputBook_fromFile',
    to make it more descriptive of just what it does. 
'''

# An implementation of records in Python, (in a way that is parallel to HLA),
# using a Python 'class' I named 'Entry', and a Python 'list', I named 'book',
# as an array, of 'Entry' objects to mimic holding an array of records ...
# like in HLA.

# The Computer will eventually update, i.e. edit, delete, sort, chop-duplicates-in,
# the file held here ... in the Python variable/object ... named here ... myDataFile
# Here ... the beginnings of a menu ... is added.

myDataFile = "myRecords.dat"

class Entry:
    def __init__(self, theName, thePhoneNumber):
        self.name = theName
        self.phone = thePhoneNumber

# 'book' is a global variable that has the 'scope' of this whole module.
book = []  # create a global Python 'list' called 'book'

done = False  # a new Global variable used in this module

def addToBook():
    while 1:
        name = input ("Name (or press 'Enter' to exit) : ")
        if len( name ) == 0:
            break # exit if 'Enter' pressed to exit
        phone = input('Phone : ')

        # check that phone number is TEN digits only
        if len( phone ) != 10:
            print("Error: Phone number must have 10 digits.")
            continue # ... so start while loop again to get another chance
        isInt = True
        for character in phone:
            if character not in "0123456789":
                print("Error: Must be integer only input for Phone number.")
                isInt = False
                break # break out of this inner 'for loop'
        if not isInt:
            break # break out of while (forever) loop

        # If we reach here ... ok to convert raw 'str' input to 'int'
        phone = int( phone )

        # Must reply 'yY' or while repeat will loop again ...
        reply = input(name + ', ' + str(phone) + ' Ok (y/n) ? ')
        if reply[0] == 'y' or reply[0] == 'Y':
            book.append( Entry(name, phone) ) # copy appended to Global 'book' type 'list'
            print() # blank line to space to next entry
            break
        # else ...
        print("Try entry again ...\n")

def updateBook():
    while 1:
        addToBook()
        reply = input( 'More (y/n) ? ', )
        if len( reply) > 0 and (reply[0] == 'n' or reply[0] == 'N'):
            break

def fileBook():
    f = open( myDataFile, "w" );
    for person in book:
        f.write( person.name + "\n" )
        f.write( str(person.phone) + "\n" )
    f.close()
   
def inputBook_fromFile():
    # see if such a file exists ...
    try:
        f = open( myDataFile, "r" )   
    except:
        print("\nThere was some problem reading your file. " \
              "Perhaps it doesn't exist?" \
              "\nDo you want to start a new contact book ",)
        reply = input( "(y/n) ? ", )
        if( len(reply) > 0 and (reply[0] == 'y' or reply[0] == 'Y') ):
            updateBook()
            fileBook()
            return
        else:
            import sys
            sys.exit("No new data/file added/changed at this time ...")
           
    #ok ... file is there ... or a new book and file were created ...

    lines = f.readlines()
    f.close() # now ...
   
    num = len(lines) # num is number of lines
    num = num//2 # new integer division use // instead of / now defaulting to float
    for n in range (num):
        name = lines[n*2].rstrip() # take off '\n' char at end
        phone = int( lines[n*2+1].rstrip() ) # and ... make an 'int'       
        book.append( Entry(name, phone) ) # NEW copy in mutable Python list object 'book'

       
def showBook():
    for person in book:
        print("{0:16} {1}".format(person.name, person.phone))
        # print("%-16s %s" % (person.name, person.phone))

def showMenu():
    showBook()
    print("\n{0} contacts now in memory".format(len(book)), end=' ')
    reply = input("... New contacts (y/n) ? ")
    if reply == 'y' or reply == 'Y':
        updateBook()
        fileBook()
    else:
        global done # done is a Global variable
        done = True


# --- main stuff begins here --- #

inputBook_fromFile()
while 1: # do forever ... until done ... then break
    showMenu()
    if done:
        break

# --- Note: The menu here is just a start --- #
# --- It will be expanded as we add more functions. --- #


Here is the next step: We will add an 'editContact' function  ...


Code: [Select]
# editContacts.py

# Chapter 15: The Computer updates (edits) its files ...

# An implementation of records in Python, (in a way that is parallel to HLA),
# using a Python 'class' I named 'Entry', and a Python 'list', I named 'book',
# as an array, of 'Entry' objects to mimic holding an array of records ...
# like in HLA.

# The Computer will eventually update, i.e. edit, delete, sort, chop-duplicates-in,
# the file held here ... in the Python variable/object ... named here ... myDataFile

myDataFile = "myRecords.dat"

class Entry:
    def __init__(self, theName, thePhoneNumber):
        self.name = theName
        self.phone = thePhoneNumber

# 'book' is a global variable that has the 'scope' of this whole module.
book = []  # create a global Python 'list' called 'book'

done = False  # a new Global variable used in this module

def isValidPhone( numStr ): # check that phone number is TEN DIGITS
    if len( numStr ) != 10:
        print("Error: Phone number must have 10 digits.")
        return False
    for character in numStr:
        if character not in "0123456789":
            print("Error: Must be integer only input for Phone number.")
            return False
    return True

def addToBook():
    while 1:
        name = input ( "Name (or press 'Enter' to exit) : " )
        if len( name ) == 0:
            break # exit if 'Enter' pressed to exit
        phone = input( 'Phone : ' )

        # check that phone number is TEN digits only
        if isValidPhone( phone ) == False:
            continue # ... do next while loop ...

        # If we reach here ... ok to convert raw 'str' input to 'int'
        phone = int( phone )
       
        # Must reply 'yY' or while repeat will loop again ...
        reply = input( name + ', ' + str(phone) + ' Ok (y/n) ? ' )
        if reply[0] == 'y' or reply[0] == 'Y':
            book.append( Entry(name, phone) ) # copy appended to Global 'book' type 'list'
            print() # blank line to space to next entry
            break
        # else ...
        print("Try entry again ...\n")
       
def updateBook():
    while 1:
        addToBook()
        reply = input( 'More (y/n) ? ', )
        if reply in 'nN' and reply != '':
            break

def fileBook():
    f = open( myDataFile, "w" );
    for tmp in book:
        f.write( tmp.name + "\n" )
        f.write( str(tmp.phone) + "\n" )
    f.close()

def inputBook_fromFile():
    # see if such a file exists ...
    try:
        f = open( myDataFile, "r" )   
    except:
        print("\nThere was some problem reading your file. " \
              "Perhaps it doesn't exist?" \
              "\nDo you want to start a new contact book ", end=' ')
        reply = input( "(y/n) ? " )
        if reply in 'yY' and reply != '':
            updateBook()
            fileBook()
            return
        else:
            import sys
            sys.exit("No new data/file added/changed at this time ...")
           
    #ok ... file is there ... or a new book and file were created ...
    lines = f.readlines()
    f.close() # now ...
   
    num = len(lines) # num is number of lines
    num = num//2 # new // for integer division
    for n in range (num):
        name = lines[n*2].rstrip() # take off '\n' char at end
        phone = int( lines[n*2+1].rstrip() ) # and ... make an 'int'       
        book.append( Entry(name, phone) ) # NEW copy in mutable Python list object 'book'
       
def showBook():
    for n in range ( len(book) ):
        #print "%4d  %-20s %s " % ( n+1, book[n].name, book[n].phone ),
        print("{0:4d}  {1:20} {2} ".format( n+1, book[n].name, book[n].phone), end=' ')
        if (n+1) % 2 == 0: print()

    if len(book) % 2 ==1: print()
   
def editContact():
    while 1:
        try:
            print("\nWhich contact number ( 1..", len(book), ") ? ", end=' ')
            contactNum = int(input())
            if 1 <=  contactNum <= len(book):
                break # ... since ... good number
            else:
                print("Re-enter in valid range of 1 to", len(book), "...")
        except:
            print("Not legal numeric input.  Please re-enter.")
           
    name = input( "Enter name   " )
    phone = input( "Enter phone  " )
    while not isValidPhone( phone ):
        phone = input( "Enter phone  " )
       
    phone = int( phone )
    book[contactNum-1] = Entry(name, phone)

def showMenu():
    showBook()
    print("\nTotal contacts now in memory =", len(book))
    reply = input( "Add contacts, Edit contacts, or Quit: (a, e, q) ? " )
    if reply == 'a' or reply == 'A':
        updateBook()
        fileBook()
    elif reply == 'e' or reply == 'E':
        editContact()
        fileBook()   
    elif reply == 'q' or reply == 'Q':
        global done # done is a Global variable
        done = True


# --- main stuff begins here --- #

inputBook_fromFile()
while 1: # do forever ... until done ... then break
    showMenu()
    if done:
        break

# --- Note: The menu here is still ... just a start --- #
# --- It will be expanded as we add more functions. --- #

« Last Edit: December 27, 2008, 10:14:20 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #11 on: September 01, 2008, 04:14:22 PM »
Chapter 15 continued ...


Code: [Select]
# editContacts2.py

# Chapter 15:
# The Computer takes control of its files and ...
# adds, edits, deletes, sorts and xDups (chops-duplicates).

myDataFile = "myRecords.dat"

class Entry:
    def __init__(self, theName, thePhoneNumber):
        self.name = theName
        self.phone = thePhoneNumber

book = []  # create a global Python 'list' called 'book'

def isValidPhone( numStr ): # check that phone number is TEN DIGITS
    if len( numStr ) != 10:
        print("Error: Phone number must have 10 digits.")
        return False
    for character in numStr:
        if character not in "0123456789":
            print("Error: Must be integer only input for Phone number.")
            return False
    return True

def addToBook():
    while 1:
        name = input( "Name (or press 'Enter' to exit) : " ).rstrip()
        if len( name ) == 0:
            break # exit if 'Enter' pressed to exit
        phone = input( 'Phone : ' )

        # check that phone number is TEN digits only
        if not isValidPhone( phone ):
            continue # ... do next while loop ...

        # If we reach here ... ok to convert raw 'str' input to 'int'
        phone = int( phone )
       
        # Must reply 'yY' or will repeat while loop again ...
        reply = input( name + ', ' + str(phone) + ' Ok (y/n) ? ' )
        if reply[0] == 'y' or reply[0] == 'Y':
            book.append( Entry(name, phone) ) # copy appended to Global 'book' type 'list'
            print() # blank line to space to next entry
            break
        # else ...
        print("Try entry again ...\n")
       
def updateBook():
    while 1:
        addToBook()
        reply = input( 'More (y/n) ? ' )
        if reply in 'nN' and reply != '':
            break

def fileBook():
    f = open( myDataFile, "w" );
    for person in book:
        f.write( person.name + "\n" )
        f.write( str(person.phone) + "\n" )
    f.close()
   
def inputBook_fromFile():
    # see if such a file exists ...
    try:
        f = open( myDataFile, "r" )   
    except:
        print("\nThere was some problem reading your file. " \
              "Perhaps it doesn't exist?" \
              "\nDo you want to start a new contact book ", end=' ')
        reply = input( "(y/n) ? " )
        if reply in 'yY' and reply != '':
            updateBook()
            fileBook()
            return
        else:
            import sys
            sys.exit("No new data/file added/changed at this time ...")
           
    #ok ... file is there ... or a new book and file were created ...

    lines = f.readlines()
    f.close() # now ...
   
    num = len(lines) # num is number of lines
    num = num//2 # note new // integer division replaces / ...
    for n in range(num):
        name = lines[n*2].rstrip() # take off '\n' char at end
        phone = int( lines[n*2+1].rstrip() ) # and ... make an 'int'       
        book.append( Entry(name, phone) ) # NEW copy in mutable Python list object 'book'

       
def showBook():
    for n, item in enumerate(book):
        print("{0:4d}  {1:20} {2} ".format( n+1, item.name, item.phone ), end=' ')
        if (n+1) % 2 == 0: print()

    if len(book) % 2 ==1: print()

def editContact():
    while 1:
        try:
            print("\nWhich contact number, '0' to exit, ( 1..", len(book), ") ? ", end=' ')
            contactNum = int(input())
            if 1 <=  contactNum <= len(book):
                break # ... since ... good number
            elif contactNum ==0:
                return
            else:
                print("Re-enter in valid range of 1 to", len(book), "...")
        except:
            print("Not legal numeric input.  Please re-enter.")
           
    name = input( "Enter name   " )
    phone = input( "Enter phone, '0' to exit, " )
    if phone == "0":
        return
    while not isValidPhone( phone ):
        phone = input( "Enter phone  " )
       
    phone = int( phone )
    book[contactNum-1] = Entry(name, phone)

def deleteContact():
    while 1:
        try:
            print("\nWhich contact number, '0' to exit, ( 1..", len(book), ") ? ", end=' ')
            contactNum = int(input())
            if 1 <=  contactNum <= len(book):
                break # ... since ... good number
            elif contactNum ==0:
                return
            else:
                print("Re-enter in valid range of 1 to", len(book), "...")
        except:
            print("Not legal numeric input.  Please re-enter.")

    # if we arrive here ... we have a good number.
    # So ... now can delete ...
    del book[contactNum-1]
   
# These simple sorts work well for small data sets
# Try converting this 'sort' to a 'bubble sort' ...
def sortBook(): # a novel select and insert sort ...
    top = len(book)
    #find largest and switch with top, then decrement top
    #then next largest and switch with top-1, then ...
    largest_j = 0
    j = 1
    while top > j:
        while j < top:
            if book[j].name > book[largest_j].name:
                largest_j = j
            j += 1

        # debug ...   
        # print largest_j, top, book[top-1].name
   
        # switch largest with top and decrement top
        book[largest_j], book[top-1] = book[top-1], book[largest_j]
        top -= 1;
        # get ready for next loop ...
        largest_j = 0
        j = 1

def xDupsInBook():
    i =1
    while i < len( book ):
        while  i < len( book ) and (book[ i ].name == book[ i-1 ].name)  :
            del book[ i ]
           
        i += 1

def showMenu(): # returns True if done, False if not done ...
    showBook()
    print("\nTotal contacts now in memory =", len(book))
    reply = input( "Add, Delete, Edit, Sort, Xdups or Quit (a, d, e, s, x, q) ? " )
    if reply == 'a'   or reply == 'A':
        updateBook()
        fileBook()
    elif reply == 'd' or reply == 'D':
        if len(book)>0:
            deleteContact()
            fileBook()
    elif reply == 'e' or reply == 'E':
        editContact()
        fileBook()
    elif reply == 's' or reply == 'S':
        if len(book) >0:
            sortBook()
            fileBook()
    elif reply == 'x' or reply == 'X':
        if len(book) >0:
            sortBook()    # Just in case not sorted already #
            xDupsInBook() #  This NEEDS a presorted 'list'  #
            fileBook()
    elif reply == 'q' or reply == 'Q':
        return True # done

    # if reach hear
    return False # not done


# --- main stuff begins here --- #

inputBook_fromFile()
done = False
while not done:
    done = showMenu()

# --- Now the menu here is looking much more complete.  --- #
# --- It may be expanded as you create other functions. --- #


And here is a way that many Python users might do this kind of data processing, using a Python dictionary ...


Code: [Select]
# editContacts2a.py

# Chapter 15:
# The Computer takes control of its files and ...
# adds, edits, deletes, sorts ... and doesn't allow duplicates.

# An implementation of records in Python using a Python Dictionary

myDataFile = "myRecords.dat"

book = {} # our empty dictionary ...

def isValidPhone( numStr ): # check that phone number is TEN DIGITS
    if len( numStr ) != 10:
        print("Error: Phone number must have 10 digits.")
        return False
    for character in numStr:
        if character not in "0123456789":
            print("Error: Must be integer only input for Phone number.")
            return False
    return True

def addEntry():
    while 1:
        name = input( "Name (or press 'Enter' to exit) : " ).rstrip()
        if len( name ) == 0:
            break # exit if 'Enter' pressed to exit
        phone = input( 'Phone : ' )

        # check that phone number is TEN digits only
        if isValidPhone( phone ) == False:
            continue # ... do next while loop ...

        # If we reach here ... ok to convert raw 'str' input to 'int'
        phone = int( phone )
       
        # Must reply 'yY' or will repeat while loop again ...
        reply = input( name + ', ' + str(phone) + ' Ok (y/n) ? ' )
        if reply[0] == 'y' or reply[0] == 'Y':
            book[name] = phone
            print() # blank line to space to next entry
            break
        # else ...
        print("Try entry again ...\n")
       
def updateBook():
    while 1:
        addEntry()
        reply = input( 'More (y/n) ? ' )
        if len( reply) > 0 and (reply[0] == 'n' or reply[0] == 'N'):
            break

def fileBook():
    f = open( myDataFile, "w" );
    for name in book:
        f.write( name + "\n" )
        f.write( str(book[name]) + "\n" )
    f.close()
   
def inputBook_fromFile():
    # see if such a file exists ...
    try:
        f = open( myDataFile, "r" )   
    except:
        print("\nThere was some problem reading your file. " \
              "Perhaps it doesn't exist?" \
              "\nDo you want to start a new contact book ", end=' ')
        reply = input( "(y/n) ? " )
        if( len(reply) > 0 and (reply[0] == 'y' or reply[0] == 'Y') ):
            updateBook()
            fileBook()
            return
        else:
            import sys
            sys.exit("No new data/file added/changed at this time ...")
           
    #ok ... file is there ... or a new book and file were created ...

    lines = f.readlines()
    f.close() # now ...
   
    num = len(lines) # num is number of lines
    num = num//2 # note: integer division is now //
    for n in range (num):
        name = lines[n*2].rstrip() # take off '\n' char at end
        phone = int( lines[n*2+1].rstrip() ) # and ... make an 'int'       
        book[name] = phone
 
def showBook():
    n =1
    for name in book:
        print("{0:4d}  {1:20} {2} ".format( n, name, book[name] ), end=' ')
        if n % 2 == 0: print()
        n +=1
    # if odd number of entries ...
    if len(book) % 2 ==1: print()

def show_sorted():
    n =1
    print("\nSorted ...")
    for name in sorted(book):
        print("{0:4d}  {1:20} {2} ".format( n, name, book[name] ), end=' ')
        if n % 2 == 0: print()
        n +=1

    if len(book) % 2 ==1: print
    input("\nPress 'Enter' key to continue ... ")
    print()
       
def editContact():
    print("\nWhich name, 'Enter' to exit ? ", end=' ')
    contactName = input()
    if contactName in book:
        newname = input( "Enter name   " )
        newphone = input( "Enter phone, '0' to exit, " )
        if newphone == '0':
            return
        while not isValidPhone( newphone ):
            newphone = input( "Enter phone  " )
           
        newphone = int( newphone )
        del book[contactName]
        book[newname] = newphone

def deleteContact():
    print("\nWhich contact name, 'Enter' to exit ? ", end=' ')
    contactName = input()
    if contactName in book:
        del book[contactName]
    else:
        print(contactName, 'not in book.')
   
def showMenu(): # returns True if done, False if not done ...
    showBook()
    print("\nTotal contacts now in memory =", len(book))
    reply = input( "Add, Delete, Edit, Sort, or Quit (a, d, e, s, q) ? " )
    if reply == 'a'   or reply == 'A':
        updateBook()
        fileBook()
    elif reply == 'd' or reply == 'D':
        if len(book)>0:
            deleteContact()
            fileBook()
    elif reply == 'e' or reply == 'E':
        editContact()
        fileBook()
    elif reply == 's' or reply == 'S':
        if len(book) >0:
            show_sorted()
    elif reply == 'q' or reply == 'Q':
        return True # done

    # if reach hear
    return False # not done


# --- main stuff begins here --- #

inputBook_fromFile()
done = False
while not done:
    done = showMenu()

# --- Now the menu here is looking much more complete.  --- #
# --- It may be expanded as you create other functions. --- #
« Last Edit: December 28, 2008, 01:51:43 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #12 on: September 01, 2008, 04:48:13 PM »
Chapter 16: The Computer … vast OS’s … and the garbage collects?  (Leaving some space here, for now ...)

This chapter is a one BIG research project ... firstly on operating systems ...  and on managing memory and other bits inside the ‘box’.

From the early day when there were NO OS’s …

   1. OS's have been growing bigger and very complex ...
   2. So what did OS's start out as ...
   3. What are some present BIG risks / benefits ... (because of this complexity?)
   4. What is their future ... if any?
   5. What do these mean: 'memory leaks' and 'garbage collection' and is there a need for real time computing still?
      (Give examples ... Try to google for these.)
   6. What is the relationship between the executable file that an assembler/compiler like HLA produces, or the
       script file that an Interpreter like Python uses ... and an OS like Windows XP or LINUX?
   7. What do these signify:  direct memory access and protected memory? In the old MS DOS days, the OS
       did not forebid the programmer to poke values directly into memory. What are these dreaded fatal
       protected memory faults about anyways? 
       See:  http://webster.cs.ucr.edu/Page_win32/IczelionTuts/tut1.html
   8. Note that not all computers need to have disks, or screens, or keyboards, or mouses, etc ...
       Find examples of some very dedicated computing usage, including ones that may not even require an OS.

The following was taken from:
http://webster.cs.ucr.edu/Page_win32/IczelionTuts/tut1.html

...


« Last Edit: September 01, 2008, 05:55:38 PM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #13 on: September 01, 2008, 06:03:46 PM »
The following was taken from the beta version of the online e-Book, (to hold some space here too, for now), ...

BEGINNING COMPUTER PROGRAMMING (using HLA)  ...

Now here is an excellent project for someone ... to modify the HLA Windows version ... to a Python Windows or console version ... Take your pick ... or both?

Chapter 17: The Computer delivers daily Manna ...

Here is a fun little project that uses a similar record structure to our previous readFile in Chapter 14.  We will need to find today's date and the dayNumber in the year ... January 1 is day 1.  We can add more records to our file dailyManna.txt if we like. (We will need to keep the same record structure, though.)

We start off by reading the records in dailyManna.txt into an array of records set to a maxDays of 366 ... to allow for leap years.  Recall, this is an array of pointers. (HLA strings are pointers.) So ... it only needs 4 x 2 x 366 bytes of memory at compile time. Later, as we read in the strings from the file dailyManna.txt, we will allocate sufficient memory for each string using fileio.a_gets( inFileHandle );  // which returns the address to each new string in eax

We also will count the records so we will know how may we have ... and also, so we do not exceed the maxDays size of the array.

We will use modular division to find the offset into the array for todays date.

Take a look and see if you can figure out what does what.  You can google on unknown words like this example of key words: HLA day number in year.  Oh yes, the program uses two data files: dailyManna.txt and PSmessage.hhf. These need to be in the same folder as the getManna.hla file.  When you are ready to compile/assemble the getManna.hla file use this command:  hla -w getManna.

Yes ... this is a Windows example!  Cool French too ... eh!

Now let's get some food:  ...




« Last Edit: September 02, 2008, 04:22:26 AM by David »

Offline David

  • Sr. Member
  • ****
  • Posts: 440
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #14 on: September 01, 2008, 06:33:51 PM »
BEGINNING COMPUTER PROGRAMMING  Chapter 18: OOP ... goes the computer


You may want to review Chapter 11: The Computer does some Algebra with real numbers ... that introduces the FPU and real numbers ... up to Chapter 15, and especially Chapter 13: The Computer files its Records before you dig into the following. We are about to venture into some very useful stuff that will also help your math insights and skills. Recall that a straight line is the shortest distance between two points. If you were to plot, on some graph paper, two points in Euclidean 2 space, calling them A and B with co-ordinates (x1, y1) and (x2, y2) respectively, then the distance between A and B is given by the formula sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ). This is sometimes abbreviated as sqrt( dX*dX + dY*dY ) … or spelled out in words … the square_root_of ( (the difference in the x’s squared) + (the difference in the y’s squared) ). Our first little program will do just this. We will use real numbers, (HLA type real32’s), for each value of x and y. You may recall that a real number is just a positive or negative or zero decimal number. This includes all fractions, (rational numbers), and all numbers (irrational) like the square root of 2 and PI that never have a repeating pattern to their decimal part … Thus, we always just approximate reals, (i.e. just the irrational reals), to some number of decimal places. You may have seen somewhere that 100.001 can be represented by 1.00001e2. This means the same thing as 1.00001 * 100 which we know is equal to 100.001. The HLA default output for real numbers is in a format like 1.00001e2.

So let’s dig in. Don’t be afraid to make changes and see the output. You can uncomment the line that I commented out … to verify that the output there is what is expected.


Here is a quick Python version, to get you started ...

Code: [Select]

# distanceAndPoints.py
'''
    To find the distance between 2 points, we may
    use the fact that the square on the hypotenuse,
    of any right angled triangle, is equal to the sum
    of the squares on the other two sides ...

    See: The hypotenuse of a right triangle
    http://en.wikipedia.org/wiki/Hypotenuse
'''

# We can store our points (on the 2-D XY plane) like this ...

class Point:
    def __init__(self, x, y):   # a constructor
        self.x = x
        self.y = y
   
    def __str__(self):          # so we can print a Point p
        return str( (self.x,self.y) )

    def length(self):
        return ( (self.x)**2 + (self.y)**2 )**0.5
       
    def distance(self, p):
        return ( (self.x-p.x)**2 + (self.y-p.y)**2 )**0.5
       
    def direction(self):
        import math
        a = math.atan2(self.y,self.x)*180/math.pi
        if a >= 0:
            return a
        else:
            return a+360

    def angle(self, p):
        import math
        a = (math.atan2(p.y,p.x)-math.atan2(self.y,self.x))*180/math.pi
        if a >= 0:
            return a
        else:
            return a+360
   
def getxy(message):
    while 1:
        try:
            x, y = eval(input('Enter ' + message +  ' point x, y : ' ))
            return x, y
        except:
            print('Error!  Enter two numbers separated by a comma.')

       
more = True
while more:
    x, y = getxy('1st')
    p1 = Point(x, y)
    print('p1 =',p1, ':: p1.length() =', p1.length(), ':: p1.direction() =', p1.direction())

    x, y = getxy('2nd')
    p2 = Point(x, y)
    print('p2 =',p2, ':: p2.length() =', p2.length(), ':: p2.direction() =', p2.direction())
   
    print("The distance 'p1.distance(p2)' =", p1.distance(p2))
    print("The angle 'p1.angle(p2)' =", p1.angle(p2))
    more = ( input('More y/n ? ').upper() != 'N' )

# Just some playing with a 30, 60, 90 deg triangle,
# with sides 1, srqr(3), 2 ... (to check the output
# of atan2 with some known values.)
import math
print(math.atan2(3**0.5, 1)*180/math.pi)  # 60 degs with y/x = sqrt(3)/1
print(math.atan2(1, 3**0.5)*180/math.pi)  # 30 degs with y/x = 1/sqrt(3)


Code: [Select]

# Triangles1.py

class Point:
    def __init__(self, x, y):   # a constructor
        self.x = x
        self.y = y
   
    def __str__(self):          # so we can print a Point p
        return str( (self.x,self.y) )

    def length(self):
        return ( (self.x)**2 + (self.y)**2 )**0.5
       
    def distance(self, p):
        return ( (self.x-p.x)**2 + (self.y-p.y)**2 )**0.5
       
    def direction(self):
        import math
        a = math.atan2(self.y,self.x)*180/math.pi
        if a >= 0:
            return a
        else:
            return a+360

    def angle(self, p):
        import math
        a = (math.atan2(p.y,p.x)-math.atan2(self.y,self.x))*180/math.pi
        if a >= 0:
            return a
        else:
            return a+360

    def vector(self, p):
        return Point(p.x-self.x, p.y-self.y)
   
class Triangle():
    def __init__(self, p1, p2, p3 ):
        self.p1 = Point(p1.x, p1.y)
        self.p2 = Point(p2.x, p2.y)
        self.p3 = Point(p3.x, p3.y)

    def __str__(self):
        return '( ' + str( (self.p1.x,self.p1.y) ) + ', ' \
               + str( (self.p2.x,self.p2.y) ) + ', ' \
               + str( (self.p3.x,self.p3.y) ) + ' )'
   
    def sides(self):
        a = self.p1.distance(self.p2)
        b = self.p2.distance(self.p3)
        c = self.p3.distance(self.p1)
        return a, b, c
       
    def perimeter(self):
        a, b, c = self.sides()
        return a+b+c

    def area(self):
        a, b, c = self.sides()
        s = (a+b+c)/2.0
        return (s*(s-a)*(s-b)*(s-c))**0.5

    def angles(self):
        a = self.p1.vector(self.p2)
        b = self.p2.vector(self.p3)
        c = self.p3.vector(self.p1)
        A = 180 - b.angle(c)
        B = 180 - c.angle(a)
        C = 180 - a.angle(b)
        return A, B, C

def getxy(message):
    while 1:
        try:
            x, y = eval(input('Enter ' + message +  ' point x, y : ' ))
            return x, y
        except:
            print('Error!  Enter two numbers separated by a comma.')

more = True
while more:
    x, y = getxy('1st')
    p1 = Point(x, y)
    print('p1 =',p1)
    x, y = getxy('2nd')
    p2 = Point(x, y)
    print('p2 =', p2)
    x, y = getxy('3rd')
    p3 = Point(x, y)
    print('p3 =', p3)

    va = p1.vector(p2)
    da = va.direction()
    print('va = p1.vector(p2) =', va, ':: da = va.direction() =', da)
    vb = p2.vector(p3)
    db = vb.direction()
    print('vb = p2.vector(p3) =', vb, ':: db = vb.direction() =', db)
    vc = p3.vector(p1)
    dc = vc.direction()
    print('vc = p3.vector(p1) =', vc, ':: dc = vc.direction() =', dc)

    t = Triangle(p1, p2, p3)
    print('Triangle t =', t)
    print('t.sides() =', t.sides())
    print('t.angles() =', t.angles())
    print('t.perimeter() =', t.perimeter())
    print('t.area() =', t.area())

    more = ( input('More y/n ? ').upper() != 'N' )


Code: [Select]

# Triangles2.py

# Points in 3-D space may be simply stored using a Python 'list 'for a 'container'.
# Each 'list' has 3 elements, (i.e. a 3-D 'vector').

# Here ... a Triangle is simply a list containing 3 lists ... and EACH of these 3 lists
# being ... a list of 3 values ... one value for each x, y, z of each point in 3-space
       
def distance(v1, v2):
    if len(v1) != len(v2):
        print('Error! Both vectors passed in must be of equal dimension.')
        return
    sumOfSquares = 0
    for i in range(len(v1)):
        sumOfSquares += (v2[i]-v1[i])**2
    return sumOfSquares**0.5

def dotProduct(v1, v2):
    if len(v1) != len(v2):
        print('Error! Both vectors passed in must be of equal dimension.')
        return
    sumProducts = 0
    for i in range(len(v1)):
        sumProducts += v2[i]*v1[i]
    return sumProducts

def length(v):
    return dotProduct(v, v)**0.5

def angle(v1, v2):
    import math
    a = length(v1)
    b = length(v2)
    dotP = dotProduct(v1, v2)
    if (a*b)==0: # let zero vector have angle 0
        return 0
    if dotP/( a*b ) >=1 or dotP/(a*b) <=-1 : # allow for rounding errors
        return 0
    return 180/math.pi * math.acos(dotP/(a*b))

def vector(v1, v2):
    if len(v1) != len(v2):
        print('Error! Both vectors passed in must be of equal dimension.')
        return
    v =[]
    for i in range(len(v1)):
        v.append(v2[i]-v1[i])
    return v

def sides(t):
    s = []
    for i in range(len(t)):
        s.append(distance(t[i],t[(i+1) % len(t)]))
    return s
   
def area(t):
    a, b, c = sides(t)
    s = (a+b+c)/2.0
    if s-a <= 0 or s-b <=0 or s-c <= 0:
        return 0;
    return (s*(s-a)*(s-b)*(s-c))**0.5

def perimeter(t):
    if not area(t):
        return 0
    d=0
    for each_d in sides(t):
        d += each_d
    return d

def vectors(t):
    s = []
    for i in range(len(t)):
        s.append(vector(t[i], t[((i+1)%len(t))]))
    return s

def angles(t):
    v = vectors(t)
    angs = []
    if not area(t):
        for i in range(len(t)):
            angs.append( 0 )
        return angs
    for i in range(len(v)):
        angs.append(180 - angle( v[((i+1)%len(v))], v[((i+2)%len(v))]))
    return angs

def angles2(t):
    if not area(t):
        return 0,0,0
    a,b,c = sides(t)
    import math
    A = 180/math.pi*math.acos((b*b+c*c-a*a)/(2*b*c));
    B = 180/math.pi*math.acos((c*c+a*a-b*b)/(2*c*a));
    C = 180/math.pi*math.acos((a*a+b*b-c*c)/(2*a*b));
    #C = 180-A-B;
    return A,B,C
   

def getxyz(message):
    while 1:
        try:
            x, y, z = eval(input('Enter ' + message +  ' point x, y, z : ' ))
            return x, y, z
        except:
            print('Error!  Enter three numbers separated by commas.')

           
more = True
while more:
   
    x, y, z = getxyz('1st')
    p1 = [x, y, z] # create 1st point
    print('p1 =', p1)
    x, y, z = getxyz('2nd')
    p2 = [x, y, z] # create 2nd point
    print('p2 =', p2)
    x, y, z = getxyz('3rd')
    p3 = [x, y, z] # create 3rd point
    print('p3 =', p3)
    print()
   
    a = vector(p1, p2)
    print('a = p1->p2 =', a)
    b = vector(p2, p3)
    print('b = p2->p3 =', b)
    c = vector(p3, p1)
    print('c = p3->p1 =', c)
    print()
   
    print('distance(p1, p2) =', distance(p1, p2))
    print('dotProduct(p1, p2) =', dotProduct(p1, p2))
    print('length(p1)*length(p2) =', length(p1)*length(p2))
    print('angle(p1, p2) =', angle(p1, p2))
    print('C = interior angle(a, b) =', 180 - angle(a, b))
    print()

    print('distance(p2, p3) =', distance(p2, p3))
    print('dotProduct(p2, p3) =', dotProduct(p2, p3))
    print('length(p2)*length(p3) =', length(p2)*length(p3))
    print('angle(p2, p3) =', angle(p2, p3))
    print('A = interior angle(b, c) =', 180 - angle(b, c))
    print()

    print('distance(p3, p1) =', distance(p3, p1))
    print('dotProduct(p3, p1) =', dotProduct(p3, p1))
    print('length(p3)*length(p1) =', length(p3)*length(p1))
    print('angle(p3, p1) =', angle(p3, p1))
    print('B = interior angle(c, a) =', 180 - angle(c, a))
    print()

    t = [p1, p2, p3] # create triangle, a list of lists ...
    print('The triangle t is', t)
    print('with area(t) =', area(t))
    print('and perimeter(t) =', perimeter(t))

    print('The sides(t) a, b, c are', sides(t))
    print('The direction vectors(t) of sides a, b, c are', vectors(t))
    print('The zero corrected interior angles(t) A, B, C are', angles(t))
    print('The zero corrected confirm angles2(t) A, B, C are', angles2(t))

    more = ( input('More y/n ? ').upper() != 'N' )


If you entered 2, 3 and 0, 0  or the other way around ... either way you should have the answer ...

The distance is:  3.60555127546

If you entered  0, 0 and  3, -4  or the other way around ... either way you should have the answer ...

The distance is:  5.0


So what does this have to do with OOP?  Well, we have just defined an OBJECT, a point ... and described one property of points ... they have a distance between them.  With Objected Oriented Programming, we will keep together, i.e. encapsulate, all the data and all the functions that relate to some object.

Another way that we can think of a point object is ... as a vector.  We can imagine the vector, for now, as having its tail at the origin, i.e. at (0, 0) ... and its head at the point (x, y).  A vector object can also be described by an unique length and an unique direction angle (in the range 0..365.999999999999... degrees) from some line, say the x-axis, (or, -179.9999999999999... to +180 degrees.)

If we have some point or vector then, represented by (x, y) ... we can think of it

    * as the 2 real numbers of the co-ordinates x and y ...


OR ...

    * as a vector with length = sqrt( x*x + y*y ) and direction angle theta = arctan( y/x ).


NOTE!  Either way, TWO unique real numbers are sufficient to describe this OBJECT!  ( i.e a 2-Dimensional vector - has just TWO DIMENSIONS! )

For this example, we will choose the two real numbers that uniquely describe our point, the head of the vector.  And we will also associate functions with this encapsulation of information, concerning this point/vector object ...  i.e.procedures and methods that readily let us calculate / access or get and report this info ... or that set / reset / change / manipulate the numbers that are the data (point) of this object.  To encapsulate all this ... we (will eventually) use a CLASS and give that class a class name.  And all members of that class will use that class name ... similar to what we did with the data inside a record.  Recall that we accessed parts of a record with the dot operator. ... We will likewise use this same dot operator to get to the members of the Class Object ... whether they be data ... or functions that act on that data.

You may not have heard yet ... that the tangent or tan of some angle is just the rise over the run in the right angled triangle described by the points (0, 0), (x, 0),  and ( x, y) ... In this case ... y/x.

And if we know x and y, we can calculate y/x = tan( theta ).  Theta is the angle measured cc (counterclockwise) from the x-axis to the point ( x, y).

Once we know the value of tan( theta ) ... we can look up that value, on a graph or in tables, or use the inverse tan of that value, (same thing as arctan), to find theta.

We will get the FPU unit to do our conversions for us.  If we feed into the FPU function fpatan() ... y and x ... the function will find y/x and then the inverse tan (i.e. the arctan) of the fraction ... i.e. fpatan() outputs theta if we input y and then x ... IT IS IN RADIANS so we will multiply by 360/( 2*pi ) to convert to degrees, where the degrees are counted cc from the positive X-axis. (Recall that in one complete revolution of 360 degrees there are 2pi radians. And ... for a circle with radius1, the circumference is 2*r*pi  = 2*1*pi  = 2*pi ).

See below for the rest of  program vectors2;

        fld( y );                  // now have y in st0
        fld( x );                  // now have x in st0, and y in st1
        fpatan();               // take arctan(st1/st0) and store in st1; pop stack
        fmulp( radTodeg ); // convert to degrees ... declared as: radTodeg:    real32:=    360 / ( 2 * 3.14159 );


So here ... where we know y, the rise ... and x, the run ...  then the rise/run = y/x = tan( theta ). Thus we find the direction angle for our vector by plugging this into the formula ...  theta = arctan( y/x )

But if we instead knew the direction angle theta and the length of some vector ... we could then find the unique(x, y) that represents the head of that vector, if we place its tail at the origin.  (We  would use x = lengthOfVector * cos( theta )  and  y = lengthOfVector* sin( theta );  Note that sin(theta)/cos(theta) = tan(theta) = y/x for all theta.)

For further quick reference see:

http://answermath.com/sin.htm

 http://mathworld.wolfram.com/x-Axis.html

http://www.physics.uoguelph.ca/tutorials/vectors/vectors.html


...

To continue click on the 2 in this line Pages: [1] 2   Go Up in the lower LEFT corner of the screen ...
« Last Edit: November 02, 2009, 01:23:01 AM by David »