Beispiel #1
0
def test_read_params():

    # ---- Single default kwargs
    kwargs = lib.read_params({'a': 0}, {'a': 1, 'b': 2})
    assert kwargs == {'a': 0, 'b': 2}
    assert kwargs.a == 0
    assert kwargs.b == 2
    kwargs.b = 3
    assert kwargs.b == 3
    assert kwargs == {'a': 0, 'b': 3}

    with pytest.raises(KeyError):
        lib.read_params({'a': 0, 'c': 8}, {'a': 1, 'b': 2})

    kwargs = lib.read_params({'a': 0, 'c': 8}, {'a': 1, 'b': 2}, safe=False)
    assert kwargs == {'a': 0, 'b': 2}

    kwargs = lib.read_params(
        {'a': lib.DFT, 'b': None}, {'a': 1, 'b': 2}
    )
    assert kwargs == {'a': 1, 'b': None}


    # ---- Multiple default kwargs
    kwargs = lib.read_params(
        {'a': 0, 'c': 8}, [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}],
    )
    assert kwargs == [{'a': 0, 'b': 2}, {"c": 8, "d": 4}]

    with pytest.raises(KeyError):
        lib.read_params(
            {'a': 0, 'c': 8, 'e': 10}, [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}],
        )

    kwargs = lib.read_params(
        {'a': 0, 'c': 8, 'e': 10},
        [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}],
        safe=False
    )
    assert kwargs == [{'a': 0, 'b': 2}, {'c': 8, 'd': 4}]

    kwargs = lib.read_params(
        {'a': 0, 'c': 8, 'e': 10},
        [{'a': 1, 'b': 2, 'e': 5, 'f': 6}, {'c': 3, 'd': 4, 'e': 5, 'f': 7}],
        safe=False
    )
    assert kwargs == [
        {'a': 0, 'b': 2, 'e': 10, 'f': 6},
        {'c': 8, 'd': 4, 'e': 10, 'f': 7},
    ]
Beispiel #2
0
def read_align_params(kwargs, dft_kwargs, safe=False):
    """Read alignments parameters

    Args:
        kwargs (dict)       : parameters for alignment
            'h_align': (str)    -> horizontal alignment (within H_ALIGN)
            'v_align': (str)    -> vertical alignment (within V_ALIGN)
            'align': (str)      -> alignment ("{h_align}-{v_align}")
                overwrite other params
        dft_kwargs (dict)   : default parameters for alignment
            'h_align': (str)    -> horizontal alignment (within H_ALIGN)
            'v_align': (str)    -> vertical alignment (within V_ALIGN)
        safe (bool)         : raise Error if kwargs has unexpected params

    Return:
        (olutils.Param): dictionary with alignment params
            'h_align': (str)    -> horizontal alignment (within H_ALIGN)
            'v_align': (str)    -> vertical alignment (within V_ALIGN)
    """
    assert sorted(dft_kwargs.keys()) == ['h_align', 'v_align']
    if 'align' in kwargs:
        kwargs = _read_align_param(kwargs['align'])
    kwargs = read_params(kwargs, dft_kwargs, safe=safe)
    if kwargs.h_align not in H_ALIGN:
        raise ValueError(
            f"Unknown value for adjustment '{kwargs.h_align}'"
            f", must be within {H_ALIGN}"
        )
    if kwargs.v_align not in V_ALIGN:
        raise ValueError(
            f"Unknown value for adjustment '{kwargs.v_align}'"
            f", must be within {V_ALIGN}"
        )
    return kwargs
Beispiel #3
0
def plot_projection_base(T, c1, c2, **kwargs):
    """Plot projection of transformed data on given principal components"""
    plot_kwargs = read_params(kwargs, PLOT_KWARGS)
    plt.scatter(
        T[:, c1 - 1],
        T[:, c2 - 1],
        **plot_kwargs,
    )
Beispiel #4
0
    def __init__(self, **kwargs):
        """Initiate a linear shape

        Args:
            **kwargs    : aspect of shape
                @see self.__class__.dft_look
        """
        super().__init__(**kwargs)
        look = read_params(kwargs, self.cls.dft_look, safe=False)
        apply_conversions(look, self.cls.par_conv)
        self._params = look
