Computer Science Canada

How to make buttons call a function?

Author:  Decadence666 [ Tue Oct 24, 2006 5:56 pm ]
Post subject:  How to make buttons call a function?

Hey, im new here, and like alot of people, learning turing as a Gr. 10 course. I'm pretty good with php and new to turing, and im having some problems. I made a cash register program for an assignment, but now im making it with a GUI, and im running into some problems.

code:
import GUI

View.Set ("graphics:600;600") % Shrink the run window


function addnums (num :int) : int

    put "yes"

end addnums


% The procedure called when the button is pushed.
procedure PutHello
    put "ced"
end PutHello

procedure p_one
    addnums (5)
end p_one

var one : int := GUI.CreateButtonFull (290, 500, 100, "1 - One", PutHello, 100, '^D', true)
var two : int := GUI.CreateButtonFull (395, 500, 100, "2 - Two", PutHello, 100, '^D', true)
var three : int := GUI.CreateButtonFull (500, 500, 100, "3 - Three", PutHello, 100, '^D', true)

var four : int := GUI.CreateButtonFull (290, 395, 100, "4 - Four", PutHello, 100, '^D', true)
var five : int := GUI.CreateButtonFull (395, 395, 100, "5 - Five", PutHello, 100, '^D', true)
var six : int := GUI.CreateButtonFull (500, 395, 100, "6 - Six", PutHello, 100, '^D', true)

var seven : int := GUI.CreateButtonFull (290, 290, 100, "7 - Seven", PutHello, 100, '^D', true)
var eight : int := GUI.CreateButtonFull (395, 290, 100, "8 - Eight", PutHello, 100, '^D', true)
var nine : int := GUI.CreateButtonFull (500, 290, 100, "9 - Nine", PutHello, 100, '^D', true)

% Now process events until the user aborts the program.
loop
    exit when GUI.ProcessEvent
end loop


(yes i just modded the hello world program)

This is what is supposed i want it to be: You press the buttons the numbers appear, then you press enter. The first sale amount is enter, etc etc, then it calculates the total cost + tax. The problem is, i can't get the numbers from the buttons to pass to a function, (when i try to call a function from inside the 'p_one' procedure, it says I can't do that)

Sorry if i'm being unclear ( the program is still barley finished so it may be hard to tell what im trying to do) ... and thanks in advance for any help.

Author:  Decadence666 [ Tue Oct 24, 2006 6:00 pm ]
Post subject: 

appologies for double posting, but there is no edit button... heres a more clear version of the program!



IGNORE THE FIRST SET OF CODE

code:
import GUI

View.Set ("graphics:600;600") % Shrink the run window


function addnums (num :int) : int

    put "THIS fuNCTION IS BEING CALLED!!!"

end addnums


% this is the procedure that will call the fucntion
procedure p_one
    addnums (5)
end p_one

%buttons
var one : int := GUI.CreateButtonFull (290, 500, 100, "1 - One", p_one, 100, '^D', true)
var two : int := GUI.CreateButtonFull (395, 500, 100, "2 - Two", p_one, 100, '^D', true)
var three : int := GUI.CreateButtonFull (500, 500, 100, "3 - Three", p_one, 100, '^D', true)

var four : int := GUI.CreateButtonFull (290, 395, 100, "4 - Four", p_one, 100, '^D', true)
var five : int := GUI.CreateButtonFull (395, 395, 100, "5 - Five", p_one, 100, '^D', true)
var six : int := GUI.CreateButtonFull (500, 395, 100, "6 - Six", p_one, 100, '^D', true)

var seven : int := GUI.CreateButtonFull (290, 290, 100, "7 - Seven", p_one, 100, '^D', true)
var eight : int := GUI.CreateButtonFull (395, 290, 100, "8 - Eight", p_one, 100, '^D', true)
var nine : int := GUI.CreateButtonFull (500, 290, 100, "9 - Nine", p_one, 100, '^D', true)


loop
    exit when GUI.ProcessEvent
