<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def addcols(X, cols, names=None):
 """ Add one or more columns to a numpy ndarray. Technical dependency of :func:`tabular.spreadsheet.aggregate_in`. Implemented by the tabarray method :func:`tabular.tab.tabarray.addcols`. **Parameters** **X** : numpy ndarray with structured dtype or recarray The recarray to add columns to. **cols** : numpy ndarray, or list of arrays of columns Column(s) to add. **names**: list of strings, optional Names of the new columns. Only applicable when `cols` is a list of arrays. **Returns** **out** : numpy ndarray with structured dtype New numpy array made up of `X` plus the new columns. **See also:** :func:`tabular.spreadsheet.colstack` """


    if isinstance(names,str):
        names = [n.strip() for n in names.split(',')]

    if isinstance(cols, list):
        if any([isinstance(x,np.ndarray) or isinstance(x,list) or \
                                     isinstance(x,tuple) for x in cols]):
            assert all([len(x) == len(X) for x in cols]), \
                   'Trying to add columns of wrong length.'
            assert names != None and len(cols) == len(names), \
                   'Number of columns to add must equal number of new names.'
            cols = utils.fromarrays(cols,type=np.ndarray,names = names)
        else:
            assert len(cols) == len(X), 'Trying to add column of wrong length.'
            cols = utils.fromarrays([cols], type=np.ndarray,names=names)
    else:
        assert isinstance(cols, np.ndarray)
        if cols.dtype.names == None:
            cols = utils.fromarrays([cols],type=np.ndarray, names=names)

    Replacements = [a for a in cols.dtype.names if a in X.dtype.names]
    if len(Replacements) > 0:
        print('Replacing columns', 
              [a for a in cols.dtype.names if a in X.dtype.names])

    return utils.fromarrays(
      [X[a] if a not in cols.dtype.names else cols[a] for a in X.dtype.names] + 
      [cols[a] for a in cols.dtype.names if a not in X.dtype.names], 
      type=np.ndarray,
      names=list(X.dtype.names) + [a for a in cols.dtype.names 
                                   if a not in X.dtype.names])