Coder Social home page Coder Social logo

Comments (7)

salabim avatar salabim commented on June 15, 2024

The following code is a bit more generic, and better IMHO (not fully tested by me, though).

Be sure to import collections.abc as well!

    def convert(obj):
        if isinstance(obj, complex):
            # this has to be checked before the Number check,
            # as complex is a Number
            return convert(obj.real) + convert(obj.imag) * 1j
        if isinstance(obj, numbers.Number):
            return func(obj, *digits)
        if isinstance(obj, list):
            obj[:] = list(map(convert, obj))
            return obj
        if isinstance(obj, tuple):
            if hasattr(obj, "_fields"):  # it's a namedtuple
                return obj._replace(**convert(obj._asdict()))
            else:
                return tuple(convert(list(obj)))
        if isinstance(obj, set):
            return set(convert(list(obj)))
        if isinstance(obj, frozenset):
            return frozenset(convert(list(obj)))
        if isinstance(obj, collections.abc.Mapping):
            for k, v in obj.items():
                obj[k] = convert(obj[k])
            return obj
        if isinstance(obj, array.array):
            obj[:] = array.array(obj.typecode, convert(obj.tolist()))
            return obj
        if isinstance(obj, collections.deque):
            for i, elem in enumerate(obj):
                obj[i] = convert(elem)
            return obj
        if hasattr(obj, "__dict__"):
            # this should be at the end as some of the above types
            # have a __dict__ attribute
            convert(obj.__dict__)
            return obj

        return obj

from rounder.

nyggus avatar nyggus commented on June 15, 2024

I think we should not enable collections.Counter to be fed into rounder functions. Or rather, if such an object is fed into a rounder function, it should be returned untouched. This is for the following reason: Counter values are integers, so the only functions that will work is signif_object and map_object. And indeed, they do work - but do we want to change Counter values? No! Because then they will be incorrect, as they will not show what Counter aims to show: the number of occurrences of particular values. If a user wants to change these values, the user can (and definitely should) change the Counter instance to, for instance, a dict, and then he or she can use rounder in whatever way he or she wants.

Hence, my suggestion is to add the following if-statement :

if isinstance(obj, frozenset):
    return frozenset(convert(list(obj)))
if isinstance(obj, collections.Counter):
    return obj
if isinstance(obj, collections.abc.Mapping):
    for k, v in obj.items():
        obj[k] = convert(obj[k])
    return obj

The new statement is in the middle. It must be before collections.abc.Mappings, but the later the better for performance, as we do not expect the users to feed Counter instances to rounder functions all that often.

from rounder.

salabim avatar salabim commented on June 15, 2024

from rounder.

nyggus avatar nyggus commented on June 15, 2024

I see the point. I think this is reserved for some special and rare situations indeed, but as Python enables that, we should do so indeed. OK, then, so let's enable collections.Counter that way indeed.

from rounder.

nyggus avatar nyggus commented on June 15, 2024

And frankly, I think the main documentation of the Counter class is slightly misleading, as it says:
"A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. "

And only when you read notes for the class, you will see this is not true.

from rounder.

salabim avatar salabim commented on June 15, 2024

Well, the Python documentation is not very consistent. Anyway, any type is accepted as the value.

from rounder.

nyggus avatar nyggus commented on June 15, 2024

Done.

from rounder.

Related Issues (15)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.