<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def liftover(args):
 """ %prog liftover old.vcf hg19ToHg38.over.chain.gz new.vcf Lift over coordinates in vcf file. """

    p = OptionParser(liftover.__doc__)
    p.add_option("--newid", default=False, action="store_true",
                 help="Make new identifiers")
    opts, args = p.parse_args(args)

    if len(args) != 3:
        sys.exit(not p.print_help())

    oldvcf, chainfile, newvcf = args
    ul = UniqueLiftover(chainfile)
    num_excluded = 0
    fp = open(oldvcf)
    fw = open(newvcf, "w")
    for row in fp:
        row = row.strip()
        if row[0] == '#':
            if row.startswith("##source="):
                row = "##source={0}".format(__file__)
            elif row.startswith("##reference="):
                row = "##reference=hg38"
            elif row.startswith("##contig="):
                continue
            print(row.strip(), file=fw)
            continue

        v = VcfLine(row)
        # GRCh37.p2 has the same MT sequence as hg38 (but hg19 is different)
        if v.seqid == "MT":
            v.seqid = "chrM"
            print(v, file=fw)
            continue

        try:
            new_chrom, new_pos = ul.liftover_cpra(CM[v.seqid], v.pos)
        except:
            num_excluded +=1
            continue

        if new_chrom != None and new_pos != None:
            v.seqid, v.pos = new_chrom, new_pos
            if opts.newid:
                v.rsid = "{0}:{1}".format(new_chrom.replace("chr", ""), new_pos)
            print(v, file=fw)
        else:
            num_excluded +=1

    logging.debug("Excluded {0}".format(num_excluded))