<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def download_extract_raw_files(names: List[str], cache_dir: str, dest_dir: str):
 """ Download and extract raw files, making use of a cache directory. - Downloaded files are verified by MD5 sum. - Extraction overwrites existing files. :param names: List of raw file names in RAW_FILES. :param cache_dir: Cache directory for downloading raw files. :param dest_dir: Destination directory for extracting raw files. """


    for name in names:
        raw_file = RAW_FILES[name]
        local_dir = os.path.join(cache_dir, name)
        local_fname = os.path.join(local_dir, os.path.basename(raw_file.url))

        # Download file if not present
        if not os.path.exists(local_dir):
            logging.info("Create: %s", local_dir)
            os.makedirs(local_dir)
        if not os.path.exists(local_fname):
            logging.info("Download: %s -> %s", raw_file.url, local_fname)
            urllib.request.urlretrieve(raw_file.url, local_fname)

        # Check MD5 sum, attempt one re-download on mismatch
        md5 = md5sum(local_fname)
        if not md5 == raw_file.md5:
            logging.info("MD5 mismatch for %s, attempt re-download %s", local_fname, raw_file.url)
            urllib.request.urlretrieve(raw_file.url, local_fname)
            md5 = md5sum(local_fname)
            if not md5 == raw_file.md5:
                raise RuntimeError("MD5 mismatch for %s after re-download.  Check validity of %s"
                                   % (local_fname, raw_file.url))
        logging.info("Confirmed MD5: %s (%s)", local_fname, md5)

        # Extract file(s), overwriting directory if exists
        extract_path = os.path.join(dest_dir, name)
        if os.path.exists(extract_path):
            shutil.rmtree(extract_path)
        os.makedirs(extract_path)
        logging.info("Extract: %s -> %s", local_fname, extract_path)
        if raw_file.archive_type == ARCHIVE_NONE:
            os.symlink(local_fname, os.path.join(extract_path, os.path.basename(local_fname)))
        elif raw_file.archive_type == ARCHIVE_TAR:
            tar = tarfile.open(local_fname)
            tar.extractall(path=extract_path)
        elif raw_file.archive_type == ARCHIVE_ZIP:
            zipf = zipfile.ZipFile(local_fname, "r")
            zipf.extractall(path=extract_path)
        else:
            raise RuntimeError("Unknown archive type: %s" % raw_file.archive_type)