问:
Constant ripple effect in android
What I'm trying to do is to have a constant ripple effect on the background of a LinearLayout. Why? Basically, this LinearLayout indicates live users watching this item. So I want the background to have a constant ripple animation similar to some apps that have a live indicator with a ripple effect on the background of that indicator. I hope my question was clear.

Example:
I want this effect to be happing constantly

答:
After taking many hours I have created custom class for infinite ripple view as per you want using this lib with customisation.

InfiniteRippleLayout

```<code>public class InfiniteRippleLayout extends FrameLayout {

    /**
     * Author：Hardik Talaviya
     * Date：  2020.02.15 1:30 PM
     * Describe:
     */

    private static final int DEFAULT_DURATION = 350;
    private static final int DEFAULT_FADE_DURATION = 75;
    private static final float DEFAULT_ALPHA = 0.2f;
    private static final int DEFAULT_COLOR = Color.BLACK;
    private static final int DEFAULT_BACKGROUND = Color.TRANSPARENT;
    private static final boolean DEFAULT_DELAY_CLICK = true;
    private static final boolean DEFAULT_PERSISTENT = false;
    private static final boolean DEFAULT_SEARCH_ADAPTER = false;
    private static final boolean DEFAULT_RIPPLE_OVERLAY = false;
    private static final int DEFAULT_ROUNDED_CORNERS = 0;

    private static final int FADE_EXTRA_DELAY = 50;

    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Rect bounds = new Rect();

    private int rippleColor;
    private boolean rippleOverlay;
    private int rippleDuration;
    private int rippleAlpha;
    private boolean rippleDelayClick;
    private int rippleFadeDuration;
    private boolean ripplePersistent;
    private Drawable rippleBackground;
    private boolean rippleInAdapter;
    private float rippleRoundedCorners;

    private float radius;

    private AdapterView parentAdapter;
    private View childView;

    private AnimatorSet rippleAnimator;

    private Point currentCoords = new Point();

    private int layerType;

    private int positionInAdapter;

    /*
     * Animations
     */
    private Property<InfiniteRippleLayout, Float> radiusProperty
            = new Property<InfiniteRippleLayout, Float>(Float.class, "radius") {
        @Override
        public Float get(InfiniteRippleLayout object) {
            return object.getRadius();
        }

        @Override
        public void set(InfiniteRippleLayout object, Float value) {
            object.setRadius(value);
        }
    };
    private Property<InfiniteRippleLayout, Integer> circleAlphaProperty
            = new Property<InfiniteRippleLayout, Integer>(Integer.class, "rippleAlpha") {
        @Override
        public Integer get(InfiniteRippleLayout object) {
            return object.getRippleAlpha();
        }

        @Override
        public void set(InfiniteRippleLayout object, Integer value) {
            object.setRippleAlpha(value);
        }
    };

    public InfiniteRippleLayout(Context context) {
        this(context, null, 0);
    }

    public InfiniteRippleLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public InfiniteRippleLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        setWillNotDraw(false);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.InfiniteRippleLayout);
        rippleColor = a.getColor(R.styleable.InfiniteRippleLayout_mrl_rippleColor, DEFAULT_COLOR);
        rippleOverlay = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_rippleOverlay, DEFAULT_RIPPLE_OVERLAY);
        rippleDuration = a.getInt(R.styleable.InfiniteRippleLayout_mrl_rippleDuration, DEFAULT_DURATION);
        rippleAlpha = (int) (255 * a.getFloat(R.styleable.InfiniteRippleLayout_mrl_rippleAlpha, DEFAULT_ALPHA));
        rippleDelayClick = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_rippleDelayClick, DEFAULT_DELAY_CLICK);
        rippleFadeDuration = a.getInteger(R.styleable.InfiniteRippleLayout_mrl_rippleFadeDuration, DEFAULT_FADE_DURATION);
        rippleBackground = new ColorDrawable(a.getColor(R.styleable.InfiniteRippleLayout_mrl_rippleBackground, DEFAULT_BACKGROUND));
        ripplePersistent = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_ripplePersistent, DEFAULT_PERSISTENT);
        rippleInAdapter = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_rippleInAdapter, DEFAULT_SEARCH_ADAPTER);
        rippleRoundedCorners = a.getDimensionPixelSize(R.styleable.InfiniteRippleLayout_mrl_rippleRoundedCorners, DEFAULT_ROUNDED_CORNERS);

        a.recycle();

        paint.setColor(rippleColor);
        paint.setAlpha(rippleAlpha);

        enableClipPathSupportIfNecessary();

        startRipple();
    }

    @Override
    public final void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (getChildCount() > 0) {
            throw new IllegalStateException("MaterialRippleLayout can host only one child");
        }
        //noinspection unchecked
        childView = child;
        super.addView(child, index, params);
    }

    @Override
    public void setOnClickListener(OnClickListener onClickListener) {
        if (childView == null) {
            throw new IllegalStateException("MaterialRippleLayout must have a child view to handle clicks");
        }
        childView.setOnClickListener(onClickListener);
    }

    @Override
    public void setOnLongClickListener(OnLongClickListener onClickListener) {
        if (childView == null) {
            throw new IllegalStateException("MaterialRippleLayout must have a child view to handle clicks");
        }
        childView.setOnLongClickListener(onClickListener);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return !findClickableViewInChild(childView, (int) event.getX(), (int) event.getY());
    }

    private void startRipple() {
        float endRadius = getEndRadius();

        cancelAnimations();

        rippleAnimator = new AnimatorSet();
        rippleAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (!ripplePersistent) {
                    setRadius(0);
                    setRippleAlpha(rippleAlpha);
                }
                if (rippleDelayClick) {
                    startRipple();
                }
                childView.setPressed(false);
            }
        });

        ObjectAnimator ripple = ObjectAnimator.ofFloat(this, radiusProperty, radius, endRadius);
        ripple.setDuration(rippleDuration);
        ripple.setInterpolator(new DecelerateInterpolator());
        ObjectAnimator fade = ObjectAnimator.ofInt(this, circleAlphaProperty, rippleAlpha, 0);
        fade.setDuration(rippleFadeDuration);
        fade.setInterpolator(new AccelerateInterpolator());
        fade.setStartDelay(rippleDuration - rippleFadeDuration - FADE_EXTRA_DELAY);

        if (ripplePersistent) {
            rippleAnimator.play(ripple);
        } else if (getRadius() > endRadius) {
            fade.setStartDelay(0);
            rippleAnimator.play(fade);
        } else {
            rippleAnimator.playTogether(ripple, fade);
        }
        rippleAnimator.start();
    }

    private void cancelAnimations() {
        if (rippleAnimator != null) {
            rippleAnimator.cancel();
            rippleAnimator.removeAllListeners();
        }
    }

    private float getEndRadius() {
        final int width = getWidth();
        final int height = getHeight();

        final int halfWidth = width / 2;
        final int halfHeight = height / 2;

        final float radiusX = halfWidth > currentCoords.x ? width - currentCoords.x : currentCoords.x;
        final float radiusY = halfHeight > currentCoords.y ? height - currentCoords.y : currentCoords.y;

        return (float) Math.sqrt(Math.pow(radiusX, 2) + Math.pow(radiusY, 2)) * 1.2f;
    }

    private AdapterView findParentAdapterView() {
        if (parentAdapter != null) {
            return parentAdapter;
        }
        ViewParent current = getParent();
        while (true) {
            if (current instanceof AdapterView) {
                parentAdapter = (AdapterView) current;
                return parentAdapter;
            } else {
                try {
                    current = current.getParent();
                } catch (NullPointerException npe) {
                    throw new RuntimeException("Could not find a parent AdapterView");
                }
            }
        }
    }

    private boolean adapterPositionChanged() {
        if (rippleInAdapter) {
            int newPosition = findParentAdapterView().getPositionForView(InfiniteRippleLayout.this);
            final boolean changed = newPosition != positionInAdapter;
            positionInAdapter = newPosition;
            if (changed) {
                cancelAnimations();
                childView.setPressed(false);
                setRadius(0);
            }
            return changed;
        }
        return false;
    }

    private boolean findClickableViewInChild(View view, int x, int y) {
        if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                View child = viewGroup.getChildAt(i);
                final Rect rect = new Rect();
                child.getHitRect(rect);

                final boolean contains = rect.contains(x, y);
                if (contains) {
                    return findClickableViewInChild(child, x - rect.left, y - rect.top);
                }
            }
        } else if (view != childView) {
            return (view.isEnabled() && (view.isClickable() || view.isLongClickable() || view.isFocusableInTouchMode()));
        }

        return view.isFocusableInTouchMode();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        bounds.set(0, 0, w, h);
        rippleBackground.setBounds(bounds);
    }

    @Override
    public boolean isInEditMode() {
        return true;
    }

    /*
     * Drawing
     */
    @Override
    public void draw(Canvas canvas) {
        final boolean positionChanged = adapterPositionChanged();
        currentCoords = new Point(getWidth() / 2, getHeight() / 2);
        if (rippleOverlay) {
            if (!positionChanged) {
                rippleBackground.draw(canvas);
            }
            super.draw(canvas);
            if (!positionChanged) {
                if (rippleRoundedCorners != 0) {
                    Path clipPath = new Path();
                    RectF rect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
                    clipPath.addRoundRect(rect, rippleRoundedCorners, rippleRoundedCorners, Path.Direction.CW);
                    canvas.clipPath(clipPath);
                }
                canvas.drawCircle(currentCoords.x, currentCoords.y, radius, paint);
            }
        } else {
            if (!positionChanged) {
                rippleBackground.draw(canvas);
                canvas.drawCircle(currentCoords.x, currentCoords.y, radius, paint);
            }
            super.draw(canvas);
        }
    }

    private float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
        invalidate();
    }

    public int getRippleAlpha() {
        return paint.getAlpha();
    }

    public void setRippleAlpha(Integer rippleAlpha) {
        paint.setAlpha(rippleAlpha);
        invalidate();
    }

    /**
     * {@link Canvas#clipPath(Path)} is not supported in hardware accelerated layers
     * before API 18. Use software layer instead
     * <p/>
     * https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
     */
    private void enableClipPathSupportIfNecessary() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (rippleRoundedCorners != 0) {
                layerType = getLayerType();
                setLayerType(LAYER_TYPE_SOFTWARE, null);
            } else {
                setLayerType(layerType, null);
            }
        }
    }
}
</code>```

