<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def cs_axis_mapping(cls, part_info, # type: Dict[str, Optional[Sequence]] axes_to_move # type: Sequence[str] ):
 """Given the motor infos for the parts, filter those with scannable names in axes_to_move, check they are all in the same CS, and return the cs_port and mapping of cs_axis to MotorInfo"""

        cs_ports = set()  # type: Set[str]
        axis_mapping = {}  # type: Dict[str, MotorInfo]
        for motor_info in cls.filter_values(part_info):
            if motor_info.scannable in axes_to_move:
                assert motor_info.cs_axis in cs_axis_names, \
                    "Can only scan 1-1 mappings, %r is %r" % \
                    (motor_info.scannable, motor_info.cs_axis)
                cs_ports.add(motor_info.cs_port)
                axis_mapping[motor_info.scannable] = motor_info
        missing = list(set(axes_to_move) - set(axis_mapping))
        assert not missing, \
            "Some scannables %s are not in the CS mapping %s" % (
                missing, axis_mapping)
        assert len(cs_ports) == 1, \
            "Requested axes %s are in multiple CS numbers %s" % (
                axes_to_move, list(cs_ports))
        cs_axis_counts = Counter([x.cs_axis for x in axis_mapping.values()])
        # Any cs_axis defs that are used for more that one raw motor
        overlap = [k for k, v in cs_axis_counts.items() if v > 1]
        assert not overlap, \
            "CS axis defs %s have more that one raw motor attached" % overlap
        return cs_ports.pop(), axis_mapping