<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def process_cgmlst_results(df):
 """Append informative fields to cgMLST330 BLAST results DataFrame The `qseqid` column must contain cgMLST330 query IDs with `{marker name}|{allele number}` format. The `qseqid` parsed allele numbers and marker names are appended as new fields. `is_perfect` column contains boolean values for whether an allele result is 100% identity and coverage. `has_perfect_match` denotes if a cgMLST330 marker has a perfect allele match. The top result with the largest bitscore for a marker with no perfect match is used to retrieve the allele present at that marker locus. Args: df (pandas.DataFrame):
 DataFrame of cgMLST330 BLAST results Returns: pandas.DataFrame: cgMLST330 BLAST results DataFrame with extra fields (`marker`, `allele`, `is_perfect`, `has_perfect_match`) """

    assert isinstance(df, pd.DataFrame)
    markers = []
    alleles = []
    for x in  df['qseqid']:
        marker, allele = x.split('|')
        markers.append(marker)
        alleles.append(int(allele))
    df.loc[:, 'marker'] = markers
    df.loc[:, 'allele'] = alleles
    df.loc[:, 'is_match'] = (df['coverage'] >= 1.0) & (df['pident'] >= 90.0) & ~(df['is_trunc'])
    df.loc[:, 'allele_name'] = df.apply(lambda x: allele_name(x.sseq.replace('-', '')), axis=1)
    df.loc[:, 'is_perfect'] = (df['coverage'] == 1.0) & (df['pident'] == 100.0)
    df_perf = df[df['is_perfect']]
    perf_markers = df_perf['marker'].unique()
    df.loc[:, 'has_perfect_match'] = df['marker'].isin(perf_markers)
    start_idxs, end_idxs, needs_revcomps, trunc, is_extended = extend_subj_match_vec(df)
    df.loc[:, 'start_idx'] = start_idxs
    df.loc[:, 'end_idx'] = end_idxs
    df.loc[:, 'needs_revcomp'] = needs_revcomps
    df.loc[:, 'trunc'] = trunc
    df.loc[:, 'is_extended'] = is_extended
    df.loc[:, 'sseq_msa_gaps'] = np.zeros(df.shape[0], dtype=np.int64)
    df.loc[:, 'sseq_msa_p_gaps'] = np.zeros(df.shape[0], dtype=np.float64)
    df.loc[:, 'too_many_gaps'] = trunc

    return df