attributes.xml

Add this attributes in your res->values->attributes.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="InfiniteRippleLayout">
        <attr name="mrl_rippleColor" format="color" localization="suggested" />
        <attr name="mrl_rippleOverlay" format="boolean" localization="suggested" />
        <attr name="mrl_rippleAlpha" format="float" localization="suggested" />
        <attr name="mrl_rippleDuration" format="integer" localization="suggested" />
        <attr name="mrl_rippleFadeDuration" format="integer" localization="suggested" />
        <attr name="mrl_rippleBackground" format="color" localization="suggested" />
        <attr name="mrl_rippleDelayClick" format="boolean" localization="suggested" />
        <attr name="mrl_ripplePersistent" format="boolean" localization="suggested" />
        <attr name="mrl_rippleInAdapter" format="boolean" localization="suggested" />
        <attr name="mrl_rippleRoundedCorners" format="dimension" localization="suggested" />
    </declare-styleable>
</resources>
</code>```

Add effect using below xml code

```<code><com.broooapps.curvegraphview.InfiniteRippleLayout
    android:layout_width="match_parent"
    android:layout_height="150dp"
    app:mrl_rippleAlpha="0.2"
    app:mrl_rippleColor="#585858"
    app:mrl_rippleDelayClick="true"
    app:mrl_rippleDuration="1100"
    app:mrl_rippleOverlay="true">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="HARDIK TALAVIYA"
        android:textColor="#000"
        android:textSize="20sp" />

</com.broooapps.curvegraphview.InfiniteRippleLayout>
</code>```

Result

I hope this can help you!

Title: Constant ripple effect in android

Body:
After taking many hours I have created custom class for infinite ripple view as per you want using this lib with customisation.

InfiniteRippleLayout

public class InfiniteRippleLayout extends FrameLayout {

    /**
     * Author：Hardik Talaviya
     * Date：  2020.02.15 1:30 PM
     * Describe:
     */

    private static final int DEFAULT_DURATION = 350;
    private static final int DEFAULT_FADE_DURATION = 75;
    private static final float DEFAULT_ALPHA = 0.2f;
    private static final int DEFAULT_COLOR = Color.BLACK;
    private static final int DEFAULT_BACKGROUND = Color.TRANSPARENT;
    private static final boolean DEFAULT_DELAY_CLICK = true;
    private static final boolean DEFAULT_PERSISTENT = false;
    private static final boolean DEFAULT_SEARCH_ADAPTER = false;
    private static final boolean DEFAULT_RIPPLE_OVERLAY = false;
    private static final int DEFAULT_ROUNDED_CORNERS = 0;

    private static final int FADE_EXTRA_DELAY = 50;

    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Rect bounds = new Rect();

    private int rippleColor;
    private boolean rippleOverlay;
    private int rippleDuration;
    private int rippleAlpha;
    private boolean rippleDelayClick;
    private int rippleFadeDuration;
    private boolean ripplePersistent;
    private Drawable rippleBackground;
    private boolean rippleInAdapter;
    private float rippleRoundedCorners;

    private float radius;

    private AdapterView parentAdapter;
    private View childView;

    private AnimatorSet rippleAnimator;

    private Point currentCoords = new Point();

    private int layerType;

    private int positionInAdapter;

    /*
     * Animations
     */
    private Property<InfiniteRippleLayout, Float> radiusProperty
            = new Property<InfiniteRippleLayout, Float>(Float.class, "radius") {
        @Override
        public Float get(InfiniteRippleLayout object) {
            return object.getRadius();
        }

        @Override
        public void set(InfiniteRippleLayout object, Float value) {
            object.setRadius(value);
        }
    };
    private Property<InfiniteRippleLayout, Integer> circleAlphaProperty
            = new Property<InfiniteRippleLayout, Integer>(Integer.class, "rippleAlpha") {
        @Override
        public Integer get(InfiniteRippleLayout object) {
            return object.getRippleAlpha();
        }

        @Override
        public void set(InfiniteRippleLayout object, Integer value) {
            object.setRippleAlpha(value);
        }
    };

    public InfiniteRippleLayout(Context context) {
        this(context, null, 0);
    }

    public InfiniteRippleLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public InfiniteRippleLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        setWillNotDraw(false);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.InfiniteRippleLayout);
        rippleColor = a.getColor(R.styleable.InfiniteRippleLayout_mrl_rippleColor, DEFAULT_COLOR);
        rippleOverlay = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_rippleOverlay, DEFAULT_RIPPLE_OVERLAY);
        rippleDuration = a.getInt(R.styleable.InfiniteRippleLayout_mrl_rippleDuration, DEFAULT_DURATION);
        rippleAlpha = (int) (255 * a.getFloat(R.styleable.InfiniteRippleLayout_mrl_rippleAlpha, DEFAULT_ALPHA));
        rippleDelayClick = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_rippleDelayClick, DEFAULT_DELAY_CLICK);
        rippleFadeDuration = a.getInteger(R.styleable.InfiniteRippleLayout_mrl_rippleFadeDuration, DEFAULT_FADE_DURATION);
        rippleBackground = new ColorDrawable(a.getColor(R.styleable.InfiniteRippleLayout_mrl_rippleBackground, DEFAULT_BACKGROUND));
        ripplePersistent = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_ripplePersistent, DEFAULT_PERSISTENT);
        rippleInAdapter = a.getBoolean(R.styleable.InfiniteRippleLayout_mrl_rippleInAdapter, DEFAULT_SEARCH_ADAPTER);
        rippleRoundedCorners = a.getDimensionPixelSize(R.styleable.InfiniteRippleLayout_mrl_rippleRoundedCorners, DEFAULT_ROUNDED_CORNERS);

        a.recycle();

        paint.setColor(rippleColor);
        paint.setAlpha(rippleAlpha);

        enableClipPathSupportIfNecessary();

        startRipple();
    }

    @Override
    public final void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (getChildCount() > 0) {
            throw new IllegalStateException("MaterialRippleLayout can host only one child");
        }
        //noinspection unchecked
        childView = child;
        super.addView(child, index, params);
    }

    @Override
    public void setOnClickListener(OnClickListener onClickListener) {
        if (childView == null) {
            throw new IllegalStateException("MaterialRippleLayout must have a child view to handle clicks");
        }
        childView.setOnClickListener(onClickListener);
    }

    @Override
    public void setOnLongClickListener(OnLongClickListener onClickListener) {
        if (childView == null) {
            throw new IllegalStateException("MaterialRippleLayout must have a child view to handle clicks");
        }
        childView.setOnLongClickListener(onClickListener);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return !findClickableViewInChild(childView, (int) event.getX(), (int) event.getY());
    }

    private void startRipple() {
        float endRadius = getEndRadius();

        cancelAnimations();

        rippleAnimator = new AnimatorSet();
        rippleAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (!ripplePersistent) {
                    setRadius(0);
                    setRippleAlpha(rippleAlpha);
                }
                if (rippleDelayClick) {
                    startRipple();
                }
                childView.setPressed(false);
            }
        });

        ObjectAnimator ripple = ObjectAnimator.ofFloat(this, radiusProperty, radius, endRadius);
        ripple.setDuration(rippleDuration);
        ripple.setInterpolator(new DecelerateInterpolator());
        ObjectAnimator fade = ObjectAnimator.ofInt(this, circleAlphaProperty, rippleAlpha, 0);
        fade.setDuration(rippleFadeDuration);
        fade.setInterpolator(new AccelerateInterpolator());
        fade.setStartDelay(rippleDuration - rippleFadeDuration - FADE_EXTRA_DELAY);

        if (ripplePersistent) {
            rippleAnimator.play(ripple);
        } else if (getRadius() > endRadius) {
            fade.setStartDelay(0);
            rippleAnimator.play(fade);
        } else {
            rippleAnimator.playTogether(ripple, fade);
        }
        rippleAnimator.start();
    }

    private void cancelAnimations() {
        if (rippleAnimator != null) {
            rippleAnimator.cancel();
            rippleAnimator.removeAllListeners();
        }
    }

    private float getEndRadius() {
        final int width = getWidth();
        final int height = getHeight();

        final int halfWidth = width / 2;
        final int halfHeight = height / 2;

        final float radiusX = halfWidth > currentCoords.x ? width - currentCoords.x : currentCoords.x;
        final float radiusY = halfHeight > currentCoords.y ? height - currentCoords.y : currentCoords.y;

        return (float) Math.sqrt(Math.pow(radiusX, 2) + Math.pow(radiusY, 2)) * 1.2f;
    }

    private AdapterView findParentAdapterView() {
        if (parentAdapter != null) {
            return parentAdapter;
        }
        ViewParent current = getParent();
        while (true) {
            if (current instanceof AdapterView) {
                parentAdapter = (AdapterView) current;
                return parentAdapter;
            } else {
                try {
                    current = current.getParent();
                } catch (NullPointerException npe) {
                    throw new RuntimeException("Could not find a parent AdapterView");
                }
            }
        }
    }

    private boolean adapterPositionChanged() {
        if (rippleInAdapter) {
            int newPosition = findParentAdapterView().getPositionForView(InfiniteRippleLayout.this);
            final boolean changed = newPosition != positionInAdapter;
            positionInAdapter = newPosition;
            if (changed) {
                cancelAnimations();
                childView.setPressed(false);
                setRadius(0);
            }
            return changed;
        }
        return false;
    }

    private boolean findClickableViewInChild(View view, int x, int y) {
        if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                View child = viewGroup.getChildAt(i);
                final Rect rect = new Rect();
                child.getHitRect(rect);

                final boolean contains = rect.contains(x, y);
                if (contains) {
                    return findClickableViewInChild(child, x - rect.left, y - rect.top);
                }
            }
        } else if (view != childView) {
            return (view.isEnabled() && (view.isClickable() || view.isLongClickable() || view.isFocusableInTouchMode()));
        }

        return view.isFocusableInTouchMode();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        bounds.set(0, 0, w, h);
        rippleBackground.setBounds(bounds);
    }

    @Override
    public boolean isInEditMode() {
        return true;
    }

    /*
     * Drawing
     */
    @Override
    public void draw(Canvas canvas) {
        final boolean positionChanged = adapterPositionChanged();
        currentCoords = new Point(getWidth() / 2, getHeight() / 2);
        if (rippleOverlay) {
            if (!positionChanged) {
                rippleBackground.draw(canvas);
            }
            super.draw(canvas);
            if (!positionChanged) {
                if (rippleRoundedCorners != 0) {
                    Path clipPath = new Path();
                    RectF rect = new RectF(0, 0, canvas.getWidth(), canvas.getHeight());
                    clipPath.addRoundRect(rect, rippleRoundedCorners, rippleRoundedCorners, Path.Direction.CW);
                    canvas.clipPath(clipPath);
                }
                canvas.drawCircle(currentCoords.x, currentCoords.y, radius, paint);
            }
        } else {
            if (!positionChanged) {
                rippleBackground.draw(canvas);
                canvas.drawCircle(currentCoords.x, currentCoords.y, radius, paint);
            }
            super.draw(canvas);
        }
    }

    private float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
        invalidate();
    }

    public int getRippleAlpha() {
        return paint.getAlpha();
    }

    public void setRippleAlpha(Integer rippleAlpha) {
        paint.setAlpha(rippleAlpha);
        invalidate();
    }

    /**
     * {@link Canvas#clipPath(Path)} is not supported in hardware accelerated layers
     * before API 18. Use software layer instead
     * <p/>
     * https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
     */
    private void enableClipPathSupportIfNecessary() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (rippleRoundedCorners != 0) {
                layerType = getLayerType();
                setLayerType(LAYER_TYPE_SOFTWARE, null);
            } else {
                setLayerType(layerType, null);
            }
        }
    }
}

attributes.xml

Add this attributes in your res->values->attributes.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="InfiniteRippleLayout">
        <attr name="mrl_rippleColor" format="color" localization="suggested" />
        <attr name="mrl_rippleOverlay" format="boolean" localization="suggested" />
        <attr name="mrl_rippleAlpha" format="float" localization="suggested" />
        <attr name="mrl_rippleDuration" format="integer" localization="suggested" />
        <attr name="mrl_rippleFadeDuration" format="integer" localization="suggested" />
        <attr name="mrl_rippleBackground" format="color" localization="suggested" />
        <attr name="mrl_rippleDelayClick" format="boolean" localization="suggested" />
        <attr name="mrl_ripplePersistent" format="boolean" localization="suggested" />
        <attr name="mrl_rippleInAdapter" format="boolean" localization="suggested" />
        <attr name="mrl_rippleRoundedCorners" format="dimension" localization="suggested" />
    </declare-styleable>
</resources>

Add effect using below xml code

<com.broooapps.curvegraphview.InfiniteRippleLayout
    android:layout_width="match_parent"
    android:layout_height="150dp"
    app:mrl_rippleAlpha="0.2"
    app:mrl_rippleColor="#585858"
    app:mrl_rippleDelayClick="true"
    app:mrl_rippleDuration="1100"
    app:mrl_rippleOverlay="true">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="HARDIK TALAVIYA"
        android:textColor="#000"
        android:textSize="20sp" />

</com.broooapps.curvegraphview.InfiniteRippleLayout>

Result

I hope this can help you!


来源: stackexchange

问:
How do I get the last 5 elements, excluding the first element from an array?
In a JavaScript array, how do I get the last 5 elements, excluding the first element?

```<code>[1, 55, 77, 88] // ...would return [55, 77, 88]
</code>```

adding additional examples:

```<code>[1, 55, 77, 88, 99, 22, 33, 44] // ...would return [88, 99, 22, 33, 44]

