<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def frombinary(path, ext='bin', conf='conf.json', dtype=None, shape=None, skip=0, index=None, labels=None, engine=None, credentials=None):
 """ Load series data from flat binary files. Parameters path : string URI or local filesystem path Directory to load from, can be a URI string with scheme (e.g. 'file://', 's3n://', or 'gs://'), or a single file, or a directory, or a directory with a single wildcard character. ext : str, optional, default = 'bin' Optional file extension specifier. conf : str, optional, default = 'conf.json' Name of conf file with type and size information. dtype : dtype or dtype specifier, default 'float64' Numerical type to use for data after converting from text. shape : tuple or list, optional, default = None Shape of data if known, will be inferred otherwise. skip : int, optional, default = 0 Number of items in each record to skip. index : array, optional, default = None labels : array, optional, default = None Labels for records. If provided, should have shape of shape[:-1]. engine : object, default = None Computational engine (e.g. a SparkContext for Spark) credentials : dict, default = None Credentials for remote storage (e.g. S3) in the form {access: ***, secret: ***} """

    shape, dtype = _binaryconfig(path, conf, dtype, shape, credentials)

    from thunder.readers import normalize_scheme, get_parallel_reader
    path = normalize_scheme(path, ext)

    from numpy import dtype as dtype_func
    nelements = shape[-1] + skip
    recordsize = dtype_func(dtype).itemsize * nelements

    if spark and isinstance(engine, spark):
        lines = engine.binaryRecords(path, recordsize)
        raw = lines.map(lambda x: frombuffer(buffer(x), offset=0, count=nelements, dtype=dtype)[skip:])

        def switch(record):
            ary, idx = record
            return (idx,), ary

        rdd = raw.zipWithIndex().map(switch)

        if shape and len(shape) > 2:
            expand = lambda k: unravel_index(k[0], shape[0:-1])
            rdd = rdd.map(lambda kv: (expand(kv[0]), kv[1]))

        if not index:
            index = arange(shape[-1])

        return fromrdd(rdd, dtype=dtype, shape=shape, index=index, ordered=True)

    else:
        reader = get_parallel_reader(path)(engine, credentials=credentials)
        data = reader.read(path, ext=ext)

        values = []
        for record in data:
            buf = record[1]
            offset = 0
            while offset < len(buf):
                v = frombuffer(buffer(buf), offset=offset, count=nelements, dtype=dtype)
                values.append(v[skip:])
                offset += recordsize

        if not len(values) == prod(shape[0:-1]):
            raise ValueError('Unexpected shape, got %g records but expected %g'
                             % (len(values), prod(shape[0:-1])))

        values = asarray(values, dtype=dtype)

        if shape:
            values = values.reshape(shape)

        return fromarray(values, index=index, labels=labels)