Aegidius
 Plüss   Aplulogo
     
 www.aplu.ch      Print Text 
© 2021, V10.4
 
  Jython
 
 

 

Handling User Input

The Input-Process-Output (IPO) model provides a basic concept of how computer works. To demonstrate the model, it is common to write short programs that opens a modal dialog with a single text field and an OK/Cancel button pair. When the OK button is hit, the dialog closes and the input data is processed by some simple algorithm. The result considered as output is displayed in another window (e.g. an message box or a console).

Python has a built-in function raw_input() to request user input from the console. TigerJython adds some convenient functions to read data from a modal input dialog. input() opens a dialog and the return value has the data type of the entry, either an int, a long, a float or a string. When the Cancel or the close button is hit, the program terminates.

# InputEx1.py

while True:
   x = input("Enter a string/int/float")  
   print "got : " + str(x)
   print str(type(x))      
JyTut11
Select InputEx1.py (Ctrl+C to copy, Ctrl+V to paste)

 

If a particular input data type is requested, inputInt(), inputFloat() or inputString() can be used. If the entry does not correspond to the requested type the dialog is redisplayed with an error message. (For inputFloat() an integer entry is converted to a float).

# InputEx2.py

while True:
   x = inputInt("What is your age?")      
   print "got : " + str(x)
   print str(type(x))        
JyTut12
Select InputEx2.py (Ctrl+C to copy, Ctrl+V to paste)

 

To prevent the program to terminate when the Cancel or close button is hit, inputString() takes a boolean parameter. When False is passed, the function returns None instead of terminating. By checking the return value for None it is possible to implement a user definable action, when the Cancel or close button is hit.

# InputEx3.py

name = ""
while name != None:
   name = inputString("Your name?", False)
   if name != None:
      print "Your name is " + name
print "All done"        
Jytut13
Select InputEx3.py (Ctrl+C to copy, Ctrl+V to paste)

 

To enter a boolean value, askYesNo() can be used. If the Yes button is hit, True is returned, if the No button is hit, False is returned, if the Close button is hit, the program terminates unless the function is called with a second parameter False.

# InputEx4.py

n = 0
isRunning = True
while isRunning:
   print n
   n += 1
   isRunning = askYesNo("Continue?")    
print "All done"  


Jytut14
Select InputEx4.py (Ctrl+C to copy, Ctrl+V to paste)

 

If you intend to run your program standalone (without an OS console or an IDE), you should not use the print statement (unless you redirect stdout to a GUI console). To output a single line of text, call msgDlg() and a modal message box with an OK button is opened. The program continues when the OK or Close button is hit.

# InputEx5.py

name = ""
while name != None:
   name = inputString("Your name?", False)
   if name != None:
      msgDlg("Your name is " + name)
msgDlg("All done")        
Jytut15
Select InputEx5.py (Ctrl+C to copy, Ctrl+V to paste)

 

Enumerations

To implement state-controlled algorithms (finite state machines, FSM), it is highly recommended to use literals to denominate the states (e.g. for a video player IDLE, PLAYING, PAUSED).

  videoplayer
 
Video player modeled as a state machine
from "Programmieren mit Kara" (modified)

Unfortunately Pyhthon/Jython does not support the enum data type, but TigerJython adds full support for them. The following example shows how it is simple and straightforward to implement the above state diagram using TigerJython's enums.

# EnumEx1.py

from gpanel import *

State = enum("IDLE", "PLAYING", "PAUSED")
state = State.IDLE

createGPanel() enableRepaint(False) while True: if kbhit(): ch = getKey() if ch == "p" or ch == "P": if state == State.IDLE: state = State.PLAYING elif state == State.PLAYING: state = State.PAUSED elif state == State.PAUSED: state = State.PLAYING if ch == "s" or ch == "S": if state == State.IDLE: state = State.IDLE elif state == State.PLAYING: state = State.IDLE elif state == State.PAUSED: state = State.IDLE delay(1) clear() pos(0.5, 0.5) circle(0.1) text(0.47, 0.49, str(state)) repaint()
Jytut16
Select EnumEx1.py (Ctrl+C to copy, Ctrl+V to paste)

Discussion: The implementation of enums in Jython requires to use the constructor of class enum to denominate the different enum values as string arguments (The enums are not really strings as you may argue, but members auf a class JEnum). We violate the standard convention and use a capital for the class instance State in order to follow the usual naming convention for enums in other languages.

The state transitions are triggered by pressing the 'P' keyboard key (for Play/Pause) or the 'S' key (for Stop). We use the kbhit() method of the GPanel graphics library to detect a key press and the getKey() method to determine which key it was. This is the standard procedure if you do not want to halt the program while waiting for a key press.

In order to avoid flickering due to the fact that the screen is rendered when clear() is called, we disable the automatic rendering by calling enableRepaint(False) and invoke repaint() manually.