[1] // ...would return []
</code>```

答:
ES6 way:

I use destructuring assignment for array to get first and remaining rest elements and then I'll take last five of the rest with slice method:

const cutOffFirstAndLastFive = (array) => {
  const [first, ...rest] = array;
  return rest.slice(-5);
}

cutOffFirstAndLastFive([1, 55, 77, 88]);

console.log(
  'Tests:',
  JSON.stringify(cutOffFirstAndLastFive([1, 55, 77, 88])),
  JSON.stringify(cutOffFirstAndLastFive([1, 55, 77, 88, 99, 22, 33, 44])),
  JSON.stringify(cutOffFirstAndLastFive([1]))
);```

ContentLicense: CC BY-SA 4.0

Body:
In a JavaScript array, how do I get the last 5 elements, excluding the first element?

[1, 55, 77, 88] // ...would return [55, 77, 88]

adding additional examples:

[1, 55, 77, 88, 99, 22, 33, 44] // ...would return [88, 99, 22, 33, 44]

[1] // ...would return []


问:
Can't install lxml for python 3.8.1 on windows
I am on Windows 10 64-bit, in a venv.

```<code>Pip install lxml return
</code>```

Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?

So I tried to use the appropriate .whl availlable here (lxml-4.5.0-cp38-cp38-win_amd64.whl) which leads to another error:

lxml-4.5.0-cp38-cp38-win_amd64.whl is not a supported wheel on this platform.

I tried to use pip.exe, pip3.exe, pip3.8.exe and the 64x and 32x bit versions of the .whl file without success

Am I missing something or is the Python 3.8 version of the package not compatible with Python 3.8.1?

答: This happens because you probably have an older version of python alongside 3.8 and when you install the package it references the older one. You can try deleting all python versions and installing Python 3.8 again</p>

Body:
I am on Windows 10 64-bit, in a venv.

Pip install lxml return

Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?

So I tried to use the appropriate .whl availlable here (lxml-4.5.0-cp38-cp38-win_amd64.whl) which leads to another error:

lxml-4.5.0-cp38-cp38-win_amd64.whl is not a supported wheel on this platform.

I tried to use pip.exe, pip3.exe, pip3.8.exe and the 64x and 32x bit versions of the .whl file without success

Am I missing something or is the Python 3.8 version of the package not compatible with Python 3.8.1?


问:
Creating image histograms from all pictures in a folder
I'm trying to create a histogram for each image in a folder, and save the plots of them into a CSV file. The user would enter the folder the images are saved, and then the files would get created and named accordingly

```<code>files = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] #loop to get all files from folder
for x in files:
    image = "x + 1"
    img2 = cv2.imread('similarImages/' + directory + '/' + image + '.png', cv2.IMREAD_COLOR)
    histSim = cv2.calcHist([img2], [1], None, [256], [0, 256])  # create histo of each image
    np.savetxt('Test/similarImage' + x + '.csv', histSim, delimiter=',')  # save save plots to csv
</code>```

From my previous knowledge of python, I've theory crafted the above code, but in classic fashion, it doesnt work (shocker)

Am I going along the right lines? If not could I get a nudge in the right direction, and if so, why doesnt it work?

It's been a while since I took on something like this, and such I am a little rusty, many thanks, Ben

答:
The issue I was having was the image variable was a string, and thus, when I was adding 1 to it, it was concatenating, and not adding the values, so using integers and then converting to a string when I needed it in the file path worked</p>

```<code>image = 0
files = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  # loop to get all files from folder
for x in files:

    image = x + 1
    image = str(image)
    img2 = cv2.imread('similarImages/' + directory + '/' + image + '.png', cv2.IMREAD_COLOR)
    histSim = pd.DataFrame(cv2.calcHist([img2], [1], None, [256], [0, 256]))  # create histo of each image
    histSim.to_csv('Test/histogram' + image + '.csv', index=False)
</code>```

Body:
I'm trying to create a histogram for each image in a folder, and save the plots of them into a CSV file. The user would enter the folder the images are saved, and then the files would get created and named accordingly

files = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] #loop to get all files from folder
for x in files:
    image = "x + 1"
    img2 = cv2.imread('similarImages/' + directory + '/' + image + '.png', cv2.IMREAD_COLOR)
    histSim = cv2.calcHist([img2], [1], None, [256], [0, 256])  # create histo of each image
    np.savetxt('Test/similarImage' + x + '.csv', histSim, delimiter=',')  # save save plots to csv

From my previous knowledge of python, I've theory crafted the above code, but in classic fashion, it doesnt work (shocker)

Am I going along the right lines? If not could I get a nudge in the right direction, and if so, why doesnt it work?

It's been a while since I took on something like this, and such I am a little rusty, many thanks, Ben

Body:
The issue I was having was the image variable was a string, and thus, when I was adding 1 to it, it was concatenating, and not adding the values, so using integers and then converting to a string when I needed it in the file path worked

image = 0
files = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  # loop to get all files from folder
for x in files:

    image = x + 1
    image = str(image)
    img2 = cv2.imread('similarImages/' + directory + '/' + image + '.png', cv2.IMREAD_COLOR)
    histSim = pd.DataFrame(cv2.calcHist([img2], [1], None, [256], [0, 256]))  # create histo of each image
    histSim.to_csv('Test/histogram' + image + '.csv', index=False)


问:
ASP.NET application getting slower over time using Lucene.Net
A website I have using Lucene.Net for search is progressively getting slower over time. I have set IIS to recycle the app pool at 1.5GBs.

After a recycle the app is fast again.

What are the best steps in diagnosing which parts of the search is causing the issue?

