//: c09:PythonInterpreterGetting.java
// Getting data from the PythonInterpreter object.
import org.python.util.PythonInterpreter; 
import org.python.core.*; 
import java.util.*;
import com.bruceeckel.python.*;
import com.bruceeckel.test.*;

public class 
PythonInterpreterGetting extends UnitTest{ 
  PythonInterpreter interp = 
    new PythonInterpreter();
  public void test() throws PyException  { 
    interp.exec("a = 100");
    // If you just use the ordinary get(), 
    // it returns a PyObject:
    PyObject a = interp.get("a");
    // There's not much you can do with a generic
    // PyObject, but you can print it out:
    System.out.println("a = " + a);
    // If you know the type it's supposed to be,
    // you can "cast" it using __tojava__() to
    // that Java type and manipulate it in Java.
    // To use 'a' as an int, you must use
    // the Integer wrapper class:
    int ai= ((Integer)a.__tojava__(Integer.class))
      .intValue();
    // There are also convenience functions:
    ai = Py.py2int(a);
    System.out.println("ai + 47 = " + (ai + 47));
    // You can convert it to different types:
    float af = Py.py2float(a);
    System.out.println("af + 47 = " + (af + 47));
    // If you try to cast it to an inappropriate
    // type you'll get a runtime exception:
    //! String as = (String)a.__tojava__(
    //!   String.class);
    
    // If you know the type, a more useful method
    // is the overloaded get() that takes the 
    // desired class as the 2nd argument:
    interp.exec("x = 1 + 2");
    int x = ((Integer)interp
      .get("x", Integer.class)).intValue();
    System.out.println("x = " + x);
    
    // Since Python is so good at manipulating
    // strings and files, you will often need to
    // extract an array of Strings. Here, a file 
    // is read as a Python array:
    interp.exec("lines = " + 
      "open('PythonInterpreterGetting.java')" +
      ".readlines()");
    // Pull it in as a Java array of String:
    String[] lines = (String[])
      interp.get("lines", String[].class);
    for(int i = 0; i < 10; i++)
      System.out.print(lines[i]);
    
    // As an example of useful string tools,
    // global expansion of ambiguous file names
    // using glob is very useful, but it's not
    // part of the standard Jython package, so
    // you'll have to make sure that your
    // Python path is set to include these, or
    // that you deliver the necessary Python
    // files with your application.
    interp.exec("from glob import glob");
    interp.exec("files = glob('*.java')");
    String[] files = (String[])
      interp.get("files", String[].class);
    for(int i = 0; i < files.length; i++)
      System.out.println(files[i]);
    
    // You can extract tuples and arrays into 
    // Java Lists with com.bruceeckel.PyUtil:
    interp.exec(
      "tup = ('fee', 'fi', 'fo', 'fum', 'fi')");
    List tup = PyUtil.toList(interp, "tup");
    System.out.println(tup);
    // It really is a list of String objects:
    System.out.println(tup.get(0).getClass());
    // You can easily convert it to a Set:
    Set tups = new HashSet(tup);
    System.out.println(tups);
    interp.exec("ints=[1,3,5,7,9,11,13,17,19]");
    List ints = PyUtil.toList(interp, "ints");
    System.out.println(ints);
    // It really is a List of Integer objects:
    System.out.println((ints.get(1)).getClass());
    
    // If you have a Python dictionary, it can
    // be extracted into a Java Map, again with
    // com.bruceeckel.PyUtil:
    interp.exec("dict = { 1 : 'a', 3 : 'b'," +
      "5 : 'c', 9 : 'd', 11 : 'e' }");
    Map map = PyUtil.toMap(interp, "dict");
    System.out.println("map: " + map);
    // It really is Java objects, not PyObjects:
    Iterator it = map.entrySet().iterator();
    Map.Entry e = (Map.Entry)it.next();
    System.out.println(e.getKey().getClass());
    System.out.println(e.getValue().getClass());
  }
  public static void 
  main(String[] args) throws PyException  {
    new PythonInterpreterGetting().test();
  }
} ///:~