end loop


Author:  Ultrahex [ Tue Oct 24, 2006 7:33 pm ]
Post subject: 

Its Actually Rather Simple

A Function Returns a Value For Example...

put add(5,2)
add(5,2) returns 7
so it outputs the number 7

A Procedure HOWEVER runs a set of actions without returning a value.

so you can just do

add(5,2)

and in the procedure
it does
put a+b

for example:

code:

var num1:=5
var num2:=2

procedure p_add(a:int,b:int)
   put a+b , " This Is The Procedure"
end p_add

function f_add(a:int,b:int):int
result a+b
end f_add


%Using Function
put f_add(num1,num2)

%Using Procedure
p_add(num1,num2)
[/code]

Author:  Cervantes [ Tue Oct 24, 2006 7:43 pm ]
Post subject: 

Sorry, you can't do it. The reason is that the GUI widgets have associated with them an 'action procedure'. That is, a procedure that takes no parameters. That's what gets called when the widget is activated.

The reason it has to be an action procedure is because Turing is statically typed. That is, we must declare what types of variables our subroutines take, and they have to take that type of value. The subroutine that creates widgets takes as one of its arguments an action procedure. Because Turing is statically typed, we're not allowed to give it a function, because that's a different type than is an action procedure. Even a procedure that takes one parameter is different from an action procedure.

This wouldn't be too much of a problem if Turing supported anonymous functions/procedures. As it is, the best we can do is something like this:

code:

proc my_proc (a : int)
    % ...
end my_proc
proc my_proc1
    my_proc (1)
end my_proc1
proc my_proc2
    my_proc (2)
end my_proc2

var button1 := GUI.CreateButton (..., my_proc1)
var button2 := GUI.CreateButton (..., my_proc2)


With anonymous functions/procedures, we would be able to do something like this:
code:

proc my_proc (a : int)
    % ...
end my_proc

var button1 := GUI.CreateButton (..., lambda {my_proc (1)})
var button2 := GUI.CreateButton (..., lambda {my_proc (2)})

