text:
"""Tests the graph quantization script.

"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np

import tensorflow as tf
from tensorflow.contrib.quantization.tools import quantize_graph
from tensorflow.python.framework import graph_util

flags = tf.app.flags
FLAGS = flags.FLAGS

def run_graph_def(graph_def, input_map, outputs):
  graph = tf.Graph()
  with graph.as_default():
    tf.import_graph_def(graph_def, input_map={}, name="")
  with tf.Session(graph=graph) as sess:
    results = sess.run(outputs, feed_dict=input_map)
  return results

def test_mat_mul(m, n, k, a, b):
  """Tests a MatMul replacement."""
  a_constant_name = "a_constant"
  b_constant_name = "b_constant"
  mat_mul_name = "mat_mul"

  float_graph_def = tf.GraphDef()
  a_constant = quantize_graph.create_constant_node(a_constant_name,
                                                   value=a,
                                                   dtype=tf.float32,
                                                   shape=[m, k])
  float_graph_def.node.extend([a_constant])
  b_constant = quantize_graph.create_constant_node(b_constant_name,
                                                   value=b,
                                                   dtype=tf.float32,
                                                   shape=[k, n])
  float_graph_def.node.extend([b_constant])
  mat_mul_node = quantize_graph.create_node("MatMul", mat_mul_name,
                                            [a_constant_name, b_constant_name])
  quantize_graph.set_attr_dtype(mat_mul_node, "T", tf.float32)
  quantize_graph.set_attr_bool(mat_mul_node, "transpose_a", False)
  quantize_graph.set_attr_bool(mat_mul_node, "transpose_b", False)
  float_graph_def.node.extend([mat_mul_node])

  test_graph(float_graph_def, {}, [mat_mul_name])

def test_conv(depth, image_width, image_height, image_batch_count, filter_size,
              filter_count, stride, padding, input_values, filter_values):
  """Tests a Conv replacement."""
  input_constant_name = "input_constant"
  filter_constant_name = "filter_constant"
  conv_name = "conv"

  float_graph_def = tf.GraphDef()
  input_constant = quantize_graph.create_constant_node(
      input_constant_name,
      value=input_values,
      dtype=tf.float32,
      shape=[
          image_batch_count, image_height, image_width, depth
      ])
  float_graph_def.node.extend([input_constant])
  filter_constant = quantize_graph.create_constant_node(
      filter_constant_name,
      value=filter_values,
      dtype=tf.float32,
      shape=[
          filter_size, filter_size, depth, filter_count
      ])
  float_graph_def.node.extend([filter_constant])
  conv_node = quantize_graph.create_node("Conv2D", conv_name,
                                         [input_constant_name,
                                          filter_constant_name])
  quantize_graph.set_attr_dtype(conv_node, "T", tf.float32)
  quantize_graph.set_attr_int_list(conv_node, "strides", [1, stride, stride, 1])
  quantize_graph.set_attr_string(conv_node, "padding", padding)
  float_graph_def.node.extend([conv_node])

  test_graph(float_graph_def, {}, [conv_name])

def are_tensors_near(a, b, tolerance):
  """Tests whether two tensors are nearly identical.

  This is a specialized comparison function designed to help debug problems with
  quantization. It prints out information about the differences between tensors
  on failure, paying special attention to possible biases by looking at the mean
  and absolute average errors.

  Args:
    a: First comparison tensor.
    b: Second comparison tensor.
    tolerance: Float value indicating how large an error between values is ok.

  Returns:
    Boolean indicating whether the two inputs were close enough.
  """
  flat_a = a.flatten()
  flat_b = b.flatten()
  if len(flat_a) != len(flat_b):
    print("Tensors are different sizes: " + str(len(flat_a)) + " vs " +
          str(len(flat_b)))
    return False
  value_count = len(flat_a)
  how_many_different = 0
  total_difference = 0
  total_abs_difference = 0
  for index in range(value_count):
    a_value = flat_a[index]
    b_value = flat_b[index]
    difference = a_value - b_value
    total_difference += difference
    total_abs_difference += abs(difference)
    if abs(difference) > tolerance:
      how_many_different += 1
  mean_difference = total_difference / value_count
  mean_abs_difference = total_abs_difference / value_count
  proportion_different = (how_many_different * 1.0) / value_count
  if how_many_different == 0:
    return True
  else:
    print("Tensors have {0} different values ({1}%), with mean difference"
          " {2} and mean absolute difference {3}".format(
              how_many_different, proportion_different * 100, mean_difference,
              mean_abs_difference))
    return False

def get_top_value(input_values):
  max_value = None
  max_index = None
  for index, value in enumerate(input_values.flatten()):
    if max_value is None or value > max:
      max_value = value
      max_index = index
  return max_index, max_value

def test_graph(float_graph_def, input_map, output_names):
  """Runs the float graph through the rewriter and tests the results."""
  float_results = run_graph_def(float_graph_def, input_map,
                                [output_name + ":0"
                                 for output_name in output_names])
  # TODO(petewarden): round test is currently failing because there is no
  # RoundToSteps op available.
  # round_rewriter = quantize_graph.GraphRewriter(float_graph_def, "round")
  # round_graph_def = round_rewriter.rewrite(output_name)
  # round_results = run_graph_def(round_graph_def, input_map,
  #                               [output_name + ":0"])
  # assert are_tensors_near(expected, round_results[0], 1.0)
  #
  # TODO(petewarden): Add test for "quantize" mode.

  eightbit_rewriter = quantize_graph.GraphRewriter(float_graph_def, "eightbit")
  eightbit_graph_def = eightbit_rewriter.rewrite(output_names)
  eightbit_results = run_graph_def(eightbit_graph_def, input_map,
                                   [output_name + ":0"
                                    for output_name in output_names])
  for expected, result in zip(float_results, eightbit_results):
    assert are_tensors_near(expected, result, 1.0)

  # Test the weights_rounded mode. This uses the default bit_depth.
  weights_rounded_rewriter = quantize_graph.GraphRewriter(
      float_graph_def, "weights_rounded")
  weights_rounded_graph_def = weights_rounded_rewriter.rewrite(output_names)
  weights_rounded_results = run_graph_def(weights_rounded_graph_def, input_map,
                                          [output_name + ":0"
                                           for output_name in output_names])
  for expected, result in zip(float_results, weights_rounded_results):
    assert are_tensors_near(expected, result, 1.0)

class QuantizeGraphTest(tf.test.TestCase):

  def test_negative_const_problem(self):
    shape_constant_name = "shape_constant"
    shape_constant = quantize_graph.create_constant_node(
        shape_constant_name, value=-0.8, dtype=tf.float32, shape=[1])
    quantization_result = quantize_graph.quantize_weight_eightbit(
        shape_constant, b"MIN_COMBINED")
    self.assertEqual(4, len(quantization_result))

  def test_odd_padding_problem(self):
    """Tests one error case we ran into in a real graph."""
    test_conv(1, 4, 4, 1, 3, 1, 2, b"SAME",
              [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
              [1, 2, 3, 4, 5, 6, 7, 8, 9])

  def test_mat_mul_tiny(self):
    # These tests are added to test the generate case where
    # min(matrix) == max(matrix), which used to cause problems.
    test_mat_mul(1, 1, 1, [2], [3])
    test_mat_mul(1, 2, 1, [1], [2, 3])
    test_mat_mul(1, 1, 2, [1, 1], [1, 1])
    test_mat_mul(1, 1, 2, [0, 0], [1, 1])
    # The general case.
    test_mat_mul(1, 1, 2, [1, 2], [1, 2])

  def test_mat_mul_small(self):
    test_mat_mul(2, 4, 3, [1, 2, 3, 4, 5, 6],
                 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18])

  def test_conv(self):
    test_conv(1, 4, 3, 1, 3, 1, 1, b"SAME",
              [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
              [1, 4, 7, 2, 5, 8, 3, 6, 9])

  def test_quantize_array(self):
    # Test invalid parameters (empty array, or 0 buckets.
    self.assertRaises(ValueError, quantize_graph.quantize_array,
                      np.array([]), 2)
    self.assertRaises(ValueError, quantize_graph.quantize_array,
                      np.array([1, 2]), 0)
    # Test input array of length 1.
    arr = np.array([1])
    qarr = quantize_graph.quantize_array(arr, 1)
    self.assertEqual(arr, qarr)
    qarr = quantize_graph.quantize_array(arr, 2)
    self.assertEqual(arr, qarr)
    # Test input array with all elements equal.
    arr = np.array([1, 1, 1])
    qarr = quantize_graph.quantize_array(arr, 10)
    self.assertTrue((np.array([1, 1, 1]) == qarr).all())
    # Test "normal" input arrays.
    arr = np.array([0, 0.3, 0.6, 1])
    qarr = quantize_graph.quantize_array(arr, 1)
    self.assertTrue((np.array([0.5, 0.5, 0.5, 0.5]) == qarr).all())
    qarr = quantize_graph.quantize_array(arr, 2)
    self.assertTrue((np.array([0.25, 0.25, 0.75, 0.75]) == qarr).all())
    qarr = quantize_graph.quantize_array(arr.reshape((2, 2)), 2)
    self.assertTrue((np.array([[0.25, 0.25], [0.75, 0.75]]) == qarr).all())

  def test_concat(self):
    shape_constant_name = "shape_constant"
    a_constant_name = "a_constant"
    b_constant_name = "b_constant"
    concat_name = "concat"

    float_graph_def = tf.GraphDef()
    shape_constant = quantize_graph.create_constant_node(shape_constant_name,
                                                         value=0,
                                                         dtype=tf.int32,
                                                         shape=[])
    float_graph_def.node.extend([shape_constant])
    a_constant = quantize_graph.create_constant_node(a_constant_name,
                                                     value=[1, 2, 3, 4, 5, 6, 7,
                                                            8, 9, 10, 11, 12],
                                                     dtype=tf.float32,
                                                     shape=[2, 2, 3])
    float_graph_def.node.extend([a_constant])
    b_constant = quantize_graph.create_constant_node(b_constant_name,
                                                     value=[13, 14, 15, 16, 17,
                                                            18, 19, 20, 21, 22,
                                                            23, 24],
                                                     dtype=tf.float32,
                                                     shape=[2, 2, 3])
    float_graph_def.node.extend([b_constant])
    concat_node = quantize_graph.create_node("Concat", concat_name,
                                             [shape_constant_name,
                                              a_constant_name, b_constant_name])
    quantize_graph.set_attr_int(concat_node, "N", 2)
    quantize_graph.set_attr_dtype(concat_node, "T", tf.float32)
    float_graph_def.node.extend([concat_node])

    test_graph(float_graph_def, {}, [concat_name])

  def test_multiple_outputs(self):
    input_constant_name = "input_constant"
    split_constant_name = "split_constant"
    split_name = "split"
    concat_constant_name = "concat_constant"
    concat_name = "concat"

    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[2, 6])
    float_graph_def.node.extend([input_constant])
    split_constant = quantize_graph.create_constant_node(split_constant_name,
                                                         value=1,
                                                         dtype=tf.int32,
                                                         shape=[])
    float_graph_def.node.extend([split_constant])
    split_node = quantize_graph.create_node("Split", split_name,
                                            [split_constant_name,
                                             input_constant_name])
    quantize_graph.set_attr_int(split_node, "num_split", 2)
    quantize_graph.set_attr_dtype(split_node, "T", tf.float32)
    float_graph_def.node.extend([split_node])
    concat_constant = quantize_graph.create_constant_node(concat_constant_name,
                                                          value=1,
                                                          dtype=tf.int32,
                                                          shape=[])
    float_graph_def.node.extend([concat_constant])
    concat_node = quantize_graph.create_node("Concat", concat_name,
                                             [concat_constant_name,
                                              split_name + ":0",
                                              split_name + ":1"])
    quantize_graph.set_attr_int(concat_node, "N", 2)
    quantize_graph.set_attr_dtype(concat_node, "T", tf.float32)
    float_graph_def.node.extend([concat_node])

    test_graph(float_graph_def, {}, [concat_name])

  def test_node_name_from_input(self):
    self.assertEqual("SomeName",
                     quantize_graph.node_name_from_input("^SomeName:2"))

  def test_unique_node_name_from_input(self):
    self.assertEqual("__hat__SomeName__port__2",
                     quantize_graph.unique_node_name_from_input("^SomeName:2"))

  def test_identity(self):
    input_constant_name = "input_constant"
    identity_name = "identity"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[2, 6])
    float_graph_def.node.extend([input_constant])
    identity_node = quantize_graph.create_node("Identity", identity_name,
                                               [input_constant_name])
    quantize_graph.set_attr_dtype(identity_node, "T", tf.float32)
    float_graph_def.node.extend([identity_node])
    test_graph(float_graph_def, {}, [identity_name])

  def test_keep_control_edges(self):
    no_op_name = "no_op"
    a_constant_name = "a_constant"
    b_constant_name = "b_constant"
    a_check_name = "a_check"
    b_check_name = "b_check"
    a_identity_name = "a_identity"
    b_identity_name = "b_identity"
    add_name = "add"
    graph_def = tf.GraphDef()
    no_op = quantize_graph.create_node("NoOp", no_op_name, [])
    graph_def.node.extend([no_op])
    a_constant = quantize_graph.create_constant_node(a_constant_name,
                                                     value=1,
                                                     dtype=tf.float32,
                                                     shape=[])
    graph_def.node.extend([a_constant])
    a_check_node = quantize_graph.create_node("CheckNumerics", a_check_name,
                                              [a_constant_name])
    graph_def.node.extend([a_check_node])
    a_identity_node = quantize_graph.create_node("Identity", a_identity_name,
                                                 [a_constant_name,
                                                  "^" + a_check_name,
                                                  "^" + no_op_name])
    graph_def.node.extend([a_identity_node])
    b_constant = quantize_graph.create_constant_node(b_constant_name,
                                                     value=1,
                                                     dtype=tf.float32,
                                                     shape=[])
    graph_def.node.extend([b_constant])
    b_check_node = quantize_graph.create_node("CheckNumerics", b_check_name,
                                              [b_constant_name])
    graph_def.node.extend([b_check_node])
    b_identity_node = quantize_graph.create_node("Identity", b_identity_name,
                                                 [b_constant_name,
                                                  "^" + b_check_name])
    graph_def.node.extend([b_identity_node])
    add_node = quantize_graph.create_node("Add", add_name,
                                          [a_identity_name,
                                           b_identity_name])
    quantize_graph.set_attr_dtype(add_node, "T", tf.float32)
    graph_def.node.extend([add_node])

    expected_output = tf.GraphDef()
    no_op = quantize_graph.create_node("NoOp", no_op_name, [])
    expected_output.node.extend([no_op])
    a_constant = quantize_graph.create_constant_node(a_constant_name,
                                                     value=1,
                                                     dtype=tf.float32,
                                                     shape=[])
    expected_output.node.extend([a_constant])
    a_identity_node = quantize_graph.create_node("Identity", a_identity_name,
                                                 [a_constant_name,
                                                  "^" + no_op_name])
    expected_output.node.extend([a_identity_node])
    b_constant = quantize_graph.create_constant_node(b_constant_name,
                                                     value=1,
                                                     dtype=tf.float32,
                                                     shape=[])
    expected_output.node.extend([b_constant])
    add_node = quantize_graph.create_node("Add", add_name,
                                          [a_identity_name,
                                           b_constant_name])
    quantize_graph.set_attr_dtype(add_node, "T", tf.float32)
    expected_output.node.extend([add_node])

    output = graph_util.remove_training_nodes(graph_def)
    stripped_output = graph_util.extract_sub_graph(output, [add_name])
    self.assertProtoEquals(expected_output, stripped_output)

  def test_batch_norm(self):
    input_constant_name = "input_constant"
    mean_constant_name = "mean_constant"
    variance_constant_name = "variance_constant"
    beta_constant_name = "beta_constant"
    gamma_constant_name = "gamma_constant"
    batch_norm_name = "batch_norm"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 4, 2, 5, 3,
                                                                6, -1, -4, -2,
                                                                -5, -3, -6],
                                                         dtype=tf.float32,
                                                         shape=[1, 1, 6, 2])
    float_graph_def.node.extend([input_constant])
    mean_constant = quantize_graph.create_constant_node(mean_constant_name,
                                                        value=[10, 20],
                                                        dtype=tf.float32,
                                                        shape=[2])
    float_graph_def.node.extend([mean_constant])
    variance_constant = quantize_graph.create_constant_node(
        variance_constant_name, value=[0.25, 0.5], dtype=tf.float32, shape=[2])
    float_graph_def.node.extend([variance_constant])
    beta_constant = quantize_graph.create_constant_node(beta_constant_name,
                                                        value=[0.1, 0.6],
                                                        dtype=tf.float32,
                                                        shape=[2])
    float_graph_def.node.extend([beta_constant])
    gamma_constant = quantize_graph.create_constant_node(gamma_constant_name,
                                                         value=[0, 0],
                                                         dtype=tf.float32,
                                                         shape=[2])
    float_graph_def.node.extend([gamma_constant])
    batch_norm_node = quantize_graph.create_node(
        "BatchNormWithGlobalNormalization", batch_norm_name,
        [input_constant_name, mean_constant_name, variance_constant_name,
         beta_constant_name, gamma_constant_name])
    quantize_graph.set_attr_dtype(batch_norm_node, "T", tf.float32)
    quantize_graph.set_attr_bool(batch_norm_node, "scale_after_normalization",
                                 False)
    quantize_graph.set_attr_float(batch_norm_node, "variance_epsilon", 0.001)
    float_graph_def.node.extend([batch_norm_node])
    test_graph(float_graph_def, {}, [batch_norm_name])

  def test_max_pool(self):
    input_constant_name = "input_constant"
    max_pool_name = "max_pool"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[1, 2, 6, 1])
    float_graph_def.node.extend([input_constant])
    max_pool_node = quantize_graph.create_node("MaxPool", max_pool_name,
                                               [input_constant_name])
    quantize_graph.set_attr_int_list(max_pool_node, "ksize", [1, 2, 2, 1])
    quantize_graph.set_attr_int_list(max_pool_node, "strides", [1, 1, 1, 1])
    quantize_graph.set_attr_string(max_pool_node, "padding", b"SAME")
    float_graph_def.node.extend([max_pool_node])
    test_graph(float_graph_def, {}, [max_pool_name])

  def test_avg_pool(self):
    input_constant_name = "input_constant"
    avg_pool_name = "avg_pool"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[1, 2, 6, 1])
    float_graph_def.node.extend([input_constant])
    avg_pool_node = quantize_graph.create_node("AvgPool", avg_pool_name,
                                               [input_constant_name])
    quantize_graph.set_attr_dtype(avg_pool_node, "T", tf.float32)
    quantize_graph.set_attr_int_list(avg_pool_node, "ksize", [1, 2, 2, 1])
    quantize_graph.set_attr_int_list(avg_pool_node, "strides", [1, 1, 1, 1])
    quantize_graph.set_attr_string(avg_pool_node, "padding", b"SAME")
    float_graph_def.node.extend([avg_pool_node])
    test_graph(float_graph_def, {}, [avg_pool_name])

  def test_relu(self):
    input_constant_name = "input_constant"
    relu_name = "relu"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[1, 2, 6, 1])
    float_graph_def.node.extend([input_constant])
    relu_node = quantize_graph.create_node("Relu", relu_name,
                                           [input_constant_name])
    quantize_graph.set_attr_dtype(relu_node, "T", tf.float32)
    float_graph_def.node.extend([relu_node])
    test_graph(float_graph_def, {}, [relu_name])

  def test_relu6(self):
    input_constant_name = "input_constant"
    relu6_name = "relu6"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[1, 2, 6, 1])
    float_graph_def.node.extend([input_constant])
    relu6_node = quantize_graph.create_node("Relu6", relu6_name,
                                            [input_constant_name])
    quantize_graph.set_attr_dtype(relu6_node, "T", tf.float32)
    float_graph_def.node.extend([relu6_node])
    test_graph(float_graph_def, {}, [relu6_name])

  def test_bias_add(self):
    input_constant_name = "input_constant"
    offset_constant_name = "offset_constant"
    bias_add_name = "bias_add"
    float_graph_def = tf.GraphDef()
    input_constant = quantize_graph.create_constant_node(input_constant_name,
                                                         value=[1, 2, 3, 4, 5,
                                                                6, 7, 8, 9, 10,
                                                                11, 12],
                                                         dtype=tf.float32,
                                                         shape=[1, 1, 2, 6])
    float_graph_def.node.extend([input_constant])
    offset_constant = quantize_graph.create_constant_node(offset_constant_name,
                                                          value=[1, 2, 3, 4, 5,
                                                                 6],
                                                          dtype=tf.float32,
                                                          shape=[6])
    float_graph_def.node.extend([offset_constant])
    bias_add_node = quantize_graph.create_node("BiasAdd", bias_add_name,
                                               [input_constant_name,
                                                offset_constant_name])
    quantize_graph.set_attr_dtype(bias_add_node, "T", tf.float32)
    float_graph_def.node.extend([bias_add_node])
    test_graph(float_graph_def, {}, [bias_add_name])

  def test_remove_redundant_quantization(self):
    a_constant_name = "a_constant"
    a_constant_min_name = "a_constant_min"
    a_constant_max_name = "a_constant_max"
    a_dequantize_name = "a_dequantize"
    a_quantize_name = "a_quantize"
    b_constant_name = "b_constant"
    b_constant_min_name = "b_constant_min"
    b_constant_max_name = "b_constant_max"
    b_dequantize_name = "b_dequantize"
    b_quantize_name = "b_quantize"
    mat_mul_name = "mat_mul"
    graph_def = tf.GraphDef()
    a_constant = quantize_graph.create_constant_node(a_constant_name,
                                                     value=(0,),
                                                     dtype=tf.quint8,
                                                     shape=[])
    graph_def.node.extend([a_constant])
    a_constant_min = quantize_graph.create_constant_node(a_constant_min_name,
                                                         value=2,
                                                         dtype=tf.float32,
                                                         shape=[])
    graph_def.node.extend([a_constant_min])
    a_constant_max = quantize_graph.create_constant_node(a_constant_max_name,
                                                         value=2,
                                                         dtype=tf.float32,
                                                         shape=[])
    graph_def.node.extend([a_constant_max])
    a_dequantize_node = quantize_graph.create_node("Dequantize",
                                                   a_dequantize_name,
                                                   [a_constant_name,
                                                    a_constant_min_name,
                                                    a_constant_max_name])
    quantize_graph.set_attr_dtype(a_dequantize_node, "T", tf.uint8)
    graph_def.node.extend([a_dequantize_node])
    a_quantize_node = quantize_graph.create_node("QuantizeV2",
                                                 a_quantize_name,
                                                 [a_dequantize_name,
                                                  a_dequantize_name + ":1",
                                                  a_dequantize_name + ":2"])
    quantize_graph.set_attr_dtype(a_quantize_node, "T", tf.uint8)
    graph_def.node.extend([a_quantize_node])
    b_constant = quantize_graph.create_constant_node(b_constant_name,
                                                     value=(0,),
                                                     dtype=tf.quint8,
                                                     shape=[])
    graph_def.node.extend([b_constant])
    b_constant_min = quantize_graph.create_constant_node(b_constant_min_name,
                                                         value=3,
                                                         dtype=tf.float32,
                                                         shape=[])
    graph_def.node.extend([b_constant_min])
    b_constant_max = quantize_graph.create_constant_node(b_constant_max_name,
                                                         value=3,
                                                         dtype=tf.float32,
                                                         shape=[])
    graph_def.node.extend([b_constant_max])
    b_dequantize_node = quantize_graph.create_node("Dequantize",
                                                   b_dequantize_name,
                                                   [b_constant_name,
                                                    b_constant_min_name,
                                                    b_constant_max_name])
    quantize_graph.set_attr_dtype(b_dequantize_node, "T", tf.uint8)
    graph_def.node.extend([b_dequantize_node])
    b_quantize_node = quantize_graph.create_node("QuantizeV2",
                                                 b_quantize_name,
                                                 [b_dequantize_name,
                                                  b_dequantize_name + ":1",
                                                  b_dequantize_name + ":2"])
    quantize_graph.set_attr_dtype(b_quantize_node, "T", tf.uint8)
    graph_def.node.extend([b_quantize_node])
    mat_mul_node = quantize_graph.create_node("QuantizedMatMul", mat_mul_name,
                                              [a_quantize_name,
                                               b_quantize_name,
                                               a_quantize_name + ":1",
                                               a_quantize_name + ":2",
                                               b_quantize_name + ":1",
                                               b_quantize_name + ":2"])
    quantize_graph.set_attr_dtype(mat_mul_node, "T1", tf.uint8)
    quantize_graph.set_attr_dtype(mat_mul_node, "T2", tf.int32)
    graph_def.node.extend([mat_mul_node])

    expected_output = tf.GraphDef()
    a_constant = quantize_graph.create_constant_node(a_constant_name,
                                                     value=(0,),
                                                     dtype=tf.quint8,
                                                     shape=[])
    expected_output.node.extend([a_constant])
    a_constant_min = quantize_graph.create_constant_node(a_constant_min_name,
                                                         value=2,
                                                         dtype=tf.float32,
                                                         shape=[])
    expected_output.node.extend([a_constant_min])
    a_constant_max = quantize_graph.create_constant_node(a_constant_max_name,
                                                         value=2,
                                                         dtype=tf.float32,
                                                         shape=[])
    expected_output.node.extend([a_constant_max])
    b_constant = quantize_graph.create_constant_node(b_constant_name,
                                                     value=(0,),
                                                     dtype=tf.quint8,
                                                     shape=[])
    expected_output.node.extend([b_constant])
    b_constant_min = quantize_graph.create_constant_node(b_constant_min_name,
                                                         value=3,
                                                         dtype=tf.float32,
                                                         shape=[])
    expected_output.node.extend([b_constant_min])
    b_constant_max = quantize_graph.create_constant_node(b_constant_max_name,
                                                         value=3,
                                                         dtype=tf.float32,
                                                         shape=[])
    expected_output.node.extend([b_constant_max])
    mat_mul_node = quantize_graph.create_node("QuantizedMatMul", mat_mul_name,
                                              [a_constant_name,
                                               b_constant_name,
                                               a_constant_min_name,
                                               a_constant_max_name,
                                               b_constant_min_name,
                                               b_constant_max_name])
    quantize_graph.set_attr_dtype(mat_mul_node, "T1", tf.uint8)
    quantize_graph.set_attr_dtype(mat_mul_node, "T2", tf.int32)
    expected_output.node.extend([mat_mul_node])

    rewriter = quantize_graph.GraphRewriter(graph_def, [mat_mul_name])
    output = rewriter.remove_redundant_quantization(graph_def)
    stripped_output = graph_util.extract_sub_graph(output, [mat_mul_name])
    self.assertProtoEquals(expected_output, stripped_output)

if __name__ == "__main__":
  tf.test.main()


text:
from django.conf.urls.defaults import patterns, url

urlpatterns = patterns('seahub.notifications.views',
#    url(r'^$', 'notification_list', name='notification_list'),
    url(r'^add/$', 'notification_add', name='notification_add'),
    url(r'^delete/(?P<nid>[\d]+)/$', 'notification_delete', name='notification_delete'),
    url(r'^set-primary/(?P<nid>[\d]+)/$', 'set_primary', name='set_primary'),

########## user notifications
    url(r'^list/$', 'user_notification_list', name='user_notification_list'),
    url(r'^more/$', 'user_notification_more', name='user_notification_more'),
    url(r'^remove/$', 'user_notification_remove', name='user_notification_remove'),
)

redpajama_set_name: RedPajamaGithub


text:
cask 'processing' do
  version '3.1.1'
  sha256 '32bb3ae5c431e5bc92a457a53d3bac51874a530898c32625a44b5bdcf1edebdc'

  url "http://download.processing.org/processing-#{version}-macosx.zip"
  appcast 'https://github.com/processing/processing/releases.atom',
          checkpoint: 'fb0627edbf01a70261d623306a63c455d96f182d70b2e4caf390adfa8063f92d'
  name 'Processing'
  homepage 'https://processing.org/'
  license :gpl

  app 'Processing.app'

  zap delete: '~/Library/Processing/preferences.txt'
end


text:
import * as Knex from 'knex'

import config from '../../config'
const scheme = config.externalProductionSchema + '.'

export async function seed(knex: Knex): Promise<any> {
	await knex(scheme + 'item_type').del()
	await knex(scheme + 'item_type').insert([
		{ id: 'prototype', name: 'Prototype' },
		{ id: 'request', name: 'Request' },
		{ id: 'service', name: 'Service' }
	])
	await knex(scheme + 'status').del()
	await knex(scheme + 'status').insert([
		{ id: 'new', name: 'New' },
		{ id: 'assistanceRequested', name: 'Assistance requested' },
		{ id: 'priceApproval', name: 'Needs price approval' },
		{ id: 'completed', name: 'Completed' },
		{ id: 'restarted', name: 'Restarted' },
		{ id: 'cancelled', name: 'Cancelled' },
		{ id: 'scrapped', name: 'Scrapped' },
		{ id: 'defined', name: 'Operations defined' },
		{ id: 'defined.none', name: 'Operation initialized' },
		{ id: 'defined.ordered', name: 'Operation ordered' },
		{ id: 'defined.checked', name: 'Checked' },
		{ id: 'defined.takenOver', name: 'Taken over' },
		{ id: 'defined.toReview', name: 'Needs review' },
		{ id: 'defined.stored', name: 'Stored' },
		{ id: 'defined.reviewed', name: 'Reviewed' },
		{ id: 'defined.finished', name: 'Finished' },
		{ id: 'defined.received', name: 'Received' },
		{ id: 'defined.failedReview', name: 'Failed review' },
		{ id: 'defined.dispatched', name: 'Operation dispatched' },
		{ id: 'approved', name: 'Approved' },
		{ id: 'rejected', name: 'Rejected' },
		{ id: 'pickedUp', name: 'Picked Up' },
		{ id: 'priceDefined', name: 'Price Defined' },
		{ id: 'ordered', name: 'Ordered' },
		{ id: 'dispatched', name: 'Dispatched' },
		{ id: 'received', name: 'Received' },
		{ id: 'readyToOrder', name: 'Ready To Order' },
		{ id: 'passedCheck', name: 'Passed check' },
		{ id: 'failedCheck', name: 'Failed check' }
	])
}


text:
const validator = require('../isUppercase');

describe('isUppercase', () => {

  it('fails when not a string', async () => {
    expect(validator(true)).toEqual(false);
  });

  it('fails when invalid', async () => {
    expect(validator('Hello')).toEqual(false);
  });

  it('passes when valid', async () => {
    expect(validator('HELLO')).toEqual(true);
  });

});


text:
using NUnit.Framework.Interfaces;

namespace NUnit.Framework.Internal.Results
{
    public class TestResultWarningTests : TestResultTests
    {
        [SetUp]
        public void SimulateTestRun()
        {
            _testResult.SetResult(ResultState.Warning, "Warning message");
            _suiteResult.AddResult(_testResult);
        }

        [Test]
        public void TestResultIsWarning()
        {
            Assert.AreEqual(ResultState.Warning, _testResult.ResultState);
            Assert.AreEqual("Warning message", _testResult.Message);
        }

        [Test]
        public void SuiteResultIsWarning()
        {
            Assert.AreEqual(ResultState.ChildWarning, _suiteResult.ResultState);
            Assert.AreEqual(TestResult.CHILD_WARNINGS_MESSAGE, _suiteResult.Message);

            Assert.AreEqual(0, _suiteResult.PassCount);
            Assert.AreEqual(0, _suiteResult.FailCount);
            Assert.AreEqual(1, _suiteResult.WarningCount);
            Assert.AreEqual(0, _suiteResult.SkipCount);
            Assert.AreEqual(0, _suiteResult.InconclusiveCount);
            Assert.AreEqual(0, _suiteResult.AssertCount);
        }

        [Test]
        public void TestResultXmlNodeIsWarning()
        {
            TNode testNode = _testResult.ToXml(true);

            Assert.AreEqual("Warning", testNode.Attributes["result"]);
            Assert.AreEqual(null, testNode.Attributes["label"]);
            Assert.AreEqual(null, testNode.Attributes["site"]);

            TNode reason = testNode.SelectSingleNode("reason");
            Assert.NotNull(reason);
            Assert.NotNull(reason.SelectSingleNode("message"));
            Assert.AreEqual("Warning message", reason.SelectSingleNode("message").Value);
            Assert.Null(reason.SelectSingleNode("stack-trace"));
        }

        [Test]
        public void SuiteResultXmlNodeIsWarning()
        {
            TNode suiteNode = _suiteResult.ToXml(true);

            Assert.AreEqual("Warning", suiteNode.Attributes["result"]);
            Assert.AreEqual(null, suiteNode.Attributes["label"]);
            Assert.AreEqual("Child", suiteNode.Attributes["site"]);
            Assert.AreEqual("0", suiteNode.Attributes["passed"]);
            Assert.AreEqual("0", suiteNode.Attributes["failed"]);
            Assert.AreEqual("1", suiteNode.Attributes["warnings"]);
            Assert.AreEqual("0", suiteNode.Attributes["skipped"]);
            Assert.AreEqual("0", suiteNode.Attributes["inconclusive"]);
            Assert.AreEqual("0", suiteNode.Attributes["asserts"]);
        }
    }
}


text:
package com.oshare.thirdparty.utils;

import java.util.Random;
import java.util.UUID;

public class UUIDUtil {

	/**
	 * UUID
	 *
	 * @return the string
	 */
	public static String uuid() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/**
	 * 获取随机字符串
	 *
	 * @param length
	 *            the length
	 * @return the random string
	 */
	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	public static String getRandomInt(int length) { // length表示生成字符串的长度
		String base = "0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

}


text:
<?php
/**
 * Created by albertus
 * Project MultiE-Comm
 * on Feb 2017.
 */
?>

            Master Fitur

                  Dashboard

                 Master Fitur

        <?php //print_r($dpenjualan); ?>

 Master Paket Fitur

Data Fitur Paket Berlangganan

                            ID
                            Nama Paket
                            Harga

                        <?php
                        for ($j = 0; $j < count($data); $j++){
                            if($data[$j]['Enable'] == "1"){
                                echo "
";
                                echo "".$data[$j]['ID']."	";
                                echo "".$data[$j]['Nama Paket']."	";
                                echo "IDR".str_pad(number_format($data[$j]['Harga'],2,',','.'),20 ," ",STR_PAD_LEFT)."	";
                                echo "
";
                            }
                        }
                        ?>

Actions

                        <input type="button" class="btn btn-primary btn-block btn-lg" value="Insert Data" name="insertButton" id="insertButton"/>

                        <input type="button" class="btn btn-primary btn-block btn-lg" value="Update Data" name="updateButton" id="updateButton"/>

                        <input type="button" class="btn btn-primary btn-block btn-lg" value="Delete Data" name="deleteButton" id="deleteButton"/>

                    <button type="button" class="close" data-dismiss="modal">×</button>

Actions

                    <button type="button" class="close" data-dismiss="modal">×</button>

Search Data

                    <button type="button" class="close" data-dismiss="modal">×</button>

Caution!

                    <button type="button" class="btn btn-primary btn-block" id="yesOption" data-dismiss="modal">Yes</button>
                    <button type="button" class="btn btn-danger btn-block" id="noOption" data-dismiss="modal">No</button>


text:
<!doctype html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="description" content="Sample illustrating the use of 'any-hover' and 'any-pointer' Media Queries.">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>'any-pointer' and 'any-hover' Media Queries Sample</title>

    <meta name="mobile-web-app-capable" content="yes">
    <link rel="icon" sizes="192x192" href="../images/touch/chrome-touch-icon-192x192.png">

    <meta name="apple-mobile-web-app-title" content="'any-pointer' and 'any-hover' Media Queries Sample">

    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" href="../images/apple-touch-icon-precomposed.png">

    <meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">
    <meta name="msapplication-TileColor" content="#3372DF">

    <link rel="icon" href="../images/favicon.ico">

    <link rel="stylesheet" href="../styles/main.css">

'any-pointer' and 'any-hover' Media Queries Sample

Available in Chrome 41+

      These media features describe the capabilities of all input devices available to the user as per the specification.
      These are similar to the older 'pointer' and 'hover' media features, except that the older features only reflect the primary input device.

      For example, if a user is on a tablet (with a primary touch input) with a connected mouse, 'any-pointer' will be fine.

        <button id="sized_1" class="sized">
          Click Me
        </button>
        This button will be larger where there is no fine pointer available

          any-pointer

          any-pointer: none

          any-pointer: coarse

          any-pointer: fine

          any-hover

          any-hover: none

          any-hover: hover


text:
from jinja2.runtime import Undefined, StrictUndefined

class FilterModule(object):
    ''' A comment '''

    def filters(self):
        return {
            'is_empty': self.is_empty,
            'is_empty_or_undefined': self.is_empty_or_undefined,
        }

    def is_empty(self, input_value):
        return (input_value is None or len(input_value) == 0)

    def is_empty_or_undefined(self, input_value):
        return (type(input_value) in (StrictUndefined, Undefined, ) or
                self.is_empty(input_value))


text:
package org.yaml.snakeyaml.issues.issue10;

import java.util.List;

public class DataSources {
    List<DataSource> dataSources;

    public List<DataSource> getDataSources() {
        return dataSources;
    }

    public void setDataSources(List<DataSource> dataSources) {
        this.dataSources = dataSources;
    }
}


text:
layout: post
title: Try designing my own website with 6 principles
categories: [dev]
tags: [web]

---

# Try designing my own website with 6 principles

inspired by : [https://www.taniarascia.com/](https://www.taniarascia.com/)

6 princibles : [https://namu.wiki/w/%EC%9C%A1%ED%95%98%EC%9B%90%EC%B9%99/](https://namu.wiki/w/%EC%9C%A1%ED%95%98%EC%9B%90%EC%B9%99/)

---
# Who?

- For sure, me.
- As a developer
- As a geek; Game, Soccer, Photo, Clothes, Music
- Should I choose one? Think it later

---
# When?

- Start : end of designing
- due? as fast as possible with minimal feature #keep_in_lean_and_agile

---
# Where?

- On website for PC, mobile
- email subscription

---
# What?

- Share my daily challenge and  get feedback from readers
- Blog post seems a best option, but in my experience, writing  a blog post was not easy.
- I need a way to share my thinking effectively.
- Making blog post as a result of a challenge.
- Need a habit for that

---
# How?

- I struggled to answer this question, because using a markdown blog solution is enough to meet the requirements.
- But I want to make my own website for practicing my web dev skills and more extensible features.
- So, "Why" question should be placed first

---
# Why?

- To present myself
- To make web dev as a habit
- To improve web dev skills
- To get web design skills

---
# How? again

- Make a simple markdown enabled blog


text:
package com.hungry.mouse.main;

import com.hungry.mouse.framework.Game;
import com.hungry.mouse.framework.Graphics;
import com.hungry.mouse.framework.Image;
import com.hungry.mouse.framework.Input.TouchEvent;
import com.hungry.mouse.framework.Screen;

//java libraries
import java.util.ArrayList;//implementation of list with additional operations add,remove,replace
import java.util.List;//a collection which maintain an ordering for its elements
import java.util.Scanner;//parser that parses a text string of primitive types and strings with the help of regular expressions

//android libraries stored in SDK platform
import android.graphics.Color;//defines method for creating and converting color ints
import android.graphics.Paint;//holds the style and color information about how to draw geometries, text and bitmaps

public class GameScreen extends Screen {
	enum GameState {
		Ready, Running, Paused, GameOver, LevelIsPassed
	}

	GameState state = GameState.Ready;

	//local variables
	private static Background bg1, bg2;
	private static Mouse mouse;
	public static Kamikazi hb, hb2, hb3, hb4, hb5, hb6, hb7, hb8, hb9;
	public static Cheese ch,ch2,ch3,ch4,ch5,ch6,ch7,ch8;
	public static Bomb bo, bo2, bo3, bo4, bo5, bo6, bo7, bo8, bo9;
	public static Sign si;

	float accelerometerValue;//get negative and positive value for left and right

	//members
	private Image currentSprite, character, character2, character3, Kamikazi,
			Kamikazi2, Kamikazi3, Kamikazi4, Kamikazi5;
	private Animation anim, banim, hanim, canim, sanim;
	private Image cheese, cheese2, cheese3;
	private Image bomb, bomb2;
	private Image sign, sign2;
	private ArrayList<Tile> tilearray = new ArrayList<Tile>();

	Paint paint, paint2;

	int livesLeft = 1;
	//constructor
	public GameScreen(Game game) {
		super(game);

		//initialize game objects
		//background
		bg1 = new Background(0, 0);
		bg2 = new Background(2160, 0);

		//need to initialize bg1 and bg2 before calling mouse
		mouse = new Mouse();

		if (Settings.currentLevel == 1)
		{
			si = new Sign(8000,347);

			ch = new Cheese(520,347);
			ch2 = new Cheese(760,347);
			ch3 = new Cheese(1080,347);
			ch4 = new Cheese(2960,347);
			ch5 = new Cheese(3640,347);
			ch6 = new Cheese(5200,347);
			ch7 = new Cheese(6080,347);
			ch8 = new Cheese(6600,347);

			bo = new Bomb(1200,347);
			bo.setHealth(1);
			bo2 = new Bomb(3000,347);
			bo2.setHealth(1);
			bo3 = new Bomb(3160,347);
			bo3.setHealth(1);
			bo4 = new Bomb(4830,347);
			bo4.setHealth(1);
			bo5 = new Bomb(6120,347);
			bo5.setHealth(1);
			bo6 = new Bomb(7320,347);
			bo6.setHealth(1);
			bo7 = new Bomb(9380,347);
			bo7.setHealth(1);
			bo8 = new Bomb(9420,347);
			bo8.setHealth(1);
			bo9 = new Bomb(9500,347);
			bo9.setHealth(1);

			hb = new Kamikazi(340, 297);
			hb.setHealth(5);
			hb2 = new Kamikazi(1600,297);
			hb2.setHealth(5);
			hb3 = new Kamikazi(1720,297);
			hb3.setHealth(5);
			hb4 = new Kamikazi(5200,297);
			hb4.setHealth(5);
			hb5 = new Kamikazi(6360,297);
			hb5.setHealth(5);
			hb6 = new Kamikazi(6420,297);
			hb6.setHealth(4);
			hb7 = new Kamikazi(7440,297);
			hb7.setHealth(5);
			hb8 = new Kamikazi(7500,297);
			hb8.setHealth(6);
			hb9 = new Kamikazi(7560,297);
			hb9.setHealth(12);
		}
		else if(Settings.currentLevel == 2){
			si = new Sign(8000,347);

			ch = new Cheese(520,347);
			ch2 = new Cheese(760,347);
			ch3 = new Cheese(1080,347);
			ch4 = new Cheese(2960,347);
			ch5 = new Cheese(3640,347);
			ch6 = new Cheese(5200,347);
			ch7 = new Cheese(6080,347);
			ch8 = new Cheese(6600,347);

			bo = new Bomb(1200,347);
			bo.setHealth(1);
			bo2 = new Bomb(3000,347);
			bo2.setHealth(1);
			bo3 = new Bomb(3160,347);
			bo3.setHealth(1);
			bo4 = new Bomb(4830,347);
			bo4.setHealth(1);
			bo5 = new Bomb(6120,347);
			bo5.setHealth(1);
			bo6 = new Bomb(7320,347);
			bo6.setHealth(1);
			bo7 = new Bomb(9380,347);
			bo7.setHealth(1);
			bo8 = new Bomb(9420,347);
			bo8.setHealth(1);
			bo9 = new Bomb(9500,347);
			bo9.setHealth(1);

			hb = new Kamikazi(340, 297);
			hb.setHealth(9);
			hb2 = new Kamikazi(1600,297);
			hb2.setHealth(10);
			hb3 = new Kamikazi(1720,297);
			hb3.setHealth(11);
			hb4 = new Kamikazi(5200,297);
			hb4.setHealth(10);
			hb5 = new Kamikazi(6360,297);
			hb5.setHealth(7);
			hb6 = new Kamikazi(6420,297);
			hb6.setHealth(10);
			hb7 = new Kamikazi(7440,297);
			hb7.setHealth(6);
			hb8 = new Kamikazi(7500,297);
			hb8.setHealth(5);
			hb9 = new Kamikazi(7560,297);
			hb9.setHealth(25);
		}
		else if(Settings.currentLevel == 3){
			si = new Sign(7560,347);

			ch = new Cheese(520,347);
			ch2 = new Cheese(760,347);
			ch3 = new Cheese(1080,347);
			ch4 = new Cheese(2960,347);
			ch5 = new Cheese(3640,347);
			ch6 = new Cheese(5200,347);
			ch7 = new Cheese(6080,347);
			ch8 = new Cheese(6600,347);

			bo = new Bomb(1200,347);
			bo.setHealth(1);
			bo2 = new Bomb(3000,347);
			bo2.setHealth(1);
			bo3 = new Bomb(3160,347);
			bo3.setHealth(1);
			bo4 = new Bomb(4830,347);
			bo4.setHealth(1);
			bo5 = new Bomb(6120,347);
			bo5.setHealth(1);
			bo6 = new Bomb(7320,347);
			bo6.setHealth(1);
			bo7 = new Bomb(9380,347);
			bo7.setHealth(1);
			bo8 = new Bomb(9420,347);
			bo8.setHealth(1);
			bo9 = new Bomb(9500,347);
			bo9.setHealth(1);

			hb = new Kamikazi(340, 297);
			hb.setHealth(5);
			hb2 = new Kamikazi(1600,297);
			hb2.setHealth(10);
			hb3 = new Kamikazi(1720,297);
			hb3.setHealth(13);
			hb4 = new Kamikazi(5200,297);
			hb4.setHealth(15);
			hb5 = new Kamikazi(6360,297);
			hb5.setHealth(9);
			hb6 = new Kamikazi(6420,297);
			hb6.setHealth(15);
			hb7 = new Kamikazi(7440,297);
			hb7.setHealth(8);
			hb8 = new Kamikazi(7500,297);
			hb8.setHealth(15);
			hb9 = new Kamikazi(7560,297);
			hb9.setHealth(33);
		}

		character = Assets.character;
		character2 = Assets.character2;
		character3 = Assets.character3;

		Kamikazi = Assets.Kamikazi;
		Kamikazi2 = Assets.Kamikazi2;
		Kamikazi3 = Assets.Kamikazi3;
		Kamikazi4 = Assets.Kamikazi4;
		Kamikazi5 = Assets.Kamikazi5;

		bomb = Assets.bomb;
		bomb2 = Assets.bomb;

		sign = Assets.sign;
		sign2 = Assets.sign;

		cheese = Assets.cheese_reward;
		cheese2 = Assets.cheese_reward;
		cheese3 = Assets.cheese_reward;

		//animations based on frames
		anim = new Animation();
		anim.addFrame(character, 1250);
		anim.addFrame(character2, 50);
		anim.addFrame(character3, 50);
		anim.addFrame(character2, 50);

		banim = new Animation();
		banim.addFrame(bomb, 100);
		banim.addFrame(bomb2, 100);

		hanim = new Animation();
		hanim.addFrame(Kamikazi, 100);
		hanim.addFrame(Kamikazi2, 100);
		hanim.addFrame(Kamikazi3, 100);
		hanim.addFrame(Kamikazi4, 100);
		hanim.addFrame(Kamikazi5, 100);
		hanim.addFrame(Kamikazi4, 100);
		hanim.addFrame(Kamikazi3, 100);
		hanim.addFrame(Kamikazi2, 100);

		canim = new Animation();
		canim.addFrame(cheese, 100);
		canim.addFrame(cheese2, 100);
		canim.addFrame(cheese3, 100);

		sanim = new Animation();
		sanim.addFrame(sign, 100);

		currentSprite = anim.getImage();

		loadMap();

		// Defining a paint object
		paint = new Paint();
		paint.setTextSize(30);
		paint.setTextAlign(Paint.Align.CENTER);
		paint.setAntiAlias(true);
		paint.setColor(Color.RED);

		paint2 = new Paint();
		paint2.setTextSize(100);
		paint2.setTextAlign(Paint.Align.CENTER);
		paint2.setAntiAlias(true);
		paint2.setColor(Color.WHITE);

	}

	//load the map to create the level environment
	private void loadMap() {
		ArrayList lines = new ArrayList();
		int width = 0;
		int height = 0;

		Scanner scanner = new Scanner(SampleGame.map);
		while (scanner.hasNextLine()) {
			String line = scanner.nextLine();

			//no more lines to read
			if (line == null) {
				break;
			}

			//ignore comments
			if (!line.startsWith("!")) {
				lines.add(line);
				width = Math.max(width, line.length());

			}
		}
		height = lines.size();

		//loop until the boarders of the screen
		for (int j = 0; j < 12; j++) {
			String line = (String) lines.get(j);
			for (int i = 0; i < width; i++) {

				if (i < line.length()) {
					char ch = line.charAt(i);
					Tile t = new Tile(i, j, Character.getNumericValue(ch));
					tilearray.add(t);
				}

			}
		}

	}

	//update and present different screens based on events
	@Override
	public void update(float deltaTime) {
		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();

		// We have four separate update methods in this example.
		// Depending on the state of the game, we call different update methods.
		// Refer to Unit 3's code. We did a similar thing without separating the
		// update methods.

		if (state == GameState.Ready)
			updateReady(touchEvents);
		if (state == GameState.Running)
			updateRunning(touchEvents, deltaTime);
		if (state == GameState.Paused)
			updatePaused(touchEvents);
		if (state == GameState.GameOver)
			updateGameOver(touchEvents);
		if (state == GameState.LevelIsPassed)
			updateLevelIsPassed(touchEvents);
	}

	//when user touch screen, the game begin
	private void updateReady(List<TouchEvent> touchEvents) {
		if (touchEvents.size() > 0)
			state = GameState.Running;
	}

	//game is running and we look for events to control the player
	private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {

		if (si.collected)
			state = GameState.LevelIsPassed;

		if (Settings.gyroscopeEnabled){
		//go right or left using accelerometer
		accelerometerValue=game.getInput().getAccelY();

		if (accelerometerValue>1.8) {
			mouse.moveRight();
			mouse.setMovingLeft(false);

		} else if (accelerometerValue<-1.8) {
			mouse.moveLeft();
			mouse.setMovingRight(false);

		} else
		{
			mouse.stopLeft();
			mouse.stopRight();
		}

		}

		//handle the input
		int len = touchEvents.size();
		for (int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if (event.type == TouchEvent.TOUCH_DOWN) {//when pressed down the key

				//jump
				if (inBounds(event, 592, 368, 96, 96)) {
					mouse.jump();
					currentSprite = anim.getImage();
					mouse.setDucked(false);

				}

				else if (inBounds(event, 688, 368, 96, 96)) {
					//fire
					if (mouse.isDucked() == false && mouse.isJumped() == false
							&& mouse.isReadyToFire()) {
							mouse.shoot();
											}
				}

				else if (inBounds(event, 592, 368, 96, 96)
						&& mouse.isJumped() == false) {
					currentSprite = Assets.characterDown;
					mouse.setDucked(true);
					mouse.setSpeedX(0);

				}

				if (!Settings.gyroscopeEnabled){//if gyroscope is on, we dont need the control arrows
					if (inBounds(event, 112, 368, 96, 96)) {
						mouse.moveRight();
						mouse.setMovingLeft(false);

					}
					else if (inBounds(event, 16, 368, 96, 96)) {
						mouse.moveLeft();
						mouse.setMovingRight(false);
					}

				}

			}

			if (event.type == TouchEvent.TOUCH_UP) {//when release the key

				if (inBounds(event, 0, 415, 65, 65)) {
					currentSprite = anim.getImage();
					mouse.setDucked(false);

				}

				if (inBounds(event, 0, 0, 130, 130)) {
					pause();

				}
				if (!Settings.gyroscopeEnabled){//if gyroscope is on, we dont need the control arrows
					if (inBounds(event, 112, 368, 96, 96)) {
						mouse.stopLeft();

					}
					if (inBounds(event, 16, 368, 96, 96)) {
						mouse.stopRight();

					}
				}
			}

		}

		//check for death and show gameover screen
		if (livesLeft == 0) {//when fall to gap
			state = GameState.GameOver;
		}

		if (mouse.getHealth() <1)//when died from kamikazis and bombs
		{
			state = GameState.GameOver;
		}

		//update mouse,kamikazi,bullets,background and everything that is included in game
		if (mouse != null) {
			mouse.update();
		 } else{
		       System.out.println("mouse is null, do not attempt to call update");
		}
		if (mouse.isJumped()) {
			currentSprite = Assets.characterJump;
		} else if (mouse.isJumped() == false && mouse.isDucked() == false) {
			currentSprite = anim.getImage();
		}

		ArrayList projectiles = mouse.getProjectiles();
		for (int i = 0; i < projectiles.size(); i++) {
			Projectile p = (Projectile) projectiles.get(i);
			if (p.isVisible() == true) {
				p.update();
			} else {
				projectiles.remove(i);
			}
		}

		updateTiles();
		hb.update();
		hb2.update();
		hb3.update();
		hb4.update();
		hb5.update();
		hb6.update();
		hb7.update();
		hb8.update();
		hb9.update();

		bg1.update();
		bg2.update();

		//cheese
		ch.update();
		ch2.update();
		ch3.update();
		ch4.update();
		ch5.update();
		ch6.update();
		ch7.update();
		ch8.update();

		//bomb
		bo.update();
		bo2.update();
		bo3.update();
		bo4.update();
		bo5.update();
		bo6.update();
		bo7.update();
		bo8.update();
		bo9.update();

		//sign
		si.update();

		animate();

		if (mouse.getCenterY() > 500) {
			state = GameState.GameOver;
		}
	}

	//check if user touch inside the rectangle
	private boolean inBounds(TouchEvent event, int x, int y, int width,
			int height) {
		if (event.x > x && event.x < x + width - 1 && event.y > y
				&& event.y < y + height - 1)
			return true;
		else
			return false;
	}

	//g.drawImage(Assets.menu_buttons,  224, 128, 0, 128, 352, 256);//play button (show the 2/3 of image)
	//show pause screen
	private void updatePaused(List<TouchEvent> touchEvents) {
		int len = touchEvents.size();
		for (int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if (event.type == TouchEvent.TOUCH_DOWN) {
				if (inBounds(event, 0, 0, 800, 240)) {

					if (!inBounds(event, 0, 0, 96, 96)) {
						resume();
					}
				}

				if (inBounds(event, 0, 240, 800, 240)) {
					nullify();
					goToMenu();
				}
			}
		}
	}

	//show game over screen
	private void updateGameOver(List<TouchEvent> touchEvents) {
		int len = touchEvents.size();
		for (int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if (event.type == TouchEvent.TOUCH_DOWN) {
				if (inBounds(event, 0, 0, 800, 480)) {
					nullify();
					game.setScreen(new LevelSelectorScreen(game));
					return;
				}
			}
		}

	}

	//show level passed screen
	private void updateLevelIsPassed(List<TouchEvent> touchEvents) {

		//change score only if its better
		if (Settings.currentLevel==1)
		{
			if (Settings.level1CollectedCheeses < mouse.getCollectedCheeses())
				Settings.level1CollectedCheeses=mouse.getCollectedCheeses();

			if (Settings.level1KilledKamikazis < mouse.getKamikaziKilled())
				Settings.level1KilledKamikazis=mouse.getKamikaziKilled();

		}
		else if (Settings.currentLevel==2)
		{
			if (Settings.level2CollectedCheeses < mouse.getCollectedCheeses())
				Settings.level2CollectedCheeses=mouse.getCollectedCheeses();
			if (Settings.level2KilledKamikazis < mouse.getKamikaziKilled())
				Settings.level2KilledKamikazis=mouse.getKamikaziKilled();
		}
		else
		{
			if (Settings.level3CollectedCheeses < mouse.getCollectedCheeses())
				Settings.level3CollectedCheeses=mouse.getCollectedCheeses();
			if (Settings.level3KilledKamikazis < mouse.getKamikaziKilled())
				Settings.level3KilledKamikazis=mouse.getKamikaziKilled();
		}

		int len = touchEvents.size();
		for (int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if (event.type == TouchEvent.TOUCH_DOWN) {
				if (inBounds(event, 0, 0, 800, 480)) {
					nullify();
					game.setScreen(new LevelSelectorScreen(game));
					return;
				}
			}
		}

	}
	//create the level
	private void updateTiles() {

		for (int i = 0; i < tilearray.size(); i++) {
			Tile t = (Tile) tilearray.get(i);
			t.update();
		}

	}

	//show the images to the screen
	@Override
	public void paint(float deltaTime) {
		Graphics g = game.getGraphics();

		g.drawImage(Assets.background, bg1.getBgX(), bg1.getBgY());
		g.drawImage(Assets.background, bg2.getBgX(), bg2.getBgY());
		paintTiles(g);

		ArrayList projectiles = mouse.getProjectiles();
		for (int i = 0; i < projectiles.size(); i++) {
			Projectile p = (Projectile) projectiles.get(i);
			g.drawRect(p.getX(), p.getY(), 10, 5, Color.YELLOW);
		}
		// First draw the game elements based on their center x,y

		g.drawImage(currentSprite, mouse.getCenterX() - 48,
				mouse.getCenterY() - 64);

		//sign
		if (si.getColleceted()==false){
		g.drawImage(sanim.getImage(), si.getCenterX() - 16,
				si.getCenterY() - 16);
		}
		//cheeses
		if (ch.getColleceted()==false){
		g.drawImage(canim.getImage(), ch.getCenterX() - 16,
				ch.getCenterY() - 16);
		}
		if (ch2.getColleceted()==false){
		g.drawImage(canim.getImage(), ch2.getCenterX() - 16,
				ch2.getCenterY() - 16);
		}
		if (ch3.getColleceted()==false){
		g.drawImage(canim.getImage(), ch3.getCenterX() - 16,
				ch3.getCenterY() - 16);
		}
		if (ch4.getColleceted()==false){
		g.drawImage(canim.getImage(), ch4.getCenterX() - 16,
				ch4.getCenterY() - 16);
		}
		if (ch5.getColleceted()==false){
		g.drawImage(canim.getImage(), ch5.getCenterX() - 16,
				ch5.getCenterY() - 16);
		}
		if (ch6.getColleceted()==false){
		g.drawImage(canim.getImage(), ch6.getCenterX() - 16,
				ch6.getCenterY() - 16);
		}
		if (ch7.getColleceted()==false){
		g.drawImage(canim.getImage(), ch7.getCenterX() - 16,
				ch7.getCenterY() - 16);
		}
		if (ch8.getColleceted()==false){
		g.drawImage(canim.getImage(), ch8.getCenterX() - 16,
				ch8.getCenterY() - 16);
		}

		//bombs
		if (bo.getHealth()!=0){
		g.drawImage(banim.getImage(), bo.getCenterX() - 16,
				bo.getCenterY() - 16);
		}
		if (bo2.getHealth()!=0){
		g.drawImage(banim.getImage(), bo2.getCenterX() - 16,
				bo2.getCenterY() - 16);
		}
		if (bo3.getHealth()!=0){
		g.drawImage(banim.getImage(), bo3.getCenterX() - 16,
				bo3.getCenterY() - 16);
		}
		if (bo4.getHealth()!=0){
		g.drawImage(banim.getImage(), bo4.getCenterX() - 16,
				bo4.getCenterY() - 16);
		}
		if (bo5.getHealth()!=0){
		g.drawImage(banim.getImage(), bo5.getCenterX() - 16,
				bo5.getCenterY() - 16);
		}
		if (bo6.getHealth()!=0){
		g.drawImage(banim.getImage(), bo6.getCenterX() - 16,
				bo6.getCenterY() - 16);
		}
		if (bo7.getHealth()!=0){
		g.drawImage(banim.getImage(), bo7.getCenterX() - 16,
				bo7.getCenterY() - 16);
		}
		if (bo8.getHealth()!=0){
		g.drawImage(banim.getImage(), bo8.getCenterX() - 16,
				bo8.getCenterY() - 16);
		}
		if (bo9.getHealth()!=0){
		g.drawImage(banim.getImage(), bo9.getCenterX() - 16,
				bo9.getCenterY() - 16);
		}

		//kamikazi
		if (hb.getHealth()!=0){
			g.drawString(String.valueOf(hb.health), hb.getCenterX(), hb.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb.getCenterX() - 48,
					hb.getCenterY() - 64);
		}
		if (hb2.getHealth()!=0){
			g.drawString(String.valueOf(hb2.health), hb2.getCenterX(), hb2.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb2.getCenterX() - 48,
					hb2.getCenterY() - 64);
		}
		if (hb3.getHealth()!=0){
			g.drawString(String.valueOf(hb3.health), hb3.getCenterX(), hb3.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb3.getCenterX() - 48,
					hb3.getCenterY() - 64);
		}
		if (hb4.getHealth()!=0){
			g.drawString(String.valueOf(hb4.health), hb4.getCenterX(), hb4.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb4.getCenterX() - 48,
					hb4.getCenterY() - 64);
		}
		if (hb5.getHealth()!=0){
			g.drawString(String.valueOf(hb5.health), hb5.getCenterX(), hb5.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb5.getCenterX() - 48,
					hb5.getCenterY() - 64);
		}
		if (hb6.getHealth()!=0){
			g.drawString(String.valueOf(hb6.health), hb6.getCenterX(), hb6.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb6.getCenterX() - 48,
					hb6.getCenterY() - 64);
		}
		if (hb7.getHealth()!=0){
			g.drawString(String.valueOf(hb7.health), hb7.getCenterX(), hb7.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb7.getCenterX() - 48,
					hb7.getCenterY() - 64);
		}
		if (hb8.getHealth()!=0){
			g.drawString(String.valueOf(hb8.health), hb8.getCenterX(), hb8.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb8.getCenterX() - 48,
					hb8.getCenterY() - 64);
		}
		if (hb9.getHealth()!=0){
			g.drawString(String.valueOf(hb9.health), hb9.getCenterX(), hb9.getCenterY()-48, paint);
			g.drawImage(hanim.getImage(), hb9.getCenterX() - 48,
					hb9.getCenterY() - 64);
		}
		//ui elements
		if (state == GameState.Ready)
			drawReadyUI();
		if (state == GameState.Running)
			drawRunningUI();
		if (state == GameState.Paused)
			drawPausedUI();
		if (state == GameState.GameOver)
			drawGameOverUI();
		if (state == GameState.LevelIsPassed)
			drawLevelIsPassedUI();

	}

	//show images
	private void paintTiles(Graphics g) {
		for (int i = 0; i < tilearray.size(); i++) {
			Tile t = (Tile) tilearray.get(i);
			if (t.type != 0) {
				g.drawImage(t.getTileImage(), t.getTileX(), t.getTileY());
			}
		}
	}

	//make the animations
	public void animate() {
		anim.update(10);
		hanim.update(50);
		banim.update(100);
	}

	// 	set all variables to be null and recreate them in the constructor
	//	it used when we quit from the level to free up memory
	private void nullify() {

		paint = null;
		bg1 = null;
		bg2 = null;
		mouse = null;

		hb = null;
		hb2 = null;
		hb3 = null;
		hb4 = null;
		hb5 = null;
		hb6 = null;
		hb7 = null;
		hb8 = null;
		hb9 = null;

		ch = null;
		ch2 = null;
		ch3 = null;
		ch4 = null;
		ch5 = null;
		ch6 = null;
		ch7 = null;
		ch8 = null;

		currentSprite = null;
		character = null;
		character2 = null;
		character3 = null;
		Kamikazi = null;
		Kamikazi2 = null;
		Kamikazi3 = null;
		Kamikazi4 = null;
		Kamikazi5 = null;
		anim = null;
		hanim = null;
		banim = null;

		//call the garbage collector, we need to free up the memory
		System.gc();

	}

	//show read to play screen
	private void drawReadyUI() {
		Graphics g = game.getGraphics();

		g.drawARGB(155, 0, 0, 0);
		g.drawString("Touch to Start !", 400, 240, paint);

	}

	//show some important information while in running state
	private void drawRunningUI() {
		Graphics g = game.getGraphics();

		//draw health of mob1
		g.drawString("Health: "+String.valueOf(mouse.getHealth()), 704, 64, paint);
		g.drawString("Killed: "+String.valueOf(mouse.getKamikaziKilled()), 704, 96, paint);
		g.drawString("Cheeses: "+String.valueOf(mouse.getCollectedCheeses()), 704, 128, paint);

		//info at the screen
		g.drawString("Level: "+String.valueOf(Settings.currentLevel), 196, 64, paint);

		g.drawImage(Assets.pause_button, 16, 16, 0, 0, 96, 96);

		if (!Settings.gyroscopeEnabled){//if gyroscope is on, we dont need the control arrows
		g.drawImage(Assets.arrow_buttons,  16, 368, 0, 0, 96, 96);
		g.drawImage(Assets.arrow_buttons,  112, 368, 0, 96, 96, 96);
		}

		g.drawImage(Assets.control_buttons,  592, 368, 0, 0, 96, 96);
		g.drawImage(Assets.control_buttons,  688, 368, 0, 96, 96, 96);
	}

	//show paused screen
	private void drawPausedUI() {
		Graphics g = game.getGraphics();
		//make more dark the screen
		g.drawARGB(155, 0, 0, 0);
		g.drawImage(Assets.menu_buttons,  224, 128, 0, 128, 352, 256);//play button (show the 2/3 of image)

	}
	int gameOverCounter=0;
	//show game over user interface/screen
	private void drawGameOverUI() {
		Graphics g = game.getGraphics();
		g.drawRect(0, 0, 1281, 801, Color.BLACK);

		if ((Settings.soundEnabled) && (gameOverCounter==0))
		{
			Assets.gameover.play(1);
			gameOverCounter++;
		}
		g.drawString("[Game Over]", 400, 240, paint2);
		g.drawString("Touch to return to game", 400, 290, paint);

	}

	//show game is passed user interface/screen
	int levelPassedCounter=0;
	private void drawLevelIsPassedUI() {
		Graphics g = game.getGraphics();
		g.drawRect(0, 0, 1281, 801, Color.BLACK);

		if ((Settings.soundEnabled) && (levelPassedCounter==0))
		{
			Assets.passed.play(1);
			levelPassedCounter++;
		}
		g.drawString("Level "+Settings.currentLevel+" Passed!", 400, 240, paint2);
		g.drawString("Touch to select next Level", 400, 290, paint);

	}
	@Override
	public void pause() {
		if (state == GameState.Running)
			state = GameState.Paused;

	}

	@Override
	public void resume() {
		if (state == GameState.Paused)
			state = GameState.Running;
	}

	@Override
	public void dispose() {

	}

	@Override
	public void backButton() {
		pause();
	}

	private void goToMenu() {
		// TODO Auto-generated method stub
		game.setScreen(new MainMenuScreen(game));

	}

	public static Background getBg1() {
		// TODO Auto-generated method stub
		return bg1;
	}

	public static Background getBg2() {
		// TODO Auto-generated method stub
		return bg2;
	}

	public static Mouse getMouse() {
		// TODO Auto-generated method stub
		return mouse;
	}

}


text:
use constant RLM_MODULE_OK=>2;
use constant RLM_MODULE_UPDATED=>8;
use constant RLM_MODULE_REJECT=>0;
use constant RLM_MODULE_NOOP=>7;
use Number::Bytes::Human qw(format_bytes);
use MIME::Lite;
use POSIX qw(ceil);
use DBI;
use DateTime;

my @warnings = (0,50,80,100);
my $used_pct = 0;
my $email;
my $user;
my $sentmail;
#my $reset_date;
my $used_data;
my $total_data;

#testing
use constant USED=>19000999997;
use constant TOTAL=>19590999997;
my $used_pct  = ceil(USED/TOTAL*100);
my $email = 'zhex900@gmail.com';
my $user = ucfirst('jake');
my $sentmail = 50;
my $reset_date = nextresetdate(4);
my $used_data = format_bytes(USED);
my $total_data = format_bytes(TOTAL);

# MySQL database configurations
my $dsn = "DBI:mysql:owums_db";
my $dbusername = "owums_db";
my $dbpassword = "fheman";

#testing
authorize();

sub authorize {

   # $used_pct
#	= ceil(eval{$RAD_CHECK{'Used-Bytes'}/$RAD_CHECK{'Total-Bytes'}}*100);
#    $email = $RAD_CHECK{'Email'};
 #   $user = ucfirst($RAD_REQUEST{'User-Name'});
  #  $sentmail = $RAD_CHECK{'Sent-Mail'};
   # #$reset_date = nextresetdate($RAD_CHECK{'Reset-Date'});
   # $used_data = format_bytes($RAD_CHECK{'Used-Bytes'});
   # $total_data = format_bytes($RAD_CHECK{'Total-Bytes'});

    #Send warning emails
   print "Try to send warning email\n";
   email_warning();
   # $RAD_CHECK{'Email'}=$used_pct;
    return RLM_MODULE_NOOP;
}

sub email_warning{
    #initial value
    local $range = -1;
    local @w = @warnings;

    #find the range of the current usage.
    for($i=0;$i<@w;++$i) {
	#reset mail marker
	#the first range must be always have sent mail as zero.
	if( $used_pct >= $w[0] && $used_pct < $w[1] && $sentmail != 0 ){
	    #resets the sent mail marker
	    $range = 0;
	    last;
	}
	#Greater or equal to the last range.
	elsif ( $used_pct >= $w[$n-1] && $sentmail != $w[$n-1] ){
	    #make sure the user have no more data left.
	    if ( $RAD_CHECK{'Used-Bytes'} >= $RAD_CHECK{'Total-Bytes'} ){
		#debug print
		print $used_pct . " is range" .
		    "(" . $w[$n-1]. "-". $w[$n-1].")\n";
		$range = $w[$n-1];
	    }
	    last;
	}
	elsif ( $used_pct >= $w[$i] && $used_pct < $w[add($i,$n)]
		&& $sentmail != $w[$i]){
	    #debug print
	    print "mail marker:(".$sentmail . ") " .$used_pct . "% is range" .
		"(" . $w[$i]. "-". $w[add($i,$n)].")\n";
	    $range = $w[$i];
	    last;
	}
	else{#do nothing;
	}
    }

print "range: $range\n";
    #Send mail with range that is not the initial value
    if( $range != -1 ){
	#send mail to non zero range
	#range zero only need to be reset. No mail is nees to be sent

	if ($range !=  0){
	    mysendmail();
	}
	#set sent mail marker
	print "call mailmarker ($range)";
mysendmail();
mysendmail();
mysendmail();
mysendmail();
mysendmail();
mailmarker($range);
    }
}

#
#To avoid sending the multiple warning mails. A marker 'sentmail' is used in
#the users table in radius database. sentmail records the warning mails that
#has been sent in a range. For example, if a warning email that was sent at the
#range of 80%, sentmail's value will be 80.
#
sub mailmarker{
    #get first parameter
    my $range = shift;
    # connect to MySQL database
    my %attr = ( PrintError=>0, RaiseError=>1);
    my $dbh = DBI->connect($dsn,$dbusername,$dbpassword, \%attr);
    #update statement
    my $sql = "UPDATE `users` SET `sentmail`=$range " .
	"WHERE `username`=lower('$user');";
    $dbh->do($sql);
    $dbh->disconnect;
}

#send warning mail
sub mysendmail{
	print ("generating email\n");
    #work out the number of days until the next reset
    my $today = DateTime->now(time_zone=>'local');
    my $reset_date = nextresetdate(5); #$RAD_CHECK{'Reset-Date'});
    my $remaining = $today->delta_days($reset_date)->in_units('days');
    $reset_date = $reset_date->dmy;
    my $msg = qq{
Hi $user,

This is just a friendly note to let you know that you\'ve used
$used_data ($used_pct%) of your monthly quota of $total_data.
You quota resets in $remaining day(s), just after midnight on:
$reset_date.

To check your current usage please go to
toolbox.

Much grace to you!

Jake He
};

local $subject = "$used_pct% Quota! Resets on $reset_date";

    my $mime = MIME::Lite->new(
    'From'    => $email,
    'To'      => $email,
    'Subject' => $subject,
    'Type'    => 'text/html',
    'Data'    => $msg,
	);
print $subject;
    chomp($d = `sh ./check_duplicates.sh $email "$subject"`);
    print "check: $d\n";
    if ($d eq "true") {
	print "SKIP mail!\n";
    }else{
      	print "Send mail\n";
        $mime->send() or die "Failed to send mail\n";
    }
}

#helper function
sub add{
    ($i, $m) = @_;
    if ($i==$m-1){
	return $i;
    }else{
	return $i+1;
    }
}

#this is to avoid illegal division by zero error
sub divide{
    my ( $divided, $divisor ) = @_;
    if ( $divisor != 0 ){
	return $divided/$divisor;
    }
    else{
	return 0;
    }
}

#give a date find the next month.
sub nextresetdate{

    my $reset_date = $_[0];
    # current date
    my $today = DateTime->now(time_zone=>'local');

    #if current date is ahead of the reset date
    #set the month as next month
    if ( $today->day() >= $reset_date ){
        $today->add(months=>+1);
        $today->set_day($reset_date);
    }
    else{
        $today->set_day($reset_date);
    }
    return $today;
}


text:
package com.facebook.buck.android;

import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.rules.AbstractCachingBuildRule;
import com.facebook.buck.rules.AbstractCachingBuildRuleBuilder;
import com.facebook.buck.rules.ArtifactCache;
import com.facebook.buck.rules.BuildContext;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleType;
import com.facebook.buck.rules.CachingBuildRuleParams;
import com.facebook.buck.rules.RuleKey;
import com.facebook.buck.rules.SrcsAttributeBuilder;
import com.facebook.buck.step.Step;
import com.facebook.buck.util.BuckConstant;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * An object that represents a collection of Android NDK source code.
 *

 * Suppose this were a rule defined in src/com/facebook/feed/jni/BUCK:
 *

 * ndk_library(
 *   name = 'feed-jni',
 *   deps = [],
 *   flags = ["NDK_DEBUG=1", "V=1"],
 * )
 *

 */
public class NdkLibraryRule extends AbstractCachingBuildRule {

  /** The directory containing the Android.mk file to use. This value includes a trailing slash. */
  private final String makefileDirectory;

  private final String buildArtifactsDirectory;
  private final ImmutableSortedSet<String> sources;
  private final ImmutableList<String> flags;

  protected NdkLibraryRule(
      CachingBuildRuleParams cachingBuildRuleParams,
      Set<String> sources,
      List<String> flags) {
    super(cachingBuildRuleParams);
    Preconditions.checkArgument(!sources.isEmpty(),
        "Must include at least one file (Android.mk?) in ndk_library rule");
    this.sources = ImmutableSortedSet.copyOf(sources);

    String basePathWithSlash = cachingBuildRuleParams.getBuildTarget().getBasePathWithSlash();
    Preconditions.checkArgument(basePathWithSlash.endsWith("/"));
    this.makefileDirectory = basePathWithSlash;
    this.buildArtifactsDirectory =
        String.format("%s/%s", BuckConstant.GEN_DIR, basePathWithSlash);
    this.flags = ImmutableList.copyOf(flags);
  }

  @Override
  public BuildRuleType getType() {
    return BuildRuleType.NDK_LIBRARY;
  }

  @Override
  public boolean isAndroidRule() {
    return true;
  }

  @Override
  protected RuleKey.Builder ruleKeyBuilder() {
    return super.ruleKeyBuilder()
        .set("makefileDirectory", makefileDirectory)
        .set("buildArtifactsDirectory", buildArtifactsDirectory)
        .set("sources", sources)
        .set("flags", flags);
  }

  /**
   * The directory containing all shared objects built by this rule. This
   * value does *not* include a trailing slash.
   */
  public String getLibraryPath() {
    return this.buildArtifactsDirectory + "libs";
  }

  @Override
  protected Iterable<String> getInputsToCompareToOutput(BuildContext context) {
    return this.sources;
  }

  @Override
  protected List<Step> buildInternal(BuildContext context) throws IOException {
    return ImmutableList.of((Step)new NdkBuildStep(
        this.makefileDirectory,
        this.buildArtifactsDirectory,
        this.flags));
  }

  public static Builder newNdkLibraryRuleBuilder() {
    return new Builder();
  }

  public static class Builder extends AbstractCachingBuildRuleBuilder implements
      SrcsAttributeBuilder {
    private Set<String> sources = Sets.newHashSet();
    private ImmutableList.Builder<String> flags = ImmutableList.builder();

    private Builder() {}

    @Override
    public NdkLibraryRule build(Map<String, BuildRule> buildRuleIndex) {
      return new NdkLibraryRule(
          createCachingBuildRuleParams(buildRuleIndex),
          sources,
          flags.build());
    }

    @Override
    public Builder setBuildTarget(BuildTarget buildTarget) {
      super.setBuildTarget(buildTarget);
      return this;
    }

    @Override
    public Builder addVisibilityPattern(BuildTargetPattern visibilityPattern) {
      super.addVisibilityPattern(visibilityPattern);
      return this;
    }

    @Override
    public Builder addSrc(String source) {
      this.sources.add(source);
      return this;
    }

    @Override
    public Builder setArtifactCache(ArtifactCache artifactCache) {
      super.setArtifactCache(artifactCache);
      return this;
    }

    public Builder addFlag(String flag) {
      this.flags.add(flag);
      return this;
    }
  }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<ti:module xmlns:ti="http://ti.appcelerator.org" xmlns:android="http://schemas.android.com/apk/res/android">
	<android xmlns:android="http://schemas.android.com/apk/res/android">
		<manifest>
			<uses-sdk android:minSdkVersion="8" />
			<application>
				<!-- begin gcm.js module -->
				<receiver android:name="net.iamyellow.gcmjs.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
					<intent-filter>
						<action android:name="com.google.android.c2dm.intent.RECEIVE" />
						<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
						<category android:name="${tiapp.properties['id']}" />
					</intent-filter>
				</receiver>
				<service android:name="net.iamyellow.gcmjs.GCMIntentService" />
				<service android:name="net.iamyellow.gcmjs.GcmjsService"/>
				<activity android:name="net.iamyellow.gcmjs.GcmjsActivity" android:noHistory="true" android:theme="@style/Theme.Titanium">
					<intent-filter>
						<action android:name="android.intent.action.VIEW"/>
						<category android:name="android.intent.category.DEFAULT"/>
						<category android:name="android.intent.category.BROWSABLE"/>
					</intent-filter>
				</activity>
			</application>

			<!-- begin gcm.js module -->
			<permission android:name="${tiapp.properties['id']}.permission.C2D_MESSAGE" android:protectionLevel="signature" />
			<uses-permission android:name="${tiapp.properties['id']}.permission.C2D_MESSAGE" />
			<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
			<uses-permission android:name="android.permission.INTERNET" />
			<uses-permission android:name="android.permission.GET_ACCOUNTS" />
			<uses-permission android:name="android.permission.WAKE_LOCK" />
			<!-- end gcm.js module -->
		</manifest>
	</android>
</ti:module>


text:
package org.elasticsearch.index.analysis.compound;

import org.apache.lucene.analysis.compound.CompoundWordTokenFilterBase;
import org.apache.lucene.analysis.util.CharArraySet;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.inject.assistedinject.Assisted;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.analysis.AbstractTokenFilterFactory;
import org.elasticsearch.index.analysis.Analysis;
import org.elasticsearch.index.settings.IndexSettings;

/**
 * Contains the common configuration settings between subclasses of this class.
 */
public abstract class AbstractCompoundWordTokenFilterFactory extends AbstractTokenFilterFactory {

    protected final int minWordSize;
    protected final int minSubwordSize;
    protected final int maxSubwordSize;
    protected final boolean onlyLongestMatch;
    protected final CharArraySet wordList;

    @Inject
    public AbstractCompoundWordTokenFilterFactory(Index index, @IndexSettings Settings indexSettings, Environment env, @Assisted String name, @Assisted Settings settings) {
        super(index, indexSettings, name, settings);

        minWordSize = settings.getAsInt("min_word_size", CompoundWordTokenFilterBase.DEFAULT_MIN_WORD_SIZE);
        minSubwordSize = settings.getAsInt("min_subword_size", CompoundWordTokenFilterBase.DEFAULT_MIN_SUBWORD_SIZE);
        maxSubwordSize = settings.getAsInt("max_subword_size", CompoundWordTokenFilterBase.DEFAULT_MAX_SUBWORD_SIZE);
        onlyLongestMatch = settings.getAsBoolean("only_longest_match", false);
        wordList = Analysis.getWordSet(env, settings, "word_list", version);
        if (wordList == null) {
            throw new ElasticsearchIllegalArgumentException("word_list must be provided for [" + name + "], either as a path to a file, or directly");
        }
    }
}