Its worth noting, it is definitely the search that's causing the issues as its only this part of the application which gets slow. A normal page loads fine regardless of time.

答:
If you have analyzed your search code and it's too complex or not obvious what the slowdowns are, I would start with running performance monitors (perfmon.exe) and logging the results.   Look at change in CPU usage, memory, disk queuing, ASP.Net specific counters (requests queued, requests/sec) and CLR counters (pipeline instance count, exceptions thrown, context switches/sec, etc.).

Once you can zero in on some things that look out of the ordinary (growing unchecked over time by the sounds of it), you can start to narrow down any code problems.

ContentLicense: CC BY-SA 3.0


问:
Getting started with denoising elements of a 200x200 numpy array
I have a 200x200 numpy array that has a shape in it which I can see when I graph it using matplotlib's imshow() function. However, there is also a lot of noise added in that picture. I am trying to use openCV to emphasize the shape and denoise the image. But it keeps throwing error messages that I don't understand. What should I do to get started on the denoising problem. The shape is visible to me as I see it but extra noise was added using the np.random.randint() function on top of the image. I want to reduce that noise

答: I solved the problem using Scikit Image. They have very accessible documentation page for new comers and the error messages are a lot easier to understand. As for my problem I had to use Scikit Image's restoration library which has a lot of denoising functions much like openCV however the examples and the easy to understand error messages really helped. Playing around with Bilateral filters and Non-local Means Denoising solved the problem for me. </p>


问:
Create custom meta information in WooCommerce order
I use WooCommerce with the plugin "YITH Request a quote" to enable requests for quotations.

What I try

I would like to create custom meta data when the User is requesting a quote.

I try to do this with the following hook:

```<code>add_action('woocommerce_checkout_create_order', 'before_checkout_create_order', 20, 2);
function before_checkout_create_order( $order, $data ) {
    $order->update_meta_data( '_custom_meta_key', 'value' );
}
</code>```

... unfortunately without success. Enclosed you will find a picture of the meta-information I mean.

Do you have an idea? :-)

答:
This was the solution:</p>

```<code>add_action('woocommerce_new_order_item','add_basic_meta_for_new_quote',10,3); // add extra order metas

function add_basic_meta_for_new_quote($item_id, $values, $cart_item_key)
{
    wc_add_order_item_meta($item_id, 'key', 'value');
}
</code>```

Body:
I use WooCommerce with the plugin "YITH Request a quote" to enable requests for quotations.

What I try

I would like to create custom meta data when the User is requesting a quote.

I try to do this with the following hook:

add_action('woocommerce_checkout_create_order', 'before_checkout_create_order', 20, 2);
function before_checkout_create_order( $order, $data ) {
    $order->update_meta_data( '_custom_meta_key', 'value' );
}

... unfortunately without success. Enclosed you will find a picture of the meta-information I mean.

Do you have an idea? :-)

Body:
This was the solution:

add_action('woocommerce_new_order_item','add_basic_meta_for_new_quote',10,3); // add extra order metas

function add_basic_meta_for_new_quote($item_id, $values, $cart_item_key)
{
    wc_add_order_item_meta($item_id, 'key', 'value');
}


问:
Update Entire Collection In MongoDB Node Js
I have a program that receive a New file from FTP server after some specific time , I insert the new updated file's data into my database MongoDB the fields remain same , only data changes in new file.. Now the problem is that EVERY TIME I have to insert whole new collection into database, and the collection increases accordingly.Forexample- first time data is of 20 records , second time 40 and then 60 and so on .The thing I want to do is I want to check which field's data is updated in New file before inserting new FILE's data , and should only update these field's data in database instead of inserting whole new document.Does MONGOOSE or MONGODB provide solution for this , means IF I PASS A DATA AS PARAMETER , IT SOULD COMPARE MY EXISTING COLLECTION WITH MY NEW DATA and then Update Only UPDATED FIELDS ..Please help me i,m stuck , thanks :) . I,m using NODE JS ...

```<code>var c = new Client();
            var connectionProperties = {
                host: 'ABC',
                user: 'ABC',
                port: 'ABC',
                password: 'ABC',
            };
            c.connect(connectionProperties);
          c.on('ready', function () {
                c.get('path-to-excel-file', function (err, stream) {
                    if (err) throw err;
                    stream.once('close', function () {
                        const workBook = XLSX.readFile('Convertedfile.xlsx');
                        XLSX.writeFile(workBook, 'Convertedfile', { bookType: "csv" });
                        csv()
                            .fromFile("Convertedfile")
                            .then((jsonObj) => {
                                Model.collection.insert(jsonObj, function (err, docs) {
                                    if (err) {
                                        return console.error(err);
                                    } else {
                                        console.log("All Documents insterted");
                                    }
                                });
                            })
                        c.end()
                    });
                    stream.pipe(fs.createWriteStream('ConvertedFile.xlsx'))
                })
          })
</code>```

答:
It looks like you need upsert means update if document/record exists or insert/create it.

So this can be done either 1 document at a moment or in bulk, but it would need a query to find the matching document(s) first.

Since you've not provided any sample data so I can't write a sample code snippet for you but here is the link to get you started, for bulk: Bulk.find.upsert and for single document this thread is good : how-do-i-update-upsert-a-document-in-mongoose

Update: here is the mongodb bulk upsert in action:

```<code>const mongo = require('mongodb');
const MongoClient = mongo.MongoClient;

const client = new MongoClient('mongodb://127.0.0.1:27017', { useUnifiedTopology: true });
client.connect(async err => {
    if (err) {
        console.log('DB Connection Error ', err);
    } else {
        const db = client.db('node-cheat-db');

        // lets assume you've read all file contents and data is now ready for db operation
        let records = [
            {first: 'john', last: 'doe', email: 'johen@doe.com'},
            {first: 'jack', last: 'doe', email: 'jack@doe.com'},
            {first: 'jill', last: 'doe_updated', email: 'jill@doe.com'}
        ];

        // prepare bulk upsert so that new records are created and existing are updated
        let bulk = db.collection('users').initializeOrderedBulkOp();
        for (var i = 0; i < records.length; i++) {
            bulk.find({
        "email": records[i].email // at least 1 key should be treated as PK; in this example email is PK
        }).upsert(records[i]).replaceOne(records[i]);
        }
        bulk.execute(function (err,updateResult) {
                if (updateResult.result.ok != 1) {
                    console.log('Bulk Upsert Error');
                } else {
                    console.log(`Inserted: ${updateResult.result.nUpserted} and Updated: ${updateResult.result.nModified}`);
                }
        });
    }
});
</code>```

sample output looks like:

Inserted: 0 and Updated: 3

Further Details:

Clone node-cheat bulk-update, run node bulk-update.js followed by npm install mongodb.

Body:
I have a program that receive a New file from FTP server after some specific time , I insert the new updated file's data into my database MongoDB the fields remain same , only data changes in new file.. Now the problem is that EVERY TIME I have to insert whole new collection into database, and the collection increases accordingly.Forexample- first time data is of 20 records , second time 40 and then 60 and so on .The thing I want to do is I want to check which field's data is updated in New file before inserting new FILE's data , and should only update these field's data in database instead of inserting whole new document.Does MONGOOSE or MONGODB provide solution for this , means IF I PASS A DATA AS PARAMETER , IT SOULD COMPARE MY EXISTING COLLECTION WITH MY NEW DATA and then Update Only UPDATED FIELDS ..Please help me i,m stuck , thanks :) . I,m using NODE JS ...

var c = new Client();
            var connectionProperties = {
                host: 'ABC',
                user: 'ABC',
                port: 'ABC',
                password: 'ABC',
            };
            c.connect(connectionProperties);
          c.on('ready', function () {
                c.get('path-to-excel-file', function (err, stream) {
                    if (err) throw err;
                    stream.once('close', function () {
                        const workBook = XLSX.readFile('Convertedfile.xlsx');
                        XLSX.writeFile(workBook, 'Convertedfile', { bookType: "csv" });
                        csv()
                            .fromFile("Convertedfile")
                            .then((jsonObj) => {
                                Model.collection.insert(jsonObj, function (err, docs) {
                                    if (err) {
                                        return console.error(err);
                                    } else {
                                        console.log("All Documents insterted");
                                    }
                                });
                            })
                        c.end()
                    });
                    stream.pipe(fs.createWriteStream('ConvertedFile.xlsx'))
                })
          })

Body:
It looks like you need upsert means update if document/record exists or insert/create it.

So this can be done either 1 document at a moment or in bulk, but it would need a query to find the matching document(s) first.

Since you've not provided any sample data so I can't write a sample code snippet for you but here is the link to get you started, for bulk: Bulk.find.upsert and for single document this thread is good : how-do-i-update-upsert-a-document-in-mongoose

Update: here is the mongodb bulk upsert in action:

const mongo = require('mongodb');
const MongoClient = mongo.MongoClient;

const client = new MongoClient('mongodb://127.0.0.1:27017', { useUnifiedTopology: true });
client.connect(async err => {
    if (err) {
        console.log('DB Connection Error ', err);
    } else {
        const db = client.db('node-cheat-db');

        // lets assume you've read all file contents and data is now ready for db operation
        let records = [
            {first: 'john', last: 'doe', email: 'johen@doe.com'},
            {first: 'jack', last: 'doe', email: 'jack@doe.com'},
            {first: 'jill', last: 'doe_updated', email: 'jill@doe.com'}
        ];

        // prepare bulk upsert so that new records are created and existing are updated
        let bulk = db.collection('users').initializeOrderedBulkOp();
        for (var i = 0; i < records.length; i++) {
            bulk.find({
        "email": records[i].email // at least 1 key should be treated as PK; in this example email is PK
        }).upsert(records[i]).replaceOne(records[i]);
        }
        bulk.execute(function (err,updateResult) {
                if (updateResult.result.ok != 1) {
                    console.log('Bulk Upsert Error');
                } else {
                    console.log(`Inserted: ${updateResult.result.nUpserted} and Updated: ${updateResult.result.nModified}`);
                }
        });
    }
});