Where the lambda syntax creates an anonymous subroutine (or rather I wish it did -- lambda doesn't exist in Turing). For example,
code:

var a := lambda {put "Hello world"}
% equivalent to
proc a
    put "Hello world"
end a

or
code:

var a := lambda {|x : int| result x ** 2} : int
% equivalent to
function a (x : int) : int
    result x ** 2
end a

The parameters to my lambda function/procedure are given inside pipes ( |...| ) and the types are given as usual.


In conclusion, no, you can't give functions to GUI widgets. The best we can do is to define a bunch of action procs that call our functions or whatever you wanted with the appropriate arguments. This would be easier with anonymous functions/procedures, but alas Turing does not support this. If you're interested in anonymous functions/procedures, check out the Turing as a Functional Programming Language tutorial.

Author:  Decadence666 [ Tue Oct 24, 2006 8:04 pm ]
Post subject: 

Ok, thank you for your help Smile I figured that you would say something like "Turing can't do that", so in the meantime I managed to work a different system out, heres the code for anybody who's interested.


code:
import GUI

View.Set ("graphics:600;600") % Shrink the run window


var number : real := 0
var v_result : real := 0


procedure calculate

    if v_result = 0 then
   
        v_result := number
       
       
    elsif v_result > 999999 then
   
        put "Number Limit"
   
    else
       
        v_result := (v_result * 10) + number
       
    end if
   
end calculate



% this is the procedure that will call the fucntion
procedure p_one
    number := 1
    calculate()
    put v_result
    GUI.Refresh
end p_one

procedure p_two
    number := 2
    calculate()
    put v_result
    GUI.Refresh
end p_two

procedure p_three
    number := 3
    calculate()
    put v_result
    GUI.Refresh
end p_three

procedure p_four
    number := 4
    calculate()
    put v_result
    GUI.Refresh
end p_four

procedure p_five
    number := 5
    calculate()
    put v_result
    GUI.Refresh
end p_five

procedure p_six
    number := 6
    calculate()
    put v_result
    GUI.Refresh
end p_six

procedure p_seven
    number := 7
    calculate()
    put v_result
    GUI.Refresh
end p_seven

procedure p_eight
    number := 8
    calculate()
    put v_result
    GUI.Refresh
end p_eight

procedure p_nine
    number := 9
    calculate()
    put v_result
    GUI.Refresh
end p_nine

procedure p_zero
    number := 0
    calculate()
    put v_result
    GUI.Refresh
end p_zero


%buttons
var one : int := GUI.CreateButtonFull (290, 500, 100, "1 - One", p_one, 100, '^D', true)
var two : int := GUI.CreateButtonFull (395, 500, 100, "2 - Two", p_two, 100, '^D', true)
var three : int := GUI.CreateButtonFull (500, 500, 100, "3 - Three", p_three, 100, '^D', true)

var four : int := GUI.CreateButtonFull (290, 395, 100, "4 - Four", p_four, 100, '^D', true)
var five : int := GUI.CreateButtonFull (395, 395, 100, "5 - Five", p_five, 100, '^D', true)
var six : int := GUI.CreateButtonFull (500, 395, 100, "6 - Six", p_six, 100, '^D', true)

var seven : int := GUI.CreateButtonFull (290, 290, 100, "7 - Seven", p_seven, 100, '^D', true)
var eight : int := GUI.CreateButtonFull (395, 290, 100, "8 - Eight", p_eight, 100, '^D', true)
var nine : int := GUI.CreateButtonFull (500, 290, 100, "9 - Nine", p_nine, 100, '^D', true)
var zero : int := GUI.CreateButtonFull (290, 185, 100, "0 - Zero", p_zero, 100, '^D', true)
var enter : int := GUI.CreateButtonFull (395, 185, 100, "Enter", p_one, 100, '^D', true)
var decimal : int := GUI.CreateButtonFull (500, 185, 100, ". - Decimal", p_one, 100, '^D', true)

loop
    exit when GUI.ProcessEvent
end loop

Author:  ericfourfour [ Tue Oct 24, 2006 9:22 pm ]
Post subject: 

Quote:
"Turing can't do that"

Well not necessarily. Turing can in fact do do it. It is Holt Soft's GUI library that cannot do it. If you really want a unique system make your own using OOP. I would recommend having a parent action class from which the programmer derives children classes and override a method that does the action wanted. This however, may seem like overkill for someone who just started programming class but you did say you are pretty good at PHP (I don't know anything about PHP) so you may be up for the challenge.

Author:  Decadence666 [ Tue Oct 24, 2006 9:30 pm ]
Post subject: 

thats way to much for me, php was my first language, and i started about a year ago, i just got into and realized the power of OOP about a month.5 ago, but then i got grounded for a month and still am (cough) so havn't done much php in a while now Sad

i really don't plan to stick with turing, im going to learn it pretty good for this class, but we move on to Java next year so no need to obsess Razz

Author:  Clayton [ Wed Oct 25, 2006 7:43 am ]
Post subject: 

This is why templates are so useful in C++. A template is basically a means to stop functions from being statically typed. EG.

c++:

template <typename T>

void swap(T& a, T& b)
{
    T c = a
    a = b
    b = c
}


Basically the above code will swap two pieces of data as long as they are the same type. This happens because whenever the program is compiled, there is a copy of the swap function for each type that can be passed to it (bool, int, double etc). Unfortunately turing doesn't support this, as it would need to be able to support function overloading (which it doesn't). All this really shows is that Turing is lacking in areas that it kind of needs not to be.

In conclusion, if you wanted to be able to pass a function in GUI, the GUI syntax would have to include some sort of parameter that would allow GUI to not be statically typed.

Author:  Decadence666 [ Wed Oct 25, 2006 6:54 pm ]
Post subject: 

ic, ok... Well thanks for the help Smile


: