I implemented all of the basic map, reduce, etc. from Python in Java. Now I went through the Python string tutorial, and Python list tutorial. I implemented slice, slice replacement, etc. in Java. I am learning all sorts of things about Java Generics in the process.
Python versus EasyJava:Multiline strings
print """ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to """
print (lines( " Usage: thingy [OPTIONS]", " -h Display this usage message", " -H hostname Hostname to connect to" ));Ok... that is the best I could come up with. It is not the same at all, but it might be marginally easier than having to concatenate strings.
Python versus EasyJava : Adding strings
>>> word = 'Help' + 'A' >>> print (word)
String word; word = "Help" + "A"; print (word);Ok. There was not much to do here. Java does this right already. :)
Python versus EasyJava : String slicing
print (word[4]) print (word[0:2]) print (word[2:4])Output:
'A' 'He' 'lp'
print(slice(word,4)); print(slice(word,0,2)); print(slice(word,2,4));I also implemented slice for lists, and added a few more collection methods. I implemented a replacement slice too.
All of the rest
// >>> 'x' + word[1:] // 'xelpA' // >>> 'Splat' + word[4] // 'SplatA' print(lines ( "x" + slice(word,1), "Splat" + word.charAt(4) )); // >>> word[:2] + word[2:] // 'HelpA' // >>> word[:3] + word[3:] // 'HelpA' print(lines ( slice(word,0,2) + slice(word,2), slice(word,0,3) + slice(word,3) )); // >>> word[1:100] // 'elpA' // >>> word[10:] // '' // >>> word[2:1] // '' print(lines ( "1,00 " + slice(word,1,100), "10 " + slice(word,10), "2,1 " + slice(word,2,1) )); // >>> word[-1] # The last character // 'A' // >>> word[-2] # The last-but-one character // 'p' // >>> word[-2:] # The last two characters // 'pA' // >>> word[:-2] # Everything except the last two characters // 'Hel' //slice has a alias called slc, slc=slice, index=idx print(lines ( "-1 :" + slc(word,-1), "-2 :" + idx(word, -2), "-2 :" + slc(word,-2), "0,-2 :" + slc(word,0,-2) )); // >>> word[-100:] // 'HelpA' print (slice(word,-100)); List<? extends Object> a; // a = ['spam', 'eggs', 100, 1234] // print (a) // ['spam', 'eggs', 100, 1234] a = ls("spam", "eggs", 100, 1234); print (a); //ls and list do the same thing a = list("spam", "eggs", 100, 1234); print (a); //>>> a[0] //'spam' print (idx(a,0)); //>>> a[3] //1234 print (idx(a,3)); //>>> a[-2] //100 print (idx(a,3)); //>>> a[1:-1] //['eggs', 100] print (slc(a,1,-1)); //>>> a[:2] print (slc(a,0,2)); //>>> a[:2] + ['bacon', 2*2] //['spam', 'eggs', 'bacon', 4] print ("addls", ls(slc(a,0,2), ls ("bacon", 2*2)) ); // >>> 3*a[:3] + ['Boo!'] // ['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!'] print ( ls ( mul( 3, slc( a,0,3 ) ), ls( "Boo!" ) ) ); //ls(mul(3,slc(a,0,3)),ls("Boo!")) //3*a[:3]+['Boo!'] //3*a[:3]+['Boo!']3*a[:3]+['Boo!'] //java is twice as long // a[:] // ['spam', 'eggs', 100, 1234] print (copy (a) ); // >>> a // ['spam', 'eggs', 100, 1234] // >>> a[2] = a[2] + 23 // >>> a // ['spam', 'eggs', 123, 1234] //Java is strongly typed so the above is a bit harder, better with uniform types. List<Integer> b = ls (1,2,100,1234); b.set(2, b.get(2) + 23); print (b); //Java is strongly typed so the above is a bit harder ((List<Integer>)a).set(2, ((Integer)a.get(2) + 23)); print (a); List<Integer> ia = (List<Integer>)a; List<String> sa = (List<String>)a; List<Object> oa = (List<Object>)a; //b.set(2,b.get(2)+23); //a[2]=a[2]+23 //for uniform type, python is 1/2 size //((List<Integer>)a).set(2,((Integer)a.get(2)+23)); //for non-uniform type, python is about 1/5 the size // >>> # Replace some items: // ... a[0:2] = [1, 12] // >>> a // [1, 12, 123, 1234] List<Integer> ia2 = copy(ia); replace(ia2, 0, 2, ls(1,12)); print ("ia2", ia2); rpl(ia,0,2,ls(1,12)); print ("ia", ia);Now the implementation....
package com.easyjava; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import java.util.Date; public class EasyJava { private static final Logger log = Logger.getLogger(EasyJava.class.getName()); private static final Logger appLog = Logger.getLogger(sprop(pkey(EasyJava.class,"appLog"), "genericLog")); public static final Class<String> string = String.class; public static final Class<Integer> integer = Integer.class; public static final Class<Float> flt = Float.class; public static final Class<Double> dbl = Double.class; public static final Class<Date> date = Date.class; public static final boolean debug; static { debug = sbprop(pkey(EasyJava.class, "debug")); } // HELPER // HELPER // HELPER // HELPER private static Class<?> clazz(Object that) { if (that instanceof Class) { return (Class<?>) that; } else { return that.getClass(); } } public static String mykey(Class<?> cls, final String key) { return pkey(EasyJava.class, key); } public static String pkey(Class<?> cls, String key) { return cls.getName() + "." + key; } public static String sprop(String key) { return System.getProperty(key); } public static String sprop(String key, String defaultValue) { return System.getProperty(key, defaultValue); } public static boolean sbprop(String key) { return Boolean.getBoolean(key); } public static void print (Object... items) { StringBuilder builder = new StringBuilder(256); for (Object item : items) { builder.append(item); builder.append(' '); } System.out.println(builder); } public static void printf (String fmt, Object... args) { System.out.printf(fmt, args); } public static String sprintf (String fmt, Object... args) { return String.format(fmt, args); } public static void fprintf (Logger log, String fmt, Object... args) { if (debug) { printf(fmt, args); return;} log.info(String.format(fmt, args)); } //Logging //Logging //Logging public static void info (Logger log, String fmt, Object... args) { if (debug) { printf(fmt, args); return;} log.info(String.format(fmt, args)); } public static void debug (Logger log, String fmt, Object... args) { if (debug) { printf(fmt, args); return;} log.fine(String.format(fmt, args)); } public static void trace (Logger log, String fmt, Object... args) { if (debug) { printf(fmt, args); return;} log.finest(String.format(fmt, args)); } public static void info (String fmt, Object... args) { if (debug) { printf(fmt, args); return;} appLog.info(String.format(fmt, args)); } public static void fprintf (String fmt, Object... args) { if (debug) { printf(fmt, args); return;} appLog.info(String.format(fmt, args)); } public static void debug (String fmt, Object... args) { if (debug) { printf(fmt, args); return;} appLog.fine(String.format(fmt, args)); } public static void trace (String fmt, Object... args) { if (debug) { printf(fmt, args); return;} appLog.finest(String.format(fmt, args)); } @SuppressWarnings("serial") public static class AssertionException extends RuntimeException { public AssertionException() { super(); } public AssertionException(String message, Throwable cause) { super(message, cause); } public AssertionException(String message) { super(message); } public AssertionException(Throwable cause) { super(cause); } } @SuppressWarnings("serial") public static class ReflectionException extends RuntimeException { public ReflectionException() { super(); } public ReflectionException(String message, Throwable cause) { super(message, cause); } public ReflectionException(String message) { super(message); } public ReflectionException(Throwable cause) { super(cause); } } public static void die(boolean condition, String message) { if (condition) { throw new AssertionException(message); } } public static void die(String message) { throw new AssertionException(message); } public static void die(String message, Object... args) { throw new AssertionException(String.format(message, args)); } // CREATIONAL // CREATIONAL // CREATIONAL // CREATIONAL public static interface Entry<K,V> { K key(); V value(); } private static class EntryImpl<K, V> implements Entry<K, V>{ EntryImpl(K k, V v) {this.k=k; this.v=v;} K k; V v; @Override public K key() { return k; } @Override public V value() { return v; } } public static <K, V> Entry<K, V> kv (final K k, final V v) { return new EntryImpl<K,V>(k, v); } public static <K, V> Entry <K, V> entry (final K k, final V v) { return new EntryImpl<K,V>(k,v); } public static <V> List<V> ls(final V... array) { return list(array); } public static <V> List<V> list(final V... array) { ArrayList<V> list = new ArrayList<V>(array.length); for (V o : array) { list.add(o); } return list; } public static <V> List<V> ls(final Collection<V> col) { return list(col); } public static <V> List<V> list(final Collection<V> col) { return new ArrayList<V>(col); } public static <V> List<V> ls(Collection<V> lst, final Collection<?>... others) { return list(lst, others); } @SuppressWarnings("unchecked") public static <V> List<V> list(Collection<V> lst, final Collection<?>... others) { int total=lst.size(); for (Collection<?> c : others) { total += c.size(); } ArrayList<Object> list = new ArrayList<Object>(total); list.addAll(lst); for (Collection<?> c : others) { list.addAll(c); } return (List<V>) list; } public static <V> List<V> copy(final List<V> col) { return new ArrayList<V>(col); } public static <V> Set<V> copy(final Set<V> col) { return new HashSet<V>(col); } public static <V> SortedSet<V> copy(final SortedSet<V> col) { return new TreeSet<V>(col); } public static String copy(final String str) { return new String(str); } public static StringBuilder copy(final StringBuilder str) { return new StringBuilder(str); } public static CharSequence copy(final CharSequence str) { return str.toString(); } public static <V> List<V> mul(int x, Collection<V> lst) { ArrayList<V> list = new ArrayList<V>(x * lst.size()); for (int index=0; index < x; index++) { for (V element : lst){ list.add(element); } } return list; } public static String mul(int x, CharSequence seq) { StringBuilder builder = new StringBuilder(x * seq.length()); for (int index=0; index < x; index++) { builder.append(seq); } return builder.toString(); } public static <V> Set<V> set(final V... array) { return new HashSet<V>(list(array)); } public static List<Integer> range(int stop) { return range(0, stop); } public static List<Integer> range(int start, int stop) { ArrayList<Integer> range = new ArrayList<Integer>(stop-start); for (int index=start; index<stop; index++) { range.add(index); } return range; } public static List<Integer> range(int start, int stop, int inc) { ArrayList<Integer> range = new ArrayList<Integer>(stop-start); for (int index=start; index<stop; index+=inc) { range.add(index); } return range; } public static <K, V> Map<K, V> mp(K k0, V v0) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); map.put(k7, v7); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); map.put(k7, v7); map.put(k8, v8); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) { HashMap<K, V> map = new HashMap<K, V>(10); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); map.put(k7, v7); map.put(k8, v8); map.put(k9, v9); return map; } public static <K, V> Map<K, V> mp(K k0, V v0, K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, Entry<K,V>...entries) { HashMap<K, V> map = new HashMap<K, V>(10 + entries.length); map.put(k0, v0); map.put(k1, v1); map.put(k2, v2); map.put(k3, v3); map.put(k4, v4); map.put(k5, v5); map.put(k6, v6); map.put(k7, v7); map.put(k8, v8); map.put(k9, v9); for (Entry<K,V> entry: entries) { map.put(entry.key(), entry.value()); } return map; } public static <K, V> Map<K, V> mp(Collection<K> keys, Collection<V> values) { HashMap<K, V> map = new HashMap<K, V>(10 + keys.size()); Iterator<V> iterator = values.iterator(); for (K k : keys) { if (iterator.hasNext()) { V v = iterator.next(); map.put(k, v); } else { map.put(k, null); } } return map; } public static <K, V> Map<K, V> mp(K[] keys, V[] values) { HashMap<K, V> map = new HashMap<K, V>(10 + keys.length); int index = 0; for (K k : keys) { if (index < keys.length ) { V v = values[index]; map.put(k, v); } else { map.put(k, null); } index++; } return map; } public static <K, V> Map<K, V> dict(Entry<K,V>...entries) { HashMap<K, V> map = new HashMap<K, V>(5); for (Entry<K,V> entry: entries) { map.put(entry.key(), entry.value()); } return map; } // // Functional // // // Functional // public static interface Function <T> { T execute(Object... params); } private static class FunctionImpl<T> implements Function<T> { Method method; Object that; FunctionImpl(Class<T> clazz, Method method, Object that) { this.method=method; this.that = that; } @SuppressWarnings("unchecked") public T execute(Object... params) { T ret = null; try { ret = (T) method.invoke(that, params); } catch (Exception ex) { throw new ReflectionException("unable to execute function " + method.getName(), ex); } return ret; } } public static <T> Function<T> f(Class<T> returnType, Object that, Object... args) { try { return fn(returnType, that, "f", args); } catch (Exception e) { throw new ReflectionException(e); } } public static Function<?> f(Object that, Object... args) { try { return fn(that, "f", args); } catch (Exception e) { throw new ReflectionException(e); } } public static Function<?> fn(Object that, Object name, Object... args) { return fn(Object.class, that, name, args); } public static <T> Function<T> fn(Class<T> returnType, Object that, Object name, Object... args) { try { Method[] methods = clazz(that).getDeclaredMethods(); for (Method m : methods) { if (args.length <= m.getParameterTypes().length) { if (m.getName().equals(name.toString())) { m.setAccessible(true); if (Modifier.isStatic(m.getModifiers())) { return new FunctionImpl<T>(returnType, m, null); } else { return new FunctionImpl<T>(returnType, m, that); } } } } } catch (Exception ex) { log.log(Level.SEVERE, String.format("Unable to find function that=%s, name=%s, args=%s", that, name, list(args)), ex); } die("Unable to find function that=%s, name=%s, args=%s", that, name, list(args)); return null; } public static void enumerate(Function<?> f, Collection<?> c) { int index = 0; for (Object o : c) { f.execute(index, o); index++; } } public static Collection<?> filter(Function<?> f, List<?> l) { return gfilter(f,l); } public static Collection<?> filter(Function<?> f, Collection<?> c) { return gfilter(f, c); } public static <T> Collection<T> gfilter(Function<?> f, List<T> l) { ListIterator<?> listIterator = l.listIterator(); while (listIterator.hasNext()) { Boolean b = (Boolean) f.execute(listIterator.next()); if (!b) { listIterator.remove(); } } return l; } public static <T> Collection<T> gfilter(Function<?> f, Collection<T> in) { ArrayList<Object> removeList = new ArrayList<Object>(in.size()); ArrayList<T> c = new ArrayList<T>(in); for (Object o : in) { Boolean b = (Boolean) f.execute(0); if (!b) { removeList.add(o); } } for (Object o: removeList) { c.remove(o); } return c; } public static List<?> map(Function<?> f, List<?>...cols) { return gmap(f, cols); } public static <OUT> List<OUT> gmap(Function<OUT> f, List<?>...cols) { int max = Integer.MIN_VALUE; for (int index=0; index < cols.length; index++) { Collection<?> c = cols[index]; if (c.size() > max) { max =c.size(); } } ArrayList<OUT> mapList = new ArrayList<OUT>(max); for (int row = 0; row < max; row++) { ArrayList<Object> args = new ArrayList<Object>(cols.length); for (int index=0; index < cols.length; index++) { List<?> c = cols[index]; if (row < c.size()) { args.add(c.get(row)); } else { args.add(null); } } OUT object = f.execute(args.toArray(new Object[cols.length])); mapList.add(object); } return mapList; } public static List<?> map(Function<?> f, Collection<?> c) { return gmap(f, c); } public static <IN, OUT> List<OUT> gmap(Function<OUT> f, Collection<IN> c) { ArrayList<OUT> mapList = new ArrayList<OUT>(c.size()); for (Object o : c) { mapList.add(f.execute(o)); } return mapList; } @SuppressWarnings("rawtypes") public static Object reduce(Function f, Collection<?> c) { return greduce(f, c); } @SuppressWarnings("rawtypes") public static Object reduce(Function f, Object [] array) { return greduce(f, list(array)); } @SuppressWarnings("unchecked") public static <T> T greduce(Function<?> f, Collection<T> c) { T accumulo = null; int index=0; for (T o : c) { if (index==0) { accumulo = o; } else { accumulo = (T) f.execute(accumulo, o); } index++; } return accumulo; } //File //File public static interface File { String read(String path); String [] readLines(String path); } //String //String public static String lns(String... lines) { return lines(lines); } public static String lines(String... lines) { return join("\n", (Object[]) lines); } public static String join (String delim, Object ... args) { StringBuilder builder = new StringBuilder (256); for (Object arg : args) { builder.append(arg.toString()); builder.append(delim); } return builder.toString(); } public static String join (char delim, Object ... args) { StringBuilder builder = new StringBuilder (256); for (Object arg : args) { builder.append(arg.toString()); builder.append(delim); } return builder.toString(); } public static String join (Object ... args) { StringBuilder builder = new StringBuilder (256); for (Object arg : args) { builder.append(arg.toString()); } return builder.toString(); } public static String slc (CharSequence str, int start, int end) { return slice(str, start, end); } public static String slice (CharSequence str, int start, int end) { final int length = str.length(); //Adjust if (start < 0) { start = length + start; } if (end < 0) { end = length + end; } //Bound check if (start < 0) { start = 0; } if (start > length) { start = length; } if (end > str.length()) { end = str.length(); } if (end < 0) { end = 0; } //Bound check if (start > end) { return ""; } return str.subSequence(start, end).toString(); } public static String slc (CharSequence str, int start) { return slice(str, start); } public static String slice (CharSequence str, int start) { return slice (str, start, str.length()); } public static char index (CharSequence str, int index) { return idx(str, index); } public static char idx (CharSequence str, int index) { final int length = str.length(); //Adjust if (index < 0) { index = length + index; } //Bound check if (index < 0) { index = 0; } if (index > length) { index = length; } return str.charAt(index); } public static <T> List <T> slc (List <T> lst, int start, int end) { return slice(lst, start, end); } public static <T> List <T> slice (List <T> lst, int start, int end) { final int length = lst.size(); //Adjust if (start < 0) { start = length + start; } if (end < 0) { end = length + end; } //Bound check if (start < 0) { start = 0; } if (start > length) { start = length; } if (end > length) { end = length; } if (end < 0) { end = 0; } //Bound check if (start > end) { return lst.subList(0, 0); } return lst.subList(start, end); } public static <T> void rpl (List <T> lst, int start, int end, List<T> replacement) { replace(lst, start, end, replacement); } public static <T> void rpl (List <T> lst, int start, List<T> replacement) { rpl(lst, start, replacement); } public static <T> void replace (List <T> lst, int start, List<T> replacement) { replace(lst, start, lst.size(), replacement); } public static <T> void replace (List <T> lst, int start, int end, List<T> replacement) { final int length = lst.size(); //Adjust if (start < 0) { start = length + start; } if (end < 0) { end = length + end; } //Bound check if (start < 0) { start = 0; } if (start > length) { start = length; } if (end > length) { end = length; } if (end < 0) { end = 0; } if (start==end) { List<T> copy = copy(replacement); Collections.reverse(copy); for (T t: copy) { lst.add(start, t); } return; } int slicesize = end - start; int current = start; for (int index = 0; index < replacement.size(); index++, current++) { T t = replacement.get(index); if (index < slicesize ) { lst.set(current, t); } else { lst.add(current, t); } } int stop = current; while (current<end) { lst.remove(stop); current++; } } public static <T> List <T> slc (List <T> lst, int start) { return slice(lst, start); } public static <T> List <T> slice (List <T> lst, int start) { return slice(lst, start, lst.size()); } public static <T> T idx (List<T> lst, int index) { return index(lst, index); } public static <T> T index (List<T> lst, int index) { final int length = lst.size(); //Adjust if (index < 0) { index = length + index; } //Bound check if (index < 0) { index = 0; } if (index > length) { index = length; } return lst.get(index); } public static <T> void expect (T ex, T v) { if (ex == null && v == null) { return; } if (ex == null && v != null) { throw new AssertionException(sprintf("expected was null, but value was %s", v)); } if (!ex.equals(v)) { throw new AssertionException(sprintf("expected was %s, but value was %s", ex, v)); } } }
No comments:
Post a Comment