sample output looks like:

Inserted: 0 and Updated: 3

Further Details:

Clone node-cheat bulk-update, run node bulk-update.js followed by npm install mongodb.


问:
What is the right approach for state change?
I am trying to implement this in my app:

Original code:

```<code><Searchbox change={this.onSearchChange}/>
</code>```

But this is not working. While trying several options, I found following codes work:

Code 1:

```<code><Searchbox change={event => setState({/*the state is changed*/})}/>
</code>```

Code 2:

```<code><Searchbox change={event => this.onSearchChange(event)}/>
</code>```

Reading the documentation, I believe I wrote the correct syntax in the first time, but I want to be sure.

答:
Found the solution in the React documentation. I should have put this in the constructor:

```<code>this.onSearchChange = this.onSearchChange.bind(this)
</code>```

Because, in the child component, it does not detect the function from parent for this keyword.

Body:
I am trying to implement this in my app:

Original code:

<Searchbox change={this.onSearchChange}/>

But this is not working. While trying several options, I found following codes work:

Code 1:

<Searchbox change={event => setState({/*the state is changed*/})}/>

Code 2:

<Searchbox change={event => this.onSearchChange(event)}/>

Reading the documentation, I believe I wrote the correct syntax in the first time, but I want to be sure.

Body:
Found the solution in the React documentation. I should have put this in the constructor:

this.onSearchChange = this.onSearchChange.bind(this)

Because, in the child component, it does not detect the function from parent for this keyword.


问:
Convert Ember addon to web component
How to convert an ember addon to web component?

https://github.com/BBVAEngineering/ember-cli-web-components
This plugin is not working, I am getting, defineCustomElements is not defined error.

Then I found glimmer can create web components.
With glimmer, I need to convert ember addon to glimmer, then create web component (which is time consuming). Also I am not able to pass arrays and objects to web component created using glimmer (can only pass strings using atrributes) and the web component is not using shadow dom (which can cause problems with styling).

Ember octane is using glimmer component, but cannot find in its documentation if it can be converted to web component

So what is currently the best way to convert ember addon to web component?

答:
Did you import the defineCustomElements in the app.js.

You can refer https://github.com/BBVAEngineering/ember-cli-web-components/blob/master/tests/dummy/app/app.js this file and especially this line (https://github.com/BBVAEngineering/ember-cli-web-components/blob/master/tests/dummy/app/app.js#L5).

Title: Convert Ember addon to web component


问:
Set background of preference according to the position
I am developing an app where I am using Preference (androidx.preference.Preference).
I am using PreferenceCategory and adding Preerence to it at runtime.

My requirement is that the first, middle and last preferences in PreferenceCategory should have different backgrounds and layouts. I am using following code for this :

```<code>public static class SettingsFragment extends PreferenceFragmentCompat {
    Activity activity = null;
    String TAG = "SettingsFragment";
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.root_preferences, rootKey);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        activity = (Activity) getActivity();
    }

    @Override
    public void onResume() {
        super.onResume();
        PreferenceCategory category = findPreference("MyPreference");
        category.setLayoutResource(R.layout.preference_group_layout);
        MyAdapter myAdapter = new MyAdapter(category);
        for(int i=0;i<10;i++) {
            Preference preference = new Preference(activity);
            preference.setKey("P" + i);
            preference.setLayoutResource(R.layout.preference_layout);
            category.addPreference(preference);
            Log.d(TAG,"" + category.getPreferenceCount());
            myAdapter.notifyDataSetChanged();
        }

    }
}

class MyAdapter extends PreferenceGroupAdapter {
    String TAG = "MyAdapter";
    public MyAdapter(PreferenceGroup preferenceGroup) {
        super(preferenceGroup);
    }

    @Override
    public int getItemCount() {
        return super.getItemCount();
    }

    @Override
    public Preference getItem(int position) {
        return super.getItem(position);
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @NonNull
    @Override
    public PreferenceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Log.d(TAG,"onCreateViewHolder called");
        return super.onCreateViewHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(@NonNull PreferenceViewHolder holder, int position) {
        Log.d(TAG,"onBindViewHolder called");
        super.onBindViewHolder(holder, position);
    }
}
</code>```

But This is not showing my Prefrence in layout. I searched on internet about this but I didn't find any similar example. How can I add Preference and set their layout according to their positions.

答:
Try changing the color in `onBindViewHolder':</p>

```<code>@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder, int position) {
    Log.d(TAG,"onBindViewHolder called");
    super.onBindViewHolder(holder, position);
    switch (position){
        case 0:
            holder.itemView.setBackgroundColor(Color.WHITE);
        case 1:
            holder.itemView.setBackgroundColor(Color.GREEN);
            .....
            .....
        default:
            holder.itemView.setBackgroundColor(Color.GRAY);
    }
}
</code>```

Body:
I am developing an app where I am using Preference (androidx.preference.Preference).
I am using PreferenceCategory and adding Preerence to it at runtime.

My requirement is that the first, middle and last preferences in PreferenceCategory should have different backgrounds and layouts. I am using following code for this :

public static class SettingsFragment extends PreferenceFragmentCompat {
    Activity activity = null;
    String TAG = "SettingsFragment";
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.root_preferences, rootKey);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        activity = (Activity) getActivity();
    }

    @Override
    public void onResume() {
        super.onResume();
        PreferenceCategory category = findPreference("MyPreference");
        category.setLayoutResource(R.layout.preference_group_layout);
        MyAdapter myAdapter = new MyAdapter(category);
        for(int i=0;i<10;i++) {
            Preference preference = new Preference(activity);
            preference.setKey("P" + i);
            preference.setLayoutResource(R.layout.preference_layout);
            category.addPreference(preference);
            Log.d(TAG,"" + category.getPreferenceCount());
            myAdapter.notifyDataSetChanged();
        }

    }
}

class MyAdapter extends PreferenceGroupAdapter {
    String TAG = "MyAdapter";
    public MyAdapter(PreferenceGroup preferenceGroup) {
        super(preferenceGroup);
    }

    @Override
    public int getItemCount() {
        return super.getItemCount();
    }

    @Override
    public Preference getItem(int position) {
        return super.getItem(position);
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @NonNull
    @Override
    public PreferenceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Log.d(TAG,"onCreateViewHolder called");
        return super.onCreateViewHolder(parent, viewType);
    }

    @Override
    public void onBindViewHolder(@NonNull PreferenceViewHolder holder, int position) {
        Log.d(TAG,"onBindViewHolder called");
        super.onBindViewHolder(holder, position);
    }
}

But This is not showing my Prefrence in layout. I searched on internet about this but I didn't find any similar example. How can I add Preference and set their layout according to their positions.

Body:
Try changing the color in `onBindViewHolder':

@Override
public void onBindViewHolder(@NonNull PreferenceViewHolder holder, int position) {
    Log.d(TAG,"onBindViewHolder called");
    super.onBindViewHolder(holder, position);
    switch (position){
        case 0:
            holder.itemView.setBackgroundColor(Color.WHITE);
        case 1:
            holder.itemView.setBackgroundColor(Color.GREEN);
            .....
            .....
        default:
            holder.itemView.setBackgroundColor(Color.GRAY);
    }
}


问:
How to check for the existence of values after splitting in object, and then assign them if only the last one does not exist
There is a question about sorting and adding an object, more precisely for example:

I have a string a1/b1/c1/d1 that
spl = "a1/b1/c1/d1".split ("/") and at the output I get an array of 4 elements.
I have an object - obj, I need to cycle through the spl array and each new turn I added values, right now I'll tell you

```<code>for(var i = 0; i < spl.length(); i++){
    // and here's the code I don't know how to write
}

/* there must be something like this
//if obj[spl[0]] is existing then do
i = 0: obj[spl[0]] = {};

//if obj[spl[0]][spl[1]] is existing then do
i = 1: obj[spl[0]][spl[1]] = {};

//if obj[spl[0]][spl[1]][spl[2]] is existing then do
i = 2: obj[spl[0]][spl[1]][spl[2]] = {};

//and if the last element of the massiv is not existing then do
i = 3: obj[spl[0]][spl[1]][spl[2]][spl[3]] = {};

/if the last element of the massiv is existing then do nothing
the end of the cycle*/
</code>```

that is, each scroll is added as long as i is less than the length of the array
it should work like this

```<code>obj {
    a1:{
        b1:{
            c1:{
                d1:{}
            }
        }
    }
};
</code>```

For example, if I have 2 elements in spl, the loop will add only 2 times as in the example, if 5, then 5

答:
Not sure if I understand the question correctly, is this what you want to achieve?

let obj = {}
let path = 'a1/a2/a3'.split('/')

let current = obj
for (let prop of path) {
  current[prop] = current[prop] || {}
  current = current[prop]
}

console.log(obj)```

Body:
There is a question about sorting and adding an object, more precisely for example:

I have a string a1/b1/c1/d1 that
spl = "a1/b1/c1/d1".split ("/") and at the output I get an array of 4 elements.
I have an object - obj, I need to cycle through the spl array and each new turn I added values, right now I'll tell you

for(var i = 0; i < spl.length(); i++){
    // and here's the code I don't know how to write
}

/* there must be something like this
//if obj[spl[0]] is existing then do
i = 0: obj[spl[0]] = {};

//if obj[spl[0]][spl[1]] is existing then do
i = 1: obj[spl[0]][spl[1]] = {};

//if obj[spl[0]][spl[1]][spl[2]] is existing then do
i = 2: obj[spl[0]][spl[1]][spl[2]] = {};

//and if the last element of the massiv is not existing then do
i = 3: obj[spl[0]][spl[1]][spl[2]][spl[3]] = {};

/if the last element of the massiv is existing then do nothing
the end of the cycle*/

that is, each scroll is added as long as i is less than the length of the array
it should work like this

obj {
    a1:{
        b1:{
            c1:{
                d1:{}
            }
        }
    }
};

For example, if I have 2 elements in spl, the loop will add only 2 times as in the example, if 5, then 5


问:
React: React-bootstrap, calling function only after user has finished typing
I am utilizing React-Bootstrap for a simple text box component. Right now, the callback is called every time the user edits the textbox, hence it is called back when every letter is called

```<code><Form.Group controlId="Id">
    <Form.Label>Id</Form.Label>
    <Form.Control style = {{marginLeft: 10}} name="Idstate" onChange={this.handleChange} defaultValue = {this.state.idstate}/>

