Rick

Rick
Rick

Saturday, June 9, 2012

More fooling around with EasyJava

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));
  }

 }

}

Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training