Beispiel #5
0
 def __init__(self, window, card_size, **params):
     params = read_params(params, GRID_PARAMS)
     page_x, page_y = window.settings.size
     x_margin, y_margin = params.pop('xy_margin')
     assert page_x > 2 * x_margin, "x-margin must be twice smaller than page x-size"
     assert page_y > 2 * y_margin, "y-margin must be twice smaller than page y-size"
     params['xbounds'] = (x_margin, page_x - x_margin)
     params['ybounds'] = (y_margin, page_y - y_margin)
     super().__init__(*card_size, **params)
     self.window = window
     self.init(self.window.screen)
Beispiel #6
0
    def __init__(self, **kwargs):
        """Initiate window settings

        Args:
            name (str):         name of window
            size (2-int-tuple): size of window in pixels
            fps (int):          number of frags per seconds
            background (color description): color of background
                @see oldisplay.collections.COLORS for available colors
        """
        params = read_params(kwargs, self.__class__.dft_params)
        for param, value in params.items():
            self.set(param, value)
Beispiel #7
0
def display_word_cards(window, words, card_size, **params):
    """Display one grid of words on window"""
    params = read_params(params, WORD_PARAMS)
    assert window.initiated, "Window must be initialized"
    window.components = []

    # ---- Create Grid
    grid_params = params.pop('grid', {})
    grid = build_display_grid(window, card_size, **grid_params)

    # ---- Read parameters
    txt_height = grid.dy // params.txt_height_r
    txt_xmargin = grid.dx // params.txt_xmargin_r
    txt_ymargin = grid.dy // params.txt_ymargin_r
    bot_txt_font = params.top_txt_font if params.bot_txt_font is None else params.bot_txt_font
    bot_txt_c = params.top_txt_c if params.bot_txt_c is None else params.bot_txt_c

    # ---- Write Words
    if len(words) > grid.cell_nb:
        logger.warning(
            f"Too many words ({len(words)}) regarding the number of cells"
            f" ({grid.cell_nb}): will only use first ({grid.cell_nb}) words")
        words = words[:grid.cell_nb]

    for (x, y), word in grid.xy_enum(words):
        ym = y + grid.dy // 2
        window.components += [
            Text(word.upper(), (x + txt_xmargin, ym - txt_ymargin),
                 height=txt_height,
                 align="bot-left",
                 color=params.top_txt_c,
                 font=params.top_txt_font),
            Rectangle(
                (x + txt_xmargin, ym + txt_ymargin // 2),
                (grid.dx - 3 * txt_xmargin // 2, txt_height + txt_ymargin),
                color=params.bot_txt_rect,
            ),
            Text(word.upper(), (x + grid.dx - txt_xmargin, ym + txt_ymargin),
                 height=txt_height,
                 align="top-right",
                 rotate=180,
                 color=bot_txt_c,
                 font=bot_txt_font),
        ]
    logger.debug(f"{len(words)} word cards displayed on window")
Beispiel #8
0
def display_board_cards(window, card_size, **params):
    """Display validation cards on window"""
    params = read_params(params, BOARD_PARAMS)
    assert window.initiated, "Window must be initialized"
    window.components = []

    # Main grid
    grid_params = params.pop('grid', {})
    grid = build_display_grid(window, card_size, **grid_params)

    # Card grids
    cell_dx = grid.dx // params.board_size[0]
    cell_dy = grid.dy // params.board_size[1]
    cell_di, cell_dj = params.board_size
    colors = [params.t1_color, params.t2_color] * (grid.cell_nb // 2)
    for (x, y), color in grid.xy_enum(colors):
        # Inner grid
        window.components.append(
            Grid(
                cell_dx,
                cell_dy,
                xbounds=(x, x + grid.dx),
                ybounds=(y, y + grid.dy),
                color=color,
                only_inside=True,
            ))

        # Card colors
        positions = [(x + i * cell_dx, y + j * cell_dy) for i in range(cell_di)
                     for j in range(cell_dj)]
        card_colors = ([params.t1_color] * params.guess_nb +
                       [params.t2_color] * params.guess_nb +
                       [color, params.death_color])
        assert len(card_colors) < len(positions)
        card_colors += [params.neutral_color
                        ] * (len(positions) - len(card_colors))
        rd.shuffle(card_colors)
        radius = min(cell_dx, cell_dx) // (params.form_ratio * 2)
        for (x, y), color in zip(positions, card_colors):
            window.components.append(
                Disk((x + cell_dx // 2, y + cell_dy // 2),
                     radius=radius,
                     color=color))
    logger.debug(f"{len(colors)} board cards displayed on window")
Beispiel #9
0
def display_validation_cards(window, card_size, **params):
    """Display validation cards on window"""
    params = read_params(params, VALIDATION_PARAMS)
    assert window.initiated, "Window must be initialized"
    window.components = []

    # ---- Display grid
    grid_params = params.pop('grid', {})
    grid = build_display_grid(window, card_size, **grid_params)

    # Display cards content
    colors = ([params.t1_color] * params.guess_nb +
              [params.t2_color] * params.guess_nb +
              [Color.mix(params.t1_color, params.t2_color)])
    assert len(colors) <= (grid.i_max * grid.j_max), (
        "Not enough space to display all validation cards")
    sx, sy = grid.dx // params.form_ratio, grid.dy // params.form_ratio
    for (x, y), color in grid.xy_enum(colors):
        x, y = x + grid.dx // 2, y + grid.dy // 2
        window.components.append(
            Rectangle((x, y), (sx, sy), color=color, align='center'))
    logger.debug(f"{len(colors)} validation cards displayed on window")
Beispiel #10
0
def split_params(params,
                 n,
                 dft_value=DFT,
                 extend_type=tuple,
                 dft_params=None,
                 safe=False):
    """Split an extended dict of params into n dicts of params

    Args:
        params (dict)       : extended params to split
            for a given parameter, one can give 1-to-n values within an object
            of type extend_type. Value at position i will correspond to value
            of param for i_th dictionary. If a value is default, the value
            will be replaced by the one in previous dictionary
        n (int)             : number of dict of params to build
        dft_value (object)    : default object to use as default value
            if i_th value of a param equal to default, its value is replaced
            by the one of (i-1)_th
        extend_type (type|tuple[type]): type used to extend values of params
            must be iterable type
        dft_params (dict)   : default parameters
        safe (bool)         : raise error when params are not in dft_params

    Examples:
        >>> params = {'a': 1, 'b': (2, 20), 'c': (3, DFT, 30)}
        >>> split_params(params, 3)
        [
            {'a': 1, 'b': 2, 'c': 3},
            {'a': 1, 'b': 20, 'c': 3},
            {'a': 1, 'b': 20, 'c': 30},
        ]

        >>> params = {'a': 1, 'b': DFT, 'c': 3}
        >>> split_params(params, 3)
        [{'a': 1, 'b': DFT, 'c': 3}, None, None]

        >>> params = {'a': 10, 'b': DFT, '?': 1}
        >>> dft_params = {'a': 1, 'b': 2, 'c': 3}
        >>> split_params(params, 3, dft_params=dft_params)
        ({'a': 10, 'b': 2, 'c': 3}, None, None)

        >>> params = {'a': 10, 'b': (DFT, 30)}
        >>> dft_params = {'a': 1, 'b': 2}
        >>> split_params(params, 3, dft_params=dft_params)
        ({'a': 10, 'b': 2}, {'a': 10, 'b': 30}, None)

        >>> params = {
        ...     'a': (10,),
        ...     'b': (DFT, 20),
        ...     'c': (30, DFT, 40),  # hovered c value will be same as normal
        ...     'd': (DFT, 40, DFT), # clicked d value will be same as hovered
        ... }
        >>> dft_params = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        >>> split_params(params, 3, dft_params=dft_params)
        (
            {'a': 10, 'b': 2, 'c': 30, 'd': 4},
            {'a': 10, 'b': 20, 'c': 30, 'd': 40},
            {'a': 10, 'b': 20, 'c': 40, 'd': 40},
        )

    Return:
        (list[Param|NoneType]): n dict of params
    """
    assert n > 0

    # Read params
    param_dicts = [{} for i in range(n)]
    for key, extend_val in params.items():
        if not isinstance(extend_val, extend_type):
            param_dicts[0][key] = extend_val
            continue

        prev_val = dft_value
        for i, val in enumerate(extend_val):
            try:
                param_dicts[i][key] = prev_val if val is dft_value else val
            except IndexError:
                raise ValueError(
                    f"Parameter '{key}' has more than n={n} values")
            prev_val = val

    # Complete params
    prev_kwargs = dft_params if dft_params else param_dicts[0]
    result = []
    for kwargs in param_dicts:
        if not kwargs:
            result.append(None)
            continue
        kwargs = read_params(kwargs, prev_kwargs, safe=safe, default=dft_value)
        result.append(kwargs)
        prev_kwargs = kwargs

    return result