</Form.Group>
</code>```

The code above is my form group

```<code>handleChange = (event) => {
    event.persist()
    const name = event.target.name
    if (name == "Idstate"){
        this.setState({idstate: event.target.value})
        this.state.idstate = event.target.value;
        Apiservice.updatetabletopmenudata(this.tableid, event.target.value, "idstate")
    }
    console.log(this.state)
}
</code>```

This results in a really laggy process, and sometimes the data isn't saved properly

Is there any way for the callback to be executed only after the user has finished editing the text box?

答:
First, fixing errors before performance:

Using defaultValue would create an uncontrolled component - only the default value will be set from React, then ignore any state changes.

If you need to control the value from React, please use value:

```<code>    <Form.Control ... value={this.state.idstate} />
</code>```

Also, never modify state directly, this.setState({idstate: event.target.value}) is enough, no need for this.state.idstate = ... - but the operation is asynchronous (see the link above), so console.log(this.state) is meaningless inside the handleChange - you can console.log inside render or just use React DevTools to view the current state (both for classes and hooks).

Second, performance:

React state update is NOT slow by itself, it's pretty optimized. If you want to delay a slow Apiservice, you may try following:

```<code>handleChange = (event) => {
    const name = event.target.name
    const value = event.target.value
    if (name == "Idstate"){
        this.setState({idstate: event.target.value})
        setTimeout(() =>
            Apiservice.updatetabletopmenudata(this.tableid, value, "idstate")
        )
    }
}
</code>```

Body:
I am utilizing React-Bootstrap for a simple text box component. Right now, the callback is called every time the user edits the textbox, hence it is called back when every letter is called

<Form.Group controlId="Id">
    <Form.Label>Id</Form.Label>
    <Form.Control style = {{marginLeft: 10}} name="Idstate" onChange={this.handleChange} defaultValue = {this.state.idstate}/>

</Form.Group>

The code above is my form group

handleChange = (event) => {
    event.persist()
    const name = event.target.name
    if (name == "Idstate"){
        this.setState({idstate: event.target.value})
        this.state.idstate = event.target.value;
        Apiservice.updatetabletopmenudata(this.tableid, event.target.value, "idstate")
    }
    console.log(this.state)
}

This results in a really laggy process, and sometimes the data isn't saved properly

Is there any way for the callback to be executed only after the user has finished editing the text box?

Body:
First, fixing errors before performance:

Using defaultValue would create an uncontrolled component - only the default value will be set from React, then ignore any state changes.

If you need to control the value from React, please use value:

    <Form.Control ... value={this.state.idstate} />

Also, never modify state directly, this.setState({idstate: event.target.value}) is enough, no need for this.state.idstate = ... - but the operation is asynchronous (see the link above), so console.log(this.state) is meaningless inside the handleChange - you can console.log inside render or just use React DevTools to view the current state (both for classes and hooks).

Second, performance:

React state update is NOT slow by itself, it's pretty optimized. If you want to delay a slow Apiservice, you may try following:

handleChange = (event) => {
    const name = event.target.name
    const value = event.target.value
    if (name == "Idstate"){
        this.setState({idstate: event.target.value})
        setTimeout(() =>
            Apiservice.updatetabletopmenudata(this.tableid, value, "idstate")
        )
    }
}


问:
Get items list count dynamically according to the filtering result
My app displays the total posts count, initially according to the server's response.

However, these posts can be filtered and I need to get the post count dynamically according to the filtering result.

```<code>inputFilter:function() {
   var vm = this;
   return vm.posts.filter((post) => {
        var vmPosts = post.title.match(searchValue);
        var countFilteredPostsDinammicaly = vmPosts.count(); //??????
        return vmPosts;
   });
}
</code>```

Thanks.

答:
You can make a computed property which will return you a filtered array on basis of the query/filters applied.

Another computed property will return you the length of the filtered array i.e filtered post count to show on the DOM.

new Vue({
  el: '#app',

  data: {
   posts: [
    { title: 'apple is best fruit' },
    { title: 'orange is 2020 best fruit' },
    { title: 'apples are sweeter than oranges in 2020' }
   ],
   query: ''
  },

  computed: {
   getFilteredPosts () {
    return this.posts.filter(post => post.title.includes(this.query))
   },
   getFilteredPostsCount () {
    return this.getFilteredPosts.length
   }
  }
})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

 <input placeholder="search for `apple`" v-model="query"/>
 <br/><br/>

 Filtered posts count: {{ getFilteredPostsCount }}
 <br/><br/>

 Filtered posts:
 <li v-for="(post, i) in getFilteredPosts" :key="i">
  {{ post.title }}
 </li>

</div></code>```

Body:
My app displays the total posts count, initially according to the server's response.

However, these posts can be filtered and I need to get the post count dynamically according to the filtering result.

inputFilter:function() {
   var vm = this;
   return vm.posts.filter((post) => {
        var vmPosts = post.title.match(searchValue);
        var countFilteredPostsDinammicaly = vmPosts.count(); //??????
        return vmPosts;
   });
}

Thanks.

Body:
You can make a computed property which will return you a filtered array on basis of the query/filters applied.

Another computed property will return you the length of the filtered array i.e filtered post count to show on the DOM.

new Vue({
  el: '#app',

  data: {
   posts: [
    { title: 'apple is best fruit' },
    { title: 'orange is 2020 best fruit' },
    { title: 'apples are sweeter than oranges in 2020' }
   ],
   query: ''
  },

  computed: {
   getFilteredPosts () {
    return this.posts.filter(post => post.title.includes(this.query))
   },
   getFilteredPostsCount () {
    return this.getFilteredPosts.length
   }
  }
})

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

 <input placeholder="search for `apple`" v-model="query"/>
 <br/><br/>

 Filtered posts count: {{ getFilteredPostsCount }}
 <br/><br/>

 Filtered posts:
 <li v-for="(post, i) in getFilteredPosts" :key="i">
  {{ post.title }}
 </li>

</div>


问:
Do you believe the Firefox project should be forked into a developer targeted version?
I've just got this idea that there is a need for a forked version of Firefox that would provide right out of the box tools for web development. Like FireBug, YSlow, FireCookie, LiveHTTPHeaders, etc.

Maybe the fork should only include those extensions or take a further step and implement them in existing chrome.

The reason I'm thinking about this is that right now I have two Firefox profiles. A "browsing" one which has only one extension and a "development" one which has lots and lots of extensions. The advantage is obviously that the former is faster than the latter. Maybe if aimed from the beginning at developers, a forked version would bring some speed improvements and other niceties.

What do you think? Any volunteers?

答: You can always prepare your own Firefox installator...</p>

OwnerDisplayName: Ionut G. Stan

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: Marcin Gil


问:
Setting an existing dictionary's values to all zeros
If I have this dict:

```<code>dict1 = {"Key1": [[1, 3, 4], [2, 5, 8]], "key2": [4, 5]}
</code>```

How can I set all the values to 0?

Output should be like this:

```<code>dict1 = {"Key1": [[0,0,0], [0,0,0]], "key2": [0,0]}
</code>```

答:
you can mutate your dict1 values so that the most inner lists to have only 0 as elements:

```<code>def change_to_zero(nested_list):
    if isinstance(nested_list[0], list):
        for l in nested_list:
            change_to_zero(l)
    else:
         nested_list[::] = [0] * len(nested_list)

change_to_zero(list(dict1.values()))

print(dict1)
</code>```

output:

```<code>{'Key1': [[0, 0, 0], [0, 0, 0]], 'key2': [0, 0]}
</code>```

this approach assumes that your dict values are lists of different levels of nestedness and the most inner list doesn't have lists as elements,  only integers (for your example)

Body:
If I have this dict:

dict1 = {"Key1": [[1, 3, 4], [2, 5, 8]], "key2": [4, 5]}

How can I set all the values to 0?

Output should be like this:

dict1 = {"Key1": [[0,0,0], [0,0,0]], "key2": [0,0]}

Body:
you can mutate your dict1 values so that the most inner lists to have only 0 as elements:

def change_to_zero(nested_list):
    if isinstance(nested_list[0], list):
        for l in nested_list:
            change_to_zero(l)
    else:
         nested_list[::] = [0] * len(nested_list)

change_to_zero(list(dict1.values()))

print(dict1)

output:

{'Key1': [[0, 0, 0], [0, 0, 0]], 'key2': [0, 0]}

this approach assumes that your dict values are lists of different levels of nestedness and the most inner list doesn't have lists as elements,  only integers (for your example)


问:
Why Java synchronized threads printing out of order?
I am running this java thread example :

```<code>public class Locks1 extends Thread {
    private Object lock;
    private int myId;
    public Locks1( Object l, int id ) {
      lock = l; myId = id;
    }
    public void run() {
      synchronized( lock ) {
        for ( int i = 0; i < 3; i++ ) {
          System.out.println( "Thread #" + myId + " is tired" );
        try {
          Thread.currentThread().sleep( 10 );
        } catch ( InterruptedException e ){

        } System.out.println("Thread #" + myId + " is rested" );
      }
    }
  }
    public static void main( String args[] ) {
        Integer lock = new Integer( 0 );
        for ( int i = 0; i < 4; i++ ) {
          new Locks1( lock, i ).start();
        }
    }
}
</code>```

