| ePolyglot: Examination and development of multilanguage programming using Eiffel, Python, and Haskell | ||
|---|---|---|
| Prev | Chapter 7. Shadow Classes | Next |
So how well do our new Python primitive classes hold up, and how easily can they be used? The following sample program uses the new hierarchy for a simple demonstration of many of the PYTHON_OBJECT classes:
Example 7-1. The "primitives_test.e" sample program
class PRIMITIVES_TEST
inherit
PYTHON_CLIENT
creation
make
feature
do_string_demo is
--demonstrate use of python string primitives
local
s : PYTHON_STRING
do
std_output.put_string( "Python strings can be created from %
%Eiffel strings, and vice versa.%N" )
std_output.put_string( "Creating Python string 'Hello, World!'%N" )
create s.from_string( "Hello, World!" )
std_output.put_string( "Created string: " + s.to_string + "%N%N")
end
do_number_demo is
--demonstrate use of python number primitives
local
a, b, c : PYTHON_INTEGER
af, bf : PYTHON_FLOAT
do
std_output.put_string( "Python numbers can be created from %
%Eiffel numbers, and%Ncan be %
%manipulated in the same ways:%N" )
create a.from_integer( 5 )
create b.from_integer( 6 )
create c.from_integer( 10 )
std_output.put_string( "5+6+10 = " )
std_output.put_integer( (a + b + c).to_integer )
std_output.put_new_line
std_output.put_string( "10 / 5 = " )
std_output.put_integer( ( c / a ).to_integer )
std_output.put_new_line
std_output.put_string( "10 / 6 = " )
std_output.put_integer( ( c / b ).to_integer )
std_output.put_new_line
std_output.put_string( "Remainder of 10 / 6 : " )
std_output.put_integer( (c \\ b).to_integer )
std_output.put_new_line
--similar acts with floating point
create af.from_double( 2.5 )
create bf.from_double( 6.353 )
std_output.put_string( "2.5 + 6.353 = " )
std_output.put_double( ( af + bf ).to_double )
std_output.put_new_line
std_output.put_string( "6.353 / 2.5 = " )
std_output.put_double( ( bf / af ).to_double )
std_output.put_new_line
std_output.put_new_line
end
do_list_demo is
--demonstrate use of Python lists
local
a : PYTHON_LIST
do
create a.make
std_output.put_string( "Python lists can be created easily, %
%and support many of the same%
%%Nfeatures as Eiffel arrays...but not all.%N" )
std_output.put_string( "Creating a list of strings 'Hello', 'Eiffel'%
% 'world!'%N" )
a.append( python_object_factory.new_python_string( "Hello" ) )
a.append( python_object_factory.new_python_string( "Eiffel" ) )
a.append( python_object_factory.new_python_string( "World!" ) )
std_output.put_string( "Python representation: " + a.to_string + "%N" )
std_output.put_string( "Replacing element 1:%N" )
a.put( python_object_factory.new_python_string( "Python" ), 1 )
std_output.put_string( "Python representation: " + a.to_string + "%N" )
std_output.put_string( "Inserting 'or Eiffel' after 'Python':%N" )
a.insert( python_object_factory.new_python_string( "or" ), 2 )
a.insert( python_object_factory.new_python_string( "Eiffel" ), 3 )
std_output.put_string( "Python representation: " + a.to_string + "%N" )
std_output.put_string( "Taking or setting slices is also possible.%N%N" )
end
do_dictionary_demo is
--demonstrate use of Python dictionaries
local
a : PYTHON_DICTIONARY
do
create a.make
std_output.put_string( "Python dictionaries can be used to %
%implement mappings.%N" )
std_output.put_string( "creating the simple dictionary { 'a': 'Hello',%
% 'b' : 'World!' }%N" )
a.set_item_string( "b", python_object_factory.new_python_string( "World!" ) )
a.set_item_string( "a", python_object_factory.new_python_string( "Hello" ) )
std_output.put_string( "Python representation: " + a.to_string + "%N" )
std_output.put_string( "Keys: " + a.keys.to_string + "%N" )
std_output.put_string( "Values: " + a.values.to_string + "%N" )
std_output.put_string( "Value of a: " + a.get_item_string( "a" ).to_string + "%N")
end
make is
do
py_initialize
do_string_demo
do_number_demo
do_list_demo
do_dictionary_demo
rescue
if not py_err_occurred.is_null then
py_err_print
end
end
end
|
While voluminous, it is designed to showcase many of the features of the PYTHON_OBJECT hierarchy: object creation and use, manipulation of objects from within Eiffel, and general ease of use. Unfortunately, any time you mix other languages or libraries with Eiffel, you lose some of the simplicity of the creation process, and so the details of making this simple example are a bit confusing, involving rules for SWIG and the addition of some C code to the program's compilation line. For more details of the make process, examine the files production/examples/examples_common/boilerplate.mk.in and production/examples/primitives/Makefile.in. While the Makefile is only slightly complex, the above source file was the only actual code written to take advantage of the embedded Python interpreter. When run, it produces the following output:
Example 7-2. Output from the "primitives_test.e" sample program
Python strings can be created from Eiffel strings, and vice versa.
Creating Python string 'Hello, World!'
Created string: Hello, World!
Python numbers can be created from Eiffel numbers, and
can be manipulated in the same ways:
5+6+10 = 21
10 / 5 = 2
10 / 6 = 1
Remainder of 10 / 6 : 4
2.5 + 6.353 = 8.853000
6.353 / 2.5 = 2.541200
Python lists can be created easily, and support many of the same
features as Eiffel arrays...but not all.
Creating a list of strings 'Hello', 'Eiffel' 'world!'
Python representation: ['Hello', 'Eiffel', 'World!']
Replacing element 1:
Python representation: ['Hello', 'Python', 'World!']
Inserting 'or Eiffel' after 'Python':
Python representation: ['Hello', 'Python', 'or', 'Eiffel', 'World!']
Taking or setting slices is also possible.
Python dictionaries can be used to implement mappings.
creating the simple dictionary { 'a': 'Hello', 'b' : 'World!' }
Python representation: {'b': 'World!', 'a': 'Hello'}
Keys: ['b', 'a']
Values: ['World!', 'Hello']
Value of a: 'Hello' |