[Moved from my other blog page]
Today's post is on how to use the dir() function to see what classes and methods are in a Java package.
The dir() function is a very powerful
tool you can use to find out information about a Java package. I will
demonstrate some useful hints to help you.
When working with Java, you had to use
the Reflection class to find out what classes and methods were
available. In Jython, it is a lot easier.
For my system, my Java packages are stored in the /usr/share/java/ folder. I use Ubuntu 16.04. So I picked the following package to work with: /usr/share/java/bcprov.jar. Any jar file will work if you don't have this particular package.
First, I took a quick peek at the jar file list, by typing (in a terminal): jar -tf /usr/share/java/bcprov.jar. jar is the app that willunpack a jar file. The -tf switch retrieves a list of files in the named package. So, my output was:
org/
org/bouncycastle/
org/bouncycastle/LICENSE.class
org/bouncycastle/apache/
org/bouncycastle/apache/bzip2/
org/bouncycastle/apache/bzip2/BZip2Constants.class
org/bouncycastle/apache/bzip2/CBZip2InputStream.class
org/bouncycastle/apache/bzip2/CBZip2OutputStream$1.class
org/bouncycastle/apache/bzip2/CBZip2OutputStream$StackElem.class
org/bouncycastle/apache/bzip2/CBZip2OutputStream.class
org/bouncycastle/apache/bzip2/CRC.class
org/bouncycastle/asn1/
org/bouncycastle/asn1/A
--------The rest omitted for space----------
As you see, this jar file contains a lot
of classes and methods. It would take forever to go through and find
what you want. The dir() built-in really comes in handy, as we'll see
later.
Now that I know the top two levels of
the package list, I can now open up my Jython interactive environment
(for immediate results).
You must specify the filename along with the path, or it will not import. So, I entered this:
>>> import sys
>>> sys.path.append('/usr/share/java/bcprov.jar')
I'm ready to start importing the jar package. I start off with import org.bouncycastle. Then I type dir(org.bouncycastle), and I get:
>>> import org.bouncycastle
>>> dir(org.bouncycastle)
['LICENSE',
'__name__', 'asn1', 'cert', 'cmc', 'cms', 'crypto', 'dvcs', 'eac',
'est', 'i18n', 'iana', 'jcajce', 'jce', 'math', 'mozilla', 'openssl',
'operator', 'pkcs', 'pkix', 'pqc', 'tsp', 'util', 'voms', 'x509']
You probably noticed that this list displayed above did not show the apache (we saw this in the partial file list shown earlier. That's okay. You can import specifically by typing import org.bouncycastle.apache. But let's do the math package. So, we would type import org.bouncycastle.math as math.
The AS keyword allows you to
assign an alias to the item you just importedSp., . So, instead of tying
'org.bouncycastle (and so on), now you can do type dir(math) and see a list.
>>> import org.bouncycastle.math as math
>>> dir(math)
['Primes', '__name__', 'ec', 'field', 'raw']
You see four things under the .math
sib[aclage. The names in lower case are other subpackages. You still
need to type the qualified package tree to import. One way you can type
it is: 'from org.bouncycastle.math import ec as ec' (without the quotes). What this really does is that it imports only ec whithout importing everything else. This will save on memory.
You notice Primes is capitalized.
This is a class. Methods start with a lower case with the next word
capitalized. You can import Primes the way we've been doing it, or you
can assign it to a name, like this:
>>> primes = math.Primes
What would have happened if I called it with a parentheses, as if I'm instantiating a class?
>>> primes = math.Primes()
Traceback (most recent call last):
File "", line 1, in
TypeError: can't instantiate abstract class (org.bouncycastle.math.Primes)
You
would get either the above message, or one that says no constructor is
set for that class. If you attempt to call a class with a () pair and
you get this error, just try again without the () pair. Then what can
you do?
>>> primes = math.Primes
>>> dir(primes)
['MROutput',
'SMALL_FACTOR_LIMIT', 'STOutput', '__class__', '__copy__',
'__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__',
'__eq__', '__format__', '__getattribute__', '__hash__', '__init__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__str__', '__subclasshook__', '__unicode__', 'class',
'enhancedMRProbablePrimeTest', 'equals', 'generateSTRandomPrime',
'getClass', 'hasAnySmallFactors', 'hashCode', 'isMRProbablePrime',
'isMRProbablePrimeToBase', 'notify', 'notifyAll', 'toString', 'wait']
You
see all the attributes that are available to Primes. Now, you're
getting somewhere! Of course, you may know that the attributes in ALL
CAPS are constants.
>>> primes.SMALL_FACTOR_LIMIT
211
Methods,
which require parentheses and sometimes 1 or more arguments. That can
be researched later, when you review the Java documentation.
But,
what if you do a dir() command and it returns a lot of information.
What then? This is where list comprehension and indexing really come in
handy.
Here I imported the math.ec sub-package:
>>> from org.bouncycastle.math import ec as ec
>>> dir(ec)
['AbstractECMultiplier',
'DoubleAddMultiplier', 'ECAlgorithms', 'ECConstants', 'ECCurve',
'ECFieldElement', 'ECMultiplier', 'ECPoint', 'ECPointMap',
'FixedPointCombMultiplier', 'FixedPointPreCompInfo', 'FixedPointUtil',
'GLVMultiplier', 'MixedNafR2LMultiplier', 'MontgomeryLadderMultiplier',
'NafL2RMultiplier', 'NafR2LMultiplier', 'PreCompInfo',
'ReferenceMultiplier', 'ScaleXPointMap', 'ScaleYPointMap',
'WNafL2RMultiplier', 'WNafPreCompInfo', 'WNafUtil', 'WTauNafMultiplier',
'WTauNafPreCompInfo', 'ZSignedDigitL2RMultiplier',
'ZSignedDigitR2LMultiplier', '__name__', 'custom', 'endo', 'tools']
I can type len(dir(ec) to see how many elements are in the list.
Say I only want to see items starting with 'M'. Here's list comprehension at work:
>>> [x for x in dir(ec) if x.startswith('M')]
['MixedNafR2LMultiplier', 'MontgomeryLadderMultiplier']
You can also index the dir(ec) list:
>>> dir(ec)[4]
'ECCurve'
What if you only want to see the first 10 items from the dir(ec) list? Slicing does the trick:
>>> dir (ec)[0:10]
['AbstractECMultiplier',
'DoubleAddMultiplier', 'ECAlgorithms', 'ECConstants', 'ECCurve',
'ECFieldElement', 'ECMultiplier', 'ECPoint', 'ECPointMap',
'FixedPointCombMultiplier']
So, now you know how the dir() function can help you in finding a class or wmethod within a jar package.
As I continue my journey of learning
Jython/Python, I will be sharing what I've learned along the way. I
really enjoy this language and its simplicity and powerful abilities. I
hope you will too.
Until later, happy coding!
Journey Thru Python and Jython
This is not an official Python page. It is simply a series of posts demonstrating code and other things to help other newbies to the Python language. Because I've worked with Java before, I'm drawn to the Java implementation of Python, Jython, so my posts will be more about that. But any non-Java related code should work in Python, especially if I discuss built-ins. Hope what I say is helpful. If there are mistakes, or I'm not clear on something, please let me know. Happy coding!
Tuesday, August 21, 2018
Jython: Comprehending list comprehanesions
[Moved from my other blog page]
This time, I'd like to discuss list comprehension. This is another tool used in Python and Jython. It's a very concise way of stepping through a list or a string, and processing information. You can build list comprehensions from the very basic to a complicated expression.
In an earlier post, I demonstrated a list comprehension at work with the dir() function, in returning information.
Here is a basic list comprehendion and they are enclosed in square brackets:
[expression for variable in sequence [if test-expression]]
test-expression is optional.
Let's see it in action:
>>>[x for x in ['one', 'two', 'three']]
['one', 'two', 'three']
To make it clear in my mind, I think of the first expression as the result I want, and build a list comprehension from that. Like so:
>>> [x.upper() for x in ['one', 'two', 'three']]
['ONE', 'TWO', 'THREE']
How about this?
>>> [x.startswith('t') for x in ['one', 'two', 'thre']]
[False, True, True]
It even does boolean expressions.
>>> a = 'ABC'
>>> word = ['Apple', 'Bird', 'Cat']
>>> [(x, y) for x in a for y in word if y.startswith(x)]
[('A', 'Apple'), ('B', 'Bird'), ('C', 'Cat')]
The above is an example of a nested list comprehension with an if test-expression. You noticed the result was list of tuples. You can put the result into a variable and print only what you need.
>>> result = [(x, y) for x in a for y in word if y.startswith(x)]
>>> result[0][1] <<< here I indexed the tuple
'Apple'
>>> result
[('A', 'Apple'), ('B', 'Bird'), ('C', 'Cat')]
Or this:
>>> [x for (x, y) in result]
['A', 'B', 'C']
List comprehension can process files.
>>> [x for x in open('/home/patrick/script2.py')]
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n', '\n']
If you are using list comprehension in a script, and you want to show the results on the screen, just put the print before the list comprehension.
>>>print [x for x in open('/home/patrick/script2.py')]
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n', '\n']
Can you make a complex list comprehension? You can, with some work.
I was working on the Java class GregorianCalendar. I wanted to see if my system could disply other languages. So, I used the getAvailableLocales() method. However, this method returned a list of objects, not strings. I wanted to search for a particular county, by searching a partial string, but coudln't as U got an error saying x was not in the list.
As a workaround, I had to convert it to a string to search and have it return the index of the list element.. So, my original loop went like this:
for x in range(len(locale)):
t = str(locale[x])
if t.endswith('US'):
subloc.append(locale[x])
After 3 hours or so, I was able to build a list comprehension that worked exactly as my loop:
subloc = [locale[x[0]] for x in enumerate(map(str, locale)) if x[1].endswith('US')]
Can you see how I did it? I will discuss enumerate() another day.
Is this really the Pythonic way? Maybe not, but list comprehension, when successful does marvel at the conciseness and simplicity of this powerful language.
List comprehensions allow Python/Jython do the work for you. This minimizes development time and is a great benefit of this language.
If you would like to see the full script, email me at psykiatris@gmail.com.
Till next time. Happy coding!
This time, I'd like to discuss list comprehension. This is another tool used in Python and Jython. It's a very concise way of stepping through a list or a string, and processing information. You can build list comprehensions from the very basic to a complicated expression.
In an earlier post, I demonstrated a list comprehension at work with the dir() function, in returning information.
Here is a basic list comprehendion and they are enclosed in square brackets:
[expression for variable in sequence [if test-expression]]
test-expression is optional.
Let's see it in action:
>>>[x for x in ['one', 'two', 'three']]
['one', 'two', 'three']
To make it clear in my mind, I think of the first expression as the result I want, and build a list comprehension from that. Like so:
>>> [x.upper() for x in ['one', 'two', 'three']]
['ONE', 'TWO', 'THREE']
How about this?
>>> [x.startswith('t') for x in ['one', 'two', 'thre']]
[False, True, True]
It even does boolean expressions.
>>> a = 'ABC'
>>> word = ['Apple', 'Bird', 'Cat']
>>> [(x, y) for x in a for y in word if y.startswith(x)]
[('A', 'Apple'), ('B', 'Bird'), ('C', 'Cat')]
The above is an example of a nested list comprehension with an if test-expression. You noticed the result was list of tuples. You can put the result into a variable and print only what you need.
>>> result = [(x, y) for x in a for y in word if y.startswith(x)]
>>> result[0][1] <<< here I indexed the tuple
'Apple'
>>> result
[('A', 'Apple'), ('B', 'Bird'), ('C', 'Cat')]
Or this:
>>> [x for (x, y) in result]
['A', 'B', 'C']
List comprehension can process files.
>>> [x for x in open('/home/patrick/script2.py')]
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n', '\n']
If you are using list comprehension in a script, and you want to show the results on the screen, just put the print before the list comprehension.
>>>print [x for x in open('/home/patrick/script2.py')]
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n', '\n']
Can you make a complex list comprehension? You can, with some work.
I was working on the Java class GregorianCalendar. I wanted to see if my system could disply other languages. So, I used the getAvailableLocales() method. However, this method returned a list of objects, not strings. I wanted to search for a particular county, by searching a partial string, but coudln't as U got an error saying x was not in the list.
As a workaround, I had to convert it to a string to search and have it return the index of the list element.. So, my original loop went like this:
for x in range(len(locale)):
t = str(locale[x])
if t.endswith('US'):
subloc.append(locale[x])
After 3 hours or so, I was able to build a list comprehension that worked exactly as my loop:
subloc = [locale[x[0]] for x in enumerate(map(str, locale)) if x[1].endswith('US')]
Can you see how I did it? I will discuss enumerate() another day.
Is this really the Pythonic way? Maybe not, but list comprehension, when successful does marvel at the conciseness and simplicity of this powerful language.
List comprehensions allow Python/Jython do the work for you. This minimizes development time and is a great benefit of this language.
If you would like to see the full script, email me at psykiatris@gmail.com.
Till next time. Happy coding!
Dictionaries and list comprehension in Jython/Python
[Moved from my other blog page]
I know I'm getting carried away with this list comprehension topic, but I'm finding it a lot of fun to see what else I can do with list comprehension. It also matches my other favorite topic (for another day) of slicking and indexing. You will see some of it here. What I'm doing here is exploring more ways of doing list comprehension. I''m sure most of you know how to work with dictionaries.
Create a dictionary:
>>> D = {'a': 'aardvark', 'b': 'bear', 'c': 'cat', 'd': 'dog', 'e': 'elephant', 'f': 'fox', 'g': 'giraffe', 'h': 'hippo', 'i': 'insect'}
List comprehensions on a dictionary are a little more complicated than a list, but it's fairly easy.
>>> [x for x in D]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>> [x for x in D.values()]
['aardvark', 'bear', 'cat', 'dog', 'elephant', 'fox', 'giraffe', 'hippo', 'insect']
Edited later:
>>> [x for x in D.items()]
[('a', 'apple'), ('b', 'balloon'), ('c', 'cat'), ('d', 'dog'), ('e', 'elephant'), ('f', ['fox'])]
>>> [x for x in D.items() if x[1] == 'elephant']
[('e', 'elephant')] # In this case, it sliced by element. Use x[0] to scan the keys.
You can use either .items() or .iteritems() to get key, value pairs,
Back to original post:
Say I want to get the last letter of each item in my dictionary values:
>>> [x[-1:] for x in D.values()]
['k', 'r', 't', 'g', 't', 'x', 'e', 'o', 't']
How about filtering:
# Get the elements where the last letter matches 't'.
>>> [x for x in D.values() if x[-1:] == 't']
['cat', 'elephant', 'insect']
As you see, slicing comes in handy with coding list comprehensions.
An earlier post, I eexplored how the dir() function can really be useful. Here's a little expansion on that topic:
>>> import os
>>> dir(os)
>>> len(dir(os))
110
I realized you really don't need a .startswith() or .endswith() call in a list comprehension to find matching elements. Just slice away!
Filter by first letter:
>>> [x for x in dir(os) if x[0] == 'e']
['environ', 'errno', 'error', 'extsep']
Outside of a list comprehensiuon, you would have to do this to get the first letter of an element.
>>> dir(os)[41]
'environ'
>>> dir(os)[41][0]
'e'
In the list comprehension, I didn't have to. Why? Because x already indexes the list, so I'm slicing each element to return any string beginning with 'e'.
If you need to know the index numbers to process later, you could:
>>> [dir(os).index(x) for x in dir(os) if x[0] == 'e']
[41, 42, 43, 44]
>>> [(dir(os).index(x),x) for x in dir(os) if x[0] == 'e']
[(41, 'environ'), (42, 'errno'), (43, 'error'), (44, 'extsep')]
As I've mentioned before, thinking a list comprehension through is simply a matter of putting the result you want first, then building the list comprehension to reach your result, as you can see in the example above. Now you have index intergers for all the elements beginning with 'e' from the list.
It's not necessary to use the keyword print inside the interactive session, but if you put a list comprehension in a script and need to show your result, put print before the list comprehension (e.g. print [x for ...])
I know there are programmers out there who are smareter and more experienced than me. As you see, I'm a quick learner and I relish the opportunity to continue learning.
I'm not shoinw off at all. Instead, I view this as a way to prod you and your ideas, so you can achieve your own success and sense of satisfaction at having done it. I am limited in my hearing and eyesight, but it doesn't stop me from doing what I can and stay busy in what I really enjoy.
Until later, happy coding!
I know I'm getting carried away with this list comprehension topic, but I'm finding it a lot of fun to see what else I can do with list comprehension. It also matches my other favorite topic (for another day) of slicking and indexing. You will see some of it here. What I'm doing here is exploring more ways of doing list comprehension. I''m sure most of you know how to work with dictionaries.
Create a dictionary:
>>> D = {'a': 'aardvark', 'b': 'bear', 'c': 'cat', 'd': 'dog', 'e': 'elephant', 'f': 'fox', 'g': 'giraffe', 'h': 'hippo', 'i': 'insect'}
List comprehensions on a dictionary are a little more complicated than a list, but it's fairly easy.
>>> [x for x in D]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>> [x for x in D.values()]
['aardvark', 'bear', 'cat', 'dog', 'elephant', 'fox', 'giraffe', 'hippo', 'insect']
Edited later:
>>> [x for x in D.items()]
[('a', 'apple'), ('b', 'balloon'), ('c', 'cat'), ('d', 'dog'), ('e', 'elephant'), ('f', ['fox'])]
>>> [x for x in D.items() if x[1] == 'elephant']
[('e', 'elephant')] # In this case, it sliced by element. Use x[0] to scan the keys.
You can use either .items() or .iteritems() to get key, value pairs,
Back to original post:
Say I want to get the last letter of each item in my dictionary values:
>>> [x[-1:] for x in D.values()]
['k', 'r', 't', 'g', 't', 'x', 'e', 'o', 't']
How about filtering:
# Get the elements where the last letter matches 't'.
>>> [x for x in D.values() if x[-1:] == 't']
['cat', 'elephant', 'insect']
As you see, slicing comes in handy with coding list comprehensions.
An earlier post, I eexplored how the dir() function can really be useful. Here's a little expansion on that topic:
>>> import os
>>> dir(os)
>>> len(dir(os))
110
I realized you really don't need a .startswith() or .endswith() call in a list comprehension to find matching elements. Just slice away!
Filter by first letter:
>>> [x for x in dir(os) if x[0] == 'e']
['environ', 'errno', 'error', 'extsep']
Outside of a list comprehensiuon, you would have to do this to get the first letter of an element.
>>> dir(os)[41]
'environ'
>>> dir(os)[41][0]
'e'
In the list comprehension, I didn't have to. Why? Because x already indexes the list, so I'm slicing each element to return any string beginning with 'e'.
If you need to know the index numbers to process later, you could:
>>> [dir(os).index(x) for x in dir(os) if x[0] == 'e']
[41, 42, 43, 44]
>>> [(dir(os).index(x),x) for x in dir(os) if x[0] == 'e']
[(41, 'environ'), (42, 'errno'), (43, 'error'), (44, 'extsep')]
As I've mentioned before, thinking a list comprehension through is simply a matter of putting the result you want first, then building the list comprehension to reach your result, as you can see in the example above. Now you have index intergers for all the elements beginning with 'e' from the list.
It's not necessary to use the keyword print inside the interactive session, but if you put a list comprehension in a script and need to show your result, put print before the list comprehension (e.g. print [x for ...])
I know there are programmers out there who are smareter and more experienced than me. As you see, I'm a quick learner and I relish the opportunity to continue learning.
I'm not shoinw off at all. Instead, I view this as a way to prod you and your ideas, so you can achieve your own success and sense of satisfaction at having done it. I am limited in my hearing and eyesight, but it doesn't stop me from doing what I can and stay busy in what I really enjoy.
Until later, happy coding!
Empty spaces
Good morning,
This is for the newbies:
When you're developing code and you need to test if a String object is truly empty, be careful. Here's an example:
class IsStringTrulyEmpty {
public static void main(String[] args) {
//Is string truly empty?
String s = " ";
String t = "";
//Test
System.out.println("Is s truly empty? " + s.isEmpty());
System.out.println("Is t truly empty? " + t.isEmpty());
}
}
Here is the output when run:
Is s truly empty? false
Is t truly empty? t rue
Notice that s returned false. Why? There is a space between the quotation marks. This may have an impact, because if you're checking if a string is empty, it will never be true if there's a space.
It truly is all in the details.
Happy coding!
This is for the newbies:
When you're developing code and you need to test if a String object is truly empty, be careful. Here's an example:
class IsStringTrulyEmpty {
public static void main(String[] args) {
//Is string truly empty?
String s = " ";
String t = "";
//Test
System.out.println("Is s truly empty? " + s.isEmpty());
System.out.println("Is t truly empty? " + t.isEmpty());
}
}
Here is the output when run:
Is s truly empty? false
Is t truly empty? t rue
Notice that s returned false. Why? There is a space between the quotation marks. This may have an impact, because if you're checking if a string is empty, it will never be true if there's a space.
It truly is all in the details.
Happy coding!
Friday, August 10, 2018
Jython and working with java's generic types.
Hello all!
Let's talk today about Java's Generics. I will demonstrate how you can work with these. As you work with other programmers' libraries, you may come across a library that is built around Java's generic types.
Using Jython to work with these types takes a little work. Trying to access them directly does not work. Why? It's the basic structure of Jytjpm tjat the system is dynamically typed, while Java is quite strict in that area. For example, if you, in the Jython interpreter, type:
i = 100
Then the type is 'int'. If you use the same variable name:
i = 100.5
The type is now a 'float' (or Double per Java). You do not need to declare the type you are using, as Java demands you do.
So, how to utilize Java's Generics? Simply by explicily casting your type prior to passing it to Java.
Allow me to demonstrate. I have created a simple class that actually takes TWO types. Both types can be the same, but they can be different also.
=======TwoTypes.java====================
public class TwoTypes<T, V> {
T ob1;
V ob2;
// Constructor
public TwoTypes(T o1, V o2) {
ob1 = o1;
ob2 = o2;
}
//Methods
public void showTypes() {
System.out.println("Value of type T is: " + ob1.getClass().getName());
System.out.println("Value of type V is: " + ob2.getClass().getName());
}
public T getob1() { return ob1; }
public V getob2() { return ob2; }
}
============end of java file ===============
The showTypes method will return the types as Java sees them. The getob1 and getob2 methods are used to return the data contained in the object that was created. If you think about it, one variable name can be used to contain two diffenent types!
After compiling the .java into a .class file, go to the directory where the .class file is stored and start your Jython interpreter. The following is from my own terminal, showing the demonstration of using the TwoTypes class.
==================
>>> import TwoTypes
>>> iOb = int(100)
>>> fOb = float(100.2)
>>> ttOb = TwoTypes(iOb, fOb)
>>> ttOb.showTypes()
Value of type T is: java.lang.Integer
Value of type V is: java.lang.Double
>>> # To see what's contained in the object.
>>> ttOb.getob1()
100
>>> ttOb.getob2()
100.2
>>> # You can even do operations with the objects!
>>>
>>>
>>> print "Adding the objects:", (ttOb.getob1() + ttOb.getob2())
Adding the objects: 200.2
===============
Very cool, indeed.
But really, the whole point of Java's Generic types is to ensure type safety, which Jython doesn't care about due to its dynamic nature. You can assign one TwoTypes object to another and Jython will do it happily. But, you will get strange and unexpected bahavior (and exceptions) when attempting to pass an incompatible object to java. This demonstrates what you can do to appease Java's requirements and get Jython and Java working smoothly.
As always, if you have questions or comments, don't be shy.
Happy coding!
Let's talk today about Java's Generics. I will demonstrate how you can work with these. As you work with other programmers' libraries, you may come across a library that is built around Java's generic types.
Using Jython to work with these types takes a little work. Trying to access them directly does not work. Why? It's the basic structure of Jytjpm tjat the system is dynamically typed, while Java is quite strict in that area. For example, if you, in the Jython interpreter, type:
i = 100
Then the type is 'int'. If you use the same variable name:
i = 100.5
The type is now a 'float' (or Double per Java). You do not need to declare the type you are using, as Java demands you do.
So, how to utilize Java's Generics? Simply by explicily casting your type prior to passing it to Java.
Allow me to demonstrate. I have created a simple class that actually takes TWO types. Both types can be the same, but they can be different also.
=======TwoTypes.java====================
public class TwoTypes<T, V> {
T ob1;
V ob2;
// Constructor
public TwoTypes(T o1, V o2) {
ob1 = o1;
ob2 = o2;
}
//Methods
public void showTypes() {
System.out.println("Value of type T is: " + ob1.getClass().getName());
System.out.println("Value of type V is: " + ob2.getClass().getName());
}
public T getob1() { return ob1; }
public V getob2() { return ob2; }
}
============end of java file ===============
The showTypes method will return the types as Java sees them. The getob1 and getob2 methods are used to return the data contained in the object that was created. If you think about it, one variable name can be used to contain two diffenent types!
After compiling the .java into a .class file, go to the directory where the .class file is stored and start your Jython interpreter. The following is from my own terminal, showing the demonstration of using the TwoTypes class.
==================
>>> import TwoTypes
>>> iOb = int(100)
>>> fOb = float(100.2)
>>> ttOb = TwoTypes(iOb, fOb)
>>> ttOb.showTypes()
Value of type T is: java.lang.Integer
Value of type V is: java.lang.Double
>>> # To see what's contained in the object.
>>> ttOb.getob1()
100
>>> ttOb.getob2()
100.2
>>> # You can even do operations with the objects!
>>>
>>>
>>> print "Adding the objects:", (ttOb.getob1() + ttOb.getob2())
Adding the objects: 200.2
===============
Very cool, indeed.
But really, the whole point of Java's Generic types is to ensure type safety, which Jython doesn't care about due to its dynamic nature. You can assign one TwoTypes object to another and Jython will do it happily. But, you will get strange and unexpected bahavior (and exceptions) when attempting to pass an incompatible object to java. This demonstrates what you can do to appease Java's requirements and get Jython and Java working smoothly.
As always, if you have questions or comments, don't be shy.
Happy coding!
Monday, August 6, 2018
Jython and the Java main()
hello all,
A quick post for today:
Have you exprienced frustration at attempting to run a Java main() method from Jython?
The reason is simple: Jython follows mos of the rules of Java, but not all. When you call Java's main() method using Java, you don't need to pass in anything.
However, when doing this from Jython, it complains. Even if you have arguments to pass it complains. Why? Because Java expects a String[] array. Java things you're passing an empty string, which from Java is fine, If you have arguments, you need to put the arguments into a list, and pass the list and Java will accept it.
Here is a simple Java code demonstrating printing from the console via Java. The example if from the book Java: The Complete Reference, 10th Edition, by Herbert Schildt:
=====================BRRead.java=========
import java.io.*;
public class BRRead {
public static void main(String[] args) {
char c;
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter characters. 'q' to quit.");
try {
do {
c = (char) br.read();
System.out.print(c);
} while (c != 'q');
} catch (IOException e) {
System.out.println("Exception");
}
}
}
==========End of file==========
Go to the directory where the .class file is saved, and fire up your Jython
interpreter.
Type the follwoing:
br = BRRead()
This will create an object that references the class. Now, create an array:
foo = []
It's acceptable to pass an empty list. It makes Java happy. If your main() requires arguments, then create the list as above, with your arguments as strings. To ensure you can see main from Jython, do dir(br).
If you do, you're ready to run the main() method.
br.main(foo)
You will see the two lines, with the press 'q' to stop. Type away. When you're done, type q by itself to go back to the interpreter prompt.
It may appear to be a flaw in Jython, but you have this work around to see if your code works as it should from Jython.
If you have any questions, please ask.
Happy coding!
A quick post for today:
Have you exprienced frustration at attempting to run a Java main() method from Jython?
The reason is simple: Jython follows mos of the rules of Java, but not all. When you call Java's main() method using Java, you don't need to pass in anything.
However, when doing this from Jython, it complains. Even if you have arguments to pass it complains. Why? Because Java expects a String[] array. Java things you're passing an empty string, which from Java is fine, If you have arguments, you need to put the arguments into a list, and pass the list and Java will accept it.
Here is a simple Java code demonstrating printing from the console via Java. The example if from the book Java: The Complete Reference, 10th Edition, by Herbert Schildt:
=====================BRRead.java=========
import java.io.*;
public class BRRead {
public static void main(String[] args) {
char c;
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter characters. 'q' to quit.");
try {
do {
c = (char) br.read();
System.out.print(c);
} while (c != 'q');
} catch (IOException e) {
System.out.println("Exception");
}
}
}
==========End of file==========
Go to the directory where the .class file is saved, and fire up your Jython
interpreter.
Type the follwoing:
br = BRRead()
This will create an object that references the class. Now, create an array:
foo = []
It's acceptable to pass an empty list. It makes Java happy. If your main() requires arguments, then create the list as above, with your arguments as strings. To ensure you can see main from Jython, do dir(br).
If you do, you're ready to run the main() method.
br.main(foo)
You will see the two lines, with the press 'q' to stop. Type away. When you're done, type q by itself to go back to the interpreter prompt.
It may appear to be a flaw in Jython, but you have this work around to see if your code works as it should from Jython.
If you have any questions, please ask.
Happy coding!
Monday, July 30, 2018
It's All in the Packaging.
Hello all.
Recently, I posted that if you want to build a Jython project with JDK code, it is very simple to do. However, if you want to DEVELOP your OWN Java classes, it takes a little more work. If you use an IDE to develop your code, understanding how your IDE packages your .class files is a must. Because Jython DEPENDS on knowing where your .class files are.
Understanding Java package rules will help in this are. I have found that the easiest way is to develop your Java project FIRST, then create a separate Jython project. You need to point to the directory where your .class files live. As an alternative, you could take your Java code, package it in a .JAR file, includ it in your JYTHONPATH environment variable and you're good to go.
Creating a .JAR file is simple. A short tutorial follows:
I use IntelliJ IDEA for my coding in both Java and Jython. In my project settings, under project, I defined a global /out folder for my compiled .class files. Doing this makes it easy to create .jar files depending on your project, as I will demonstrate soon. So, currently, my folder structure is
/home/patrick/out
When IntelliJ compiles the .class files, it adds a series of sub-folders, so that it looks like this\
/home/patrick/out/production/<projectname>
Under the project name is the hierarch you created with your Java project For me, it is
org.ppalczewski.<project>.<source1>.<so on>
So, in the end, my /out folder looks like this:
/home/patrick/out/production/<projectname>/org.ppalczewski.<project>/<source1>/<source2>/ etc
Wow, that's a lot of typing. But I only want to create a .jar that shows the hierarchy from org.ppaczewski dowm. I can do this two ways. First, I can navigate to my <projectname> folder (i.e. /home/patrick/out/production/<projectname>).
Then, I type this command to build my .JAR file:
jar cvf <project>.jar .
This will recurse from the <projectname> folder down and include all .class files. The switches are c(create), v(verbose), f(jar file name)
I have a root jarfiles folder that holds all of my jar files. I can navigate to this folder and type the following:
jar cvf <project>.jar -C /home/patrick/out/production/<projectname>/ .
This will do the same thing, and it retains your fully qualified package name structure (for me: org.ppalczewski.<project>.etc,etc).
It is very important to include the ending slash (or backslash in Windows). If you don't, you may get unexpected results. you can verify your package qualified name by
jar tf <jarfile>.jar
and this will list the .class files you have in your project.
So, after I have built my .jar file, and included this in my JYTHONPATH (you MUST include the actual name of your .jar file also), I can now fire up my Jython interpreter and test to see that it works.
In my code, I type this:
import org.ppalczewski.<project> as project
Now I have access to any classes I may have created.
To me, this makes it easier than having worry about whether Jython can see the .class files or not. 1. Build Java code. 2. Package in .jar file. 3. Import into Jython 4. Enjoy!
Then, for distribution, have the .jar file available and that's it.
Say you alread have a .jar file and you updated the code in your project? Do you need to delete the jar file and create a new one? No. Use the jar command's updatte feature, which will recreate the .jar file for you, adding any new files or updated code.
jar uvf <jarfile>.jar [-C <path>/<to>/<production>/] .
If I am able, I will create a blog with a simple project demonstrating this.
That's it for today. Happy coding!
Recently, I posted that if you want to build a Jython project with JDK code, it is very simple to do. However, if you want to DEVELOP your OWN Java classes, it takes a little more work. If you use an IDE to develop your code, understanding how your IDE packages your .class files is a must. Because Jython DEPENDS on knowing where your .class files are.
Understanding Java package rules will help in this are. I have found that the easiest way is to develop your Java project FIRST, then create a separate Jython project. You need to point to the directory where your .class files live. As an alternative, you could take your Java code, package it in a .JAR file, includ it in your JYTHONPATH environment variable and you're good to go.
Creating a .JAR file is simple. A short tutorial follows:
I use IntelliJ IDEA for my coding in both Java and Jython. In my project settings, under project, I defined a global /out folder for my compiled .class files. Doing this makes it easy to create .jar files depending on your project, as I will demonstrate soon. So, currently, my folder structure is
/home/patrick/out
When IntelliJ compiles the .class files, it adds a series of sub-folders, so that it looks like this\
/home/patrick/out/production/<projectname>
Under the project name is the hierarch you created with your Java project For me, it is
org.ppalczewski.<project>.<source1>.<so on>
So, in the end, my /out folder looks like this:
/home/patrick/out/production/<projectname>/org.ppalczewski.<project>/<source1>/<source2>/ etc
Wow, that's a lot of typing. But I only want to create a .jar that shows the hierarchy from org.ppaczewski dowm. I can do this two ways. First, I can navigate to my <projectname> folder (i.e. /home/patrick/out/production/<projectname>).
Then, I type this command to build my .JAR file:
jar cvf <project>.jar .
This will recurse from the <projectname> folder down and include all .class files. The switches are c(create), v(verbose), f(jar file name)
I have a root jarfiles folder that holds all of my jar files. I can navigate to this folder and type the following:
jar cvf <project>.jar -C /home/patrick/out/production/<projectname>/ .
This will do the same thing, and it retains your fully qualified package name structure (for me: org.ppalczewski.<project>.etc,etc).
It is very important to include the ending slash (or backslash in Windows). If you don't, you may get unexpected results. you can verify your package qualified name by
jar tf <jarfile>.jar
and this will list the .class files you have in your project.
So, after I have built my .jar file, and included this in my JYTHONPATH (you MUST include the actual name of your .jar file also), I can now fire up my Jython interpreter and test to see that it works.
In my code, I type this:
import org.ppalczewski.<project> as project
Now I have access to any classes I may have created.
To me, this makes it easier than having worry about whether Jython can see the .class files or not. 1. Build Java code. 2. Package in .jar file. 3. Import into Jython 4. Enjoy!
Then, for distribution, have the .jar file available and that's it.
Say you alread have a .jar file and you updated the code in your project? Do you need to delete the jar file and create a new one? No. Use the jar command's updatte feature, which will recreate the .jar file for you, adding any new files or updated code.
jar uvf <jarfile>.jar [-C <path>/<to>/<production>/] .
If I am able, I will create a blog with a simple project demonstrating this.
That's it for today. Happy coding!
Subscribe to:
Posts (Atom)