Groups the given columns by the corresponding grouping column
    value, and aggregate by summing values.

    Args:
        columns (List<WeldObject>): List of columns as WeldObjects
        column_tys (List<str>): List of each column data ty
        grouping_column (WeldObject): Column to group rest of columns by

    Returns:
          A WeldObject representing this computation

def groupby_sort(columns, column_tys, grouping_columns, grouping_column_tys, key_index, ascending):
    """
    Groups the given columns by the corresponding grouping column
    value, and aggregate by summing values.

    Args:
        columns (List<WeldObject>): List of columns as WeldObjects
        column_tys (List<str>): List of each column data ty
        grouping_column (WeldObject): Column to group rest of columns by

    Returns:
          A WeldObject representing this computation
    """
    weld_obj = WeldObject(encoder_, decoder_)
    if len(grouping_columns) == 1 and len(grouping_column_tys) == 1:
        grouping_column_var = weld_obj.update(grouping_columns[0])
        if isinstance(grouping_columns[0], WeldObject):
            grouping_column_var = grouping_columns[0].weld_code
        grouping_column_ty_str = "%s" % grouping_column_tys[0]
    else:
        grouping_column_vars = []
        for column in grouping_columns:
            column_var = weld_obj.update(column)
            if isinstance(column, WeldObject):
                column_var = column.obj_id
                weld_obj.dependencies[column_var] = column
            grouping_column_vars.append(column_var)
        grouping_column_var = ", ".join(grouping_column_vars)
        grouping_column_tys = [str(ty) for ty in grouping_column_tys]
        grouping_column_ty_str = ", ".join(grouping_column_tys)
        grouping_column_ty_str = "{%s}" % grouping_column_ty_str

    columns_var_list = []
    for column in columns:
        column_var = weld_obj.update(column)
        if isinstance(column, WeldObject):
            column_var = column.obj_id
            weld_obj.dependencies[column_var] = column
        columns_var_list.append(column_var)

    if len(columns_var_list) == 1 and len(grouping_columns) == 1:
        columns_var = columns_var_list[0]
        tys_str = column_tys[0]
        result_str = "merge(b, e)"
    elif len(columns_var_list) == 1 and len(grouping_columns) > 1:
        columns_var = columns_var_list[0]
        tys_str = column_tys[0]
        key_str_list = []
        for i in xrange(0, len(grouping_columns)):
            key_str_list.append("e.$%d" % i)
        key_str = "{%s}" % ", ".join(key_str_list)
        value_str = "e.$" + str(len(grouping_columns))
        result_str_list = [key_str, value_str]
        result_str = "merge(b, {%s})" % ", ".join(result_str_list)
    elif len(columns_var_list) > 1 and len(grouping_columns) == 1:
        columns_var = "%s" % ", ".join(columns_var_list)
        column_tys = [str(ty) for ty in column_tys]
        tys_str = "{%s}" % ", ".join(column_tys)
        key_str = "e.$0"
        value_str_list = []
        for i in xrange(1, len(columns) + 1):
            value_str_list.append("e.$%d" % i)
        value_str = "{%s}" % ", ".join(value_str_list)
        result_str_list = [key_str, value_str]
        result_str = "merge(b, {%s})" % ", ".join(result_str_list)
    else:
        columns_var = "%s" % ", ".join(columns_var_list)
        column_tys = [str(ty) for ty in column_tys]
        tys_str = "{%s}" % ", ".join(column_tys)
        key_str_list = []
        key_size = len(grouping_columns)
        value_size = len(columns)
        for i in xrange(0, key_size):
            key_str_list.append("e.$%d" % i)
        key_str = "{%s}" % ", ".join(key_str_list)
        value_str_list = []
        for i in xrange(key_size, key_size + value_size):
            value_str_list.append("e.$%d" % i)
        value_str = "{%s}" % ", ".join(value_str_list)
        result_str_list = [key_str, value_str]
        result_str = "merge(b, {%s})" % ", ".join(result_str_list)

    if key_index == None:
        key_str_x = "x"
        key_str_y = "y"
    else :
        key_str_x = "x.$%d" % key_index
        key_str_y = "y.$%d" % key_index

    if ascending == False:
        key_str = key_str + "* %s(-1)" % column_tys[key_index]

    weld_template = """
    @(grain_size:1)map(
     tovec(
       result(
         for(
           zip(%(grouping_column)s, %(columns)s),
           groupmerger[%(gty)s, %(ty)s],
           |b, i, e| %(result)s
         )
       )
     ),
    |a:{%(gty)s, vec[%(ty)s]}| {a.$0, sort(a.$1, |x:%(ty)s, y:%(ty)s| compare(%(key_str_x)s, %(key_str_y)s))}
    )
  """

    weld_obj.weld_code = weld_template % {"grouping_column": grouping_column_var,
                                          "columns": columns_var,
                                          "result": result_str,
                                          "ty": tys_str,
                                          "gty": grouping_column_ty_str,
                                          "key_str_x": key_str_x,
                                          "key_str_y": key_str_y}
    return weld_obj