And I am having this result:

```<code>Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
</code>```

I don't understand why it prints in this order. Can anyone please help me to understand why the sequence is 0321 instead of 0123?

Thanks

答:
In your code, the first issue is that lock resource has to be a final object so declare it like this :

```<code>final Integer lock = new Integer( 0 );
</code>```

As without this semantics, different threads might be locking on the different object however operating on the same object.

And an explanation to the behaviour you observed.

While the goal maybe to improve performance overall, using multiple threads always introduces some performance costs compared to the single threaded approach. These include the overhead associated with coordinating between threads(locking, signaling, synchronization),increased context switching,thread creation and teardown, and scheduling overhead. ref.ch-11.1

As stated, locking and context switching and signalling is associated with multithreading as compared to single threaded programs. In your case, the reason you get the sequence "0321" is not something reproducible in another machine for example.

The Thread.start() method invokes the system native method start0 and the system allocates resources and if the thread locks any resources (which it does). As your method takes time (however small) to complete the run() method the other threads are on wait

A simple difference changing your code to this will make a different output. As this introduces differences in the timing and scheduling of which thread the processor resumes and acquires the next lock on Integer lock. In short, this is not a reproducible output and will be different in the 1001 try "may be".

```<code> final Integer lock = new Integer( 0 );
 for ( int i = 0; i < 4; i++ ) {
    System.out.println("starting : " + i);
    new Locks1( lock, i ).start();
 }

</code>```

outputs:

```<code>starting : 0
starting : 1
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
starting : 2
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
starting : 3
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
</code>```

NOTE: This again might not be reproducible in your machine.

Body:
I am running this java thread example :

public class Locks1 extends Thread {
    private Object lock;
    private int myId;
    public Locks1( Object l, int id ) {
      lock = l; myId = id;
    }
    public void run() {
      synchronized( lock ) {
        for ( int i = 0; i < 3; i++ ) {
          System.out.println( "Thread #" + myId + " is tired" );
        try {
          Thread.currentThread().sleep( 10 );
        } catch ( InterruptedException e ){

        } System.out.println("Thread #" + myId + " is rested" );
      }
    }
  }
    public static void main( String args[] ) {
        Integer lock = new Integer( 0 );
        for ( int i = 0; i < 4; i++ ) {
          new Locks1( lock, i ).start();
        }
    }
}

And I am having this result:

Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested

I don't understand why it prints in this order. Can anyone please help me to understand why the sequence is 0321 instead of 0123?

Thanks

Body:
In your code, the first issue is that lock resource has to be a final object so declare it like this :

final Integer lock = new Integer( 0 );

As without this semantics, different threads might be locking on the different object however operating on the same object.

And an explanation to the behaviour you observed.

While the goal maybe to improve performance overall, using multiple threads always introduces some performance costs compared to the single threaded approach. These include the overhead associated with coordinating between threads(locking, signaling, synchronization),increased context switching,thread creation and teardown, and scheduling overhead. ref.ch-11.1

As stated, locking and context switching and signalling is associated with multithreading as compared to single threaded programs. In your case, the reason you get the sequence "0321" is not something reproducible in another machine for example.

The Thread.start() method invokes the system native method start0 and the system allocates resources and if the thread locks any resources (which it does). As your method takes time (however small) to complete the run() method the other threads are on wait

A simple difference changing your code to this will make a different output. As this introduces differences in the timing and scheduling of which thread the processor resumes and acquires the next lock on Integer lock. In short, this is not a reproducible output and will be different in the 1001 try "may be".

 final Integer lock = new Integer( 0 );
 for ( int i = 0; i < 4; i++ ) {
    System.out.println("starting : " + i);
    new Locks1( lock, i ).start();
 }

outputs:

starting : 0
starting : 1
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #0 is tired
Thread #0 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
Thread #1 is tired
Thread #1 is rested
starting : 2
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
Thread #2 is tired
Thread #2 is rested
starting : 3
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested
Thread #3 is tired
Thread #3 is rested

NOTE: This again might not be reproducible in your machine.


问:
Metal: vertexFunction defined in .metal file becomes nil once setting Compiler and Linker Options for MSL cikernel
VertexFunction and FragmentFunction defined in .metal file worked nicely, but they became nil once I specified Compiler and Linker Options following Apple's doc: -fcikernel flag in the Other Metal Compiler Flags option, and -cikernel flat in MTLLINKER_FLAGS in User-Defined setting.

I need the settings above for cikernel with MSL (metal shading language). Indeed, cikernel with Core Image Kernel Language deprecated in 12.0.

How could I use both vertex/fragment Metal shader and MSL cikernel together?

```<code>let library = self.device?.makeDefaultLibrary()!
let pipeLineDescriptor = MTLRenderPipelineDescriptor()
pipeLineDescriptor.vertexFunction=library.makeFunction(name: "myVertexShader")
pipeLineDescriptor.fragmentFunction=library.makeFunction(name: "myFragmentShader")
</code>```

答:
An update of Frank Schlegel's answer that works in Xcode 11, where, as Giraff Wombat mentions, the metal compiler simply ignores input files that don't end in .metal. To make sure the CI kernel file stays out of the regular metal pipeline's way, I made the extension ".mcikernel" and put for the build rule script:

```<code>mkdir -p ${DERIVED_FILES_DIR}/kernels
cp ${INPUT_FILE_PATH} ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.metal
xcrun metal -fcikernel ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.metal -c -o ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.air
xcrun metallib -cikernel -o ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.metallib ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.air
</code>```

Body:
VertexFunction and FragmentFunction defined in .metal file worked nicely, but they became nil once I specified Compiler and Linker Options following Apple's doc: -fcikernel flag in the Other Metal Compiler Flags option, and -cikernel flat in MTLLINKER_FLAGS in User-Defined setting.

I need the settings above for cikernel with MSL (metal shading language). Indeed, cikernel with Core Image Kernel Language deprecated in 12.0.

How could I use both vertex/fragment Metal shader and MSL cikernel together?

let library = self.device?.makeDefaultLibrary()!
let pipeLineDescriptor = MTLRenderPipelineDescriptor()
pipeLineDescriptor.vertexFunction=library.makeFunction(name: "myVertexShader")
pipeLineDescriptor.fragmentFunction=library.makeFunction(name: "myFragmentShader")

Body:
An update of Frank Schlegel's answer that works in Xcode 11, where, as Giraff Wombat mentions, the metal compiler simply ignores input files that don't end in .metal. To make sure the CI kernel file stays out of the regular metal pipeline's way, I made the extension ".mcikernel" and put for the build rule script:

mkdir -p ${DERIVED_FILES_DIR}/kernels
cp ${INPUT_FILE_PATH} ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.metal
xcrun metal -fcikernel ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.metal -c -o ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.air
xcrun metallib -cikernel -o ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.metallib ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.air


问:
Is it possible to replace each capturing group in a regex with a different string
If I have a regex like this: (\.\d+)|([A-Z]\d{2}\.-)

Can I replace capturing group $1 with string a and capturing group $2 with string b within one regex replace?

```<code>preg_replace($pattern, $replace, $value);
</code>```

.123A12.- to Value-aValue-b or .123funA12 to Value-afunValue-b

答:
Of course, just use $1, $2 and so on:

```<code>preg_replace($pattern, "$1_something_else$2", $value);
</code>```

E.g. .123A12.- (which would match your expression) would then be replaced to

```<code>.123_something_elseA12.-
</code>```

Body:
If I have a regex like this: (\.\d+)|([A-Z]\d{2}\.-)

Can I replace capturing group $1 with string a and capturing group $2 with string b within one regex replace?

preg_replace($pattern, $replace, $value);

.123A12.- to Value-aValue-b or .123funA12 to Value-afunValue-b

Body:
Of course, just use $1, $2 and so on:

preg_replace($pattern, "$1_something_else$2", $value);

E.g. .123A12.- (which would match your expression) would then be replaced to

.123_something_elseA12.-


问:
Ansible fail task but continue running
I'm currently writing a bunch of checks for Ansible.

It involves contacting remote machines and performing a check.

Based on the result of this check, I make a decision whether it failed or not.

This is the important bit: the task itself never fails. It merely returns a message. I register the result and then analyze it. And based on that I decide if it's a failure or not.

The thing is, I want to add a flag that allows tests to keep running instead of failing.

So the code looks like this:

```<code>- name: Check fail.
  fail:
    msg: "Test failed"
  when: "failfast_flag and <the actual check>"
</code>```

The problem there is, if I make failfast_flag false, it doesn't output red anymore.

I want it to continue with the next tests, in that case, but I also want it to color red, indicating it's an error/fail.

How do I accomplish this?

EDIT: Thanks for the suggestions, I'll give them a try in a bit.

答:
This is a combination of @edrupado's answer and @Jack's comment.

The idea is to move the error up to the task where you register the value and use a rescue block to fail with an informative message, skipping the fail with a flag.

I have no idea what your actual task to collect data is. I used a dummy example cheking for the presence of a dir/file. You should be able to adapt to you actual scenario.

```<code>---
- name: Dummy POC just to test feasability
  hosts: localhost
  gather_facts: false

  tasks:

    - block:

        - name: Make sure /whatever dir exists
          stat:
            path: /whatever
          register: whatever
          failed_when: not whatever.stat.exists | bool

        - debug:
            msg: "/whatever exists: Good !"

      rescue:

        - fail:
            msg: /whatever dir must exist.
          ignore_errors: "{{ ignore_flag | default(false) | bool }}"

    - block:

        - name: Make sure /tmp dir exists
          stat:
            path: /tmp
          register: tmpdir
          failed_when: not tmpdir.stat.exists | bool

        - debug:
            msg: "/tmp exists: Good !"

      rescue:

        - fail:
            msg: /tmp dir must exist.
          ignore_errors: "{{ ignore_flag | default(false) | bool }}"
</code>```

Which gives:

```<code>$ ansible-playbook /tmp/test.yml

PLAY [Dummy POC just to test feasability] *************************************************************************************************************************************************************************

TASK [Make sure /whatever dir exists] *****************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed_when_result": true, "stat": {"exists": false}}

TASK [fail] *******************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "/whatever dir must exist."}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=1    ignored=0

$ ansible-playbook /tmp/test.yml -e ignore_flag=true

PLAY [Dummy POC just to test feasability] *************************************************************************************************************************************************************************

TASK [Make sure /whatever dir exists] *****************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed_when_result": true, "stat": {"exists": false}}

TASK [fail] *******************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "/whatever dir must exist."}
...ignoring

TASK [Make sure /tmp dir exists] **********************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "/tmp exists: Good !"
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=1
</code>```

Title: Ansible fail task but continue running

Body:
I'm currently writing a bunch of checks for Ansible.

It involves contacting remote machines and performing a check.

Based on the result of this check, I make a decision whether it failed or not.

This is the important bit: the task itself never fails. It merely returns a message. I register the result and then analyze it. And based on that I decide if it's a failure or not.

The thing is, I want to add a flag that allows tests to keep running instead of failing.

So the code looks like this:

- name: Check fail.
  fail:
    msg: "Test failed"
  when: "failfast_flag and <the actual check>"

The problem there is, if I make failfast_flag false, it doesn't output red anymore.

I want it to continue with the next tests, in that case, but I also want it to color red, indicating it's an error/fail.

How do I accomplish this?

EDIT: Thanks for the suggestions, I'll give them a try in a bit.

Body:
This is a combination of @edrupado's answer and @Jack's comment.

The idea is to move the error up to the task where you register the value and use a rescue block to fail with an informative message, skipping the fail with a flag.

I have no idea what your actual task to collect data is. I used a dummy example cheking for the presence of a dir/file. You should be able to adapt to you actual scenario.

---
- name: Dummy POC just to test feasability
  hosts: localhost
  gather_facts: false

  tasks:

    - block:

        - name: Make sure /whatever dir exists
          stat:
            path: /whatever
          register: whatever
          failed_when: not whatever.stat.exists | bool

        - debug:
            msg: "/whatever exists: Good !"

      rescue:

        - fail:
            msg: /whatever dir must exist.
          ignore_errors: "{{ ignore_flag | default(false) | bool }}"

    - block:

        - name: Make sure /tmp dir exists
          stat:
            path: /tmp
          register: tmpdir
          failed_when: not tmpdir.stat.exists | bool

        - debug:
            msg: "/tmp exists: Good !"

      rescue:

        - fail:
            msg: /tmp dir must exist.
          ignore_errors: "{{ ignore_flag | default(false) | bool }}"

Which gives:

$ ansible-playbook /tmp/test.yml

PLAY [Dummy POC just to test feasability] *************************************************************************************************************************************************************************

TASK [Make sure /whatever dir exists] *****************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed_when_result": true, "stat": {"exists": false}}

TASK [fail] *******************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "/whatever dir must exist."}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=1    ignored=0

$ ansible-playbook /tmp/test.yml -e ignore_flag=true

PLAY [Dummy POC just to test feasability] *************************************************************************************************************************************************************************

TASK [Make sure /whatever dir exists] *****************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed_when_result": true, "stat": {"exists": false}}

TASK [fail] *******************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "/whatever dir must exist."}
...ignoring

TASK [Make sure /tmp dir exists] **********************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "/tmp exists: Good !"
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=1


问:
Modelling Cassandra Data Struncture for both real-time and search from all?
My project serves both real-time data and past data. It works like feed, so it shows real-time data through socket and past data(if scroll down) through REST api. To get real-time data efficiently, I set date as partition key and time as clustering key. For real-time service, I think this data structure is well modeled. But I also have to get limited number of recent datas(like pagination), which should able to show whole data if requested. To serve data like recent 0~20 / 20~40 / 40~60 through REST api calls, my data-serving server has to remember what it showed before to load next 20 datas continuously, as bookmark. If it was SQL I would use IDs or page&offset things but I cannot do that with Cassandra. So I tried:

```<code>SELECT * FROM examples WHERE date<='DATEMARK' AND create_at < 'TIMEMARK' AND entities CONTAINS 'something' limit 20 ALLOW FILTERING;
</code>```

But since date is the partition key, I cannot use comparison operation >, <. The past data could be created very far from now.

Can I satisfy my real-time+past requirements with Cassandra? I wonder if I have to make another DB for accessing past data.

答: Yes you can, but you must change your mindset and think like NoSQL patterns, in this scenarios you can save your data in duplicate manner and save your data in other table with another partition key and cluster column that satisfies your needs.</p>

Body:
My project serves both real-time data and past data. It works like feed, so it shows real-time data through socket and past data(if scroll down) through REST api. To get real-time data efficiently, I set date as partition key and time as clustering key. For real-time service, I think this data structure is well modeled. But I also have to get limited number of recent datas(like pagination), which should able to show whole data if requested. To serve data like recent 0~20 / 20~40 / 40~60 through REST api calls, my data-serving server has to remember what it showed before to load next 20 datas continuously, as bookmark. If it was SQL I would use IDs or page&offset things but I cannot do that with Cassandra. So I tried:

SELECT * FROM examples WHERE date<='DATEMARK' AND create_at < 'TIMEMARK' AND entities CONTAINS 'something' limit 20 ALLOW FILTERING;

But since date is the partition key, I cannot use comparison operation >, <. The past data could be created very far from now.

Can I satisfy my real-time+past requirements with Cassandra? I wonder if I have to make another DB for accessing past data.


问:
Delete a value of an array if exist on another array
I have a set of data on the table. Which are all owners.

```<code>  <table class="table">
  <tr>
    <td>
      <button id="John" onclick="deleteVal('John');" type="button"> Delete </button>
    </td>
    <td> <input type="text" name="owner[]" value="John"> John </td>
  </tr>
  <tr>
    <td><button id="Mike" onclick="deleteVal('Mike');" type="button"> Delete </button></td>
    <td> <input type="text" name="owner[]" value="Mike"> Mike </td>
  </tr>
  <tr>
    <td><button id="Sam" onclick="deleteVal('Sam');" type="button"> Delete </button></td>
    <td> <input type="text" name="owner[]" value="Sam"> Sam </td>
  </tr>
</table>
</code>```

When the submit button is clicked all owners are stored to this final_owner field. This is what i've tried.

```<code><button type="submit" id="submit">Submit</button>
FINAL OWNERS: <input type="text" id="final_owner">

 $('#submit').on('click', function() {
      var owner_value = [];
  var del_owners = document.getElementById('deleted_owners').value
      $('input[name="owner[]"]').each(function() {
          owner_value.push($(this).val());
      });
      $("#final_owner").val(owner_value);
});
</code>```

Next is Each time I click Delete Button the owners name is stored to the deleted_owners input field. Which I already made.

My question is how can I remove from the array of final_owner field if the owner is already exist on the delete_owners input field.

```<code><input type="text" id="deleted_owners">.
</code>```

答:
try this  with  add delete buttons

Using Sets
when clicking on add,delete buttons

get our final_owner array from set

```<code>  Array.from(deleted_owner);
</code>```

check live example :
https://codesandbox.io/s/crazy-goldstine-wf01q

Body:
I have a set of data on the table. Which are all owners.

      <button id="John" onclick="deleteVal('John');" type="button"> Delete </button>

     <input type="text" name="owner[]" value="John"> John

    <button id="Mike" onclick="deleteVal('Mike');" type="button"> Delete </button>
     <input type="text" name="owner[]" value="Mike"> Mike

    <button id="Sam" onclick="deleteVal('Sam');" type="button"> Delete </button>
     <input type="text" name="owner[]" value="Sam"> Sam

When the submit button is clicked all owners are stored to this final_owner field. This is what i've tried.

<button type="submit" id="submit">Submit</button>
FINAL OWNERS: <input type="text" id="final_owner">

 $('#submit').on('click', function() {
      var owner_value = [];
  var del_owners = document.getElementById('deleted_owners').value
      $('input[name="owner[]"]').each(function() {
          owner_value.push($(this).val());
      });
      $("#final_owner").val(owner_value);
});

Next is Each time I click Delete Button the owners name is stored to the deleted_owners input field. Which I already made.

My question is how can I remove from the array of final_owner field if the owner is already exist on the delete_owners input field.

<input type="text" id="deleted_owners">.

Body:
try this  with  add delete buttons

Using Sets
when clicking on add,delete buttons

get our final_owner array from set

  Array.from(deleted_owner);

check live example :
https://codesandbox.io/s/crazy-goldstine-wf01q


问:
How can i remove the Deprecation error in sklearn(python3)?
I started working on sklearn recently, i executed a command:

```<code>from sklearn.datasets import fetch_openml
</code>```

it gave an error as:

File "/usr/lib/python3/dist-packages/sklearn/externals/joblib.py", line 1
     import imp
  DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses"

Now i have no clue what to do next.. every other library like matplotlib and pandas are working just fine othr than sklearn. any help would be much appreciated

答:
One way would be just to update your sklearn:

```<code>import sklearn
print(sklearn.__version__)
0.22.1
</code>```

```<code>from sklearn.datasets import fetch_openml
</code>```

No error as you see.

Another way is to silence a warning:

```<code>import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
</code>```

Body:
I started working on sklearn recently, i executed a command:

from sklearn.datasets import fetch_openml

it gave an error as:

File "/usr/lib/python3/dist-packages/sklearn/externals/joblib.py", line 1
     import imp
  DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses"

Now i have no clue what to do next.. every other library like matplotlib and pandas are working just fine othr than sklearn. any help would be much appreciated

Body:
One way would be just to update your sklearn:

import sklearn
print(sklearn.__version__)
0.22.1

from sklearn.datasets import fetch_openml

No error as you see.

Another way is to silence a warning:

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)