<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def id_nameDAVID(df,GTF=None,name_id=None):
 """ Given a DAVIDenrich output it converts ensembl gene ids to genes names and adds this column to the output :param df: a dataframe output from DAVIDenrich :param GTF: a GTF dataframe from readGTF() :param name_id: instead of a gtf dataframe a dataframe with the columns 'gene_name' and 'gene_id' can be given as input :returns: a pandas dataframe with a gene name column added to it. """

    if name_id is None:
        gene_name=retrieve_GTF_field('gene_name',GTF)
        gene_id=retrieve_GTF_field('gene_id', GTF)
        GTF=pd.concat([gene_name,gene_id],axis=1)
    else:
        GTF=name_id.copy()
    df['Gene_names']="genes"
    terms=df['termName'].tolist()
    enrichN=pd.DataFrame()
    for term in terms:
        tmp=df[df['termName']==term]
        tmp=tmp.reset_index(drop=True)
        ids=tmp.xs(0)['geneIds']
        ids=pd.DataFrame(data=ids.split(", "))
        ids.columns=['geneIds']
        ids['geneIds']=ids['geneIds'].map(str.lower)
        GTF['gene_id']=GTF['gene_id'].astype(str)
        GTF['gene_id']=GTF['gene_id'].map(str.lower)
        ids=pd.merge(ids, GTF, how='left', left_on='geneIds', right_on='gene_id')
        names=ids['gene_name'].tolist()
        names= ', '.join(names)
        tmp["Gene_names"]=names
        #tmp=tmp.replace(to_replace=tmp.xs(0)['Gene_names'], value=names)
        enrichN=pd.concat([enrichN, tmp])
    enrichN=enrichN.reset_index(drop=True)

    gene_names=enrichN[['Gene_names']]
    gpos=enrichN.columns.get_loc("geneIds")
    enrichN=enrichN.drop(['Gene_names'],axis=1)
    cols=enrichN.columns.tolist()
    enrichN=pd.concat([enrichN[cols[:gpos+1]],gene_names,enrichN[cols[gpos+1:]]],axis=1)

    return enrichN