问:
RecyclerView inside CoordinatorLayout scrolls before Toolbar is colapsed
I have an image and a recyclerview, and I would like it to scroll as if they were inside a NestedScrollView. But I also want my RecyclerView to recycle the views (not to load everything like in a listview).

To achieve that, I am using a CoordinatorLayout. But it's not working the way that I need.
The RecyclerView is scrolling even when the CollapsibleToolbar is not collapsed.

Could anyone help me figure out what I am doing wrong? I have tried everything I read here on StackOverflow, nothing worked.

I already tried android:nestedScrollingEnabled="true" and "false" as suggested in similar questions. Didn't work.

androidx version: androidx.appcompat:appcompat:1.4.1

```<code><androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ToVisitFragment"
android:id="@+id/to_visit_container">

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:id="@+id/to_visit_coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/to_visit_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:visibility="visible"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/to_visit_collapsing_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/to_visit_map"
                    style="@style/WorldMap"
                    android:contentDescription="@string/world_map"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/to_visit_regions_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="80dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:listitem="@layout/item_region" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/to_visit_button_add"
    style="@style/MyFloatingActionButton"
    android:contentDescription="@string/desc_add_city"
    android:backgroundTint="@color/purple"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />
 </androidx.constraintlayout.widget.ConstraintLayout>
</code>```

EDIT

After @BenjyTec mentioned the recyclerView item layout file, I found the problem. I have another recyclerView inside the item. I had set isScrollContainer to false, but didn't set nestedScrollView to false on the inner recyclerView.

Here is the working code:

item layout:

```<code>    <TextView
        android:id="@+id/region_title"
        style="@style/Title"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:text="América Latina"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/region_country_list"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:isScrollContainer="false"
        android:nestedScrollingEnabled="false"
        android:layout_marginTop="10dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/region_title"
        tools:listitem="@layout/item_country"/>
</code>```

Coordinator Layout:

```<code><androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/to_visit_coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/to_visit_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:visibility="visible"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/to_visit_collapsing_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="pin">

                <ImageView
                    android:id="@+id/to_visit_map"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:scaleType="fitCenter"
                    android:src="@drawable/map_world"
                    android:paddingStart="10dp"
                    android:paddingEnd="10dp"
                    android:background="@color/grey_200"
                    android:contentDescription="@string/world_map"
                    app:layout_constraintDimensionRatio="h,16:11"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/to_visit_regions_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="80dp"
        android:clipToPadding="false"
        tools:listitem="@layout/item_region"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/to_visit_button_add"
        style="@style/MyFloatingActionButton"
        android:contentDescription="@string/desc_add_city"
        android:backgroundTint="@color/purple"
        android:layout_gravity="bottom|end"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</code>```

答:
I've created a small sample app to test out the combination of RecyclerView and CollapsingToolbarLayout. The result I get from the sample app looks like this:

Is that what you want to achieve? If yes, and it still does not work, you might want to show your layout file of the RecyclerView items, as the culprit might be there.

Also, your root ConstraintLayout might be useless. If you only need it to place the FloatingActionButton, you can also achieve the same thing by using CoordinatorLayout attribute layout_gravity, as shown below.

Below is the layout for the sample app:

```<code><androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/to_visit_coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/to_visit_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:visibility="visible"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/to_visit_collapsing_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/to_visit_map"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@drawable/photo"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/to_visit_regions_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="80dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/to_visit_button_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="Description"
        android:layout_margin="@dimen/fab_margin"
        android:layout_gravity="bottom|end" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</code>```

And the layout file for the RecyclerView items:

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>
</code>```

Body:
I have an image and a recyclerview, and I would like it to scroll as if they were inside a NestedScrollView. But I also want my RecyclerView to recycle the views (not to load everything like in a listview).

To achieve that, I am using a CoordinatorLayout. But it's not working the way that I need.
The RecyclerView is scrolling even when the CollapsibleToolbar is not collapsed.

Could anyone help me figure out what I am doing wrong? I have tried everything I read here on StackOverflow, nothing worked.

I already tried android:nestedScrollingEnabled="true" and "false" as suggested in similar questions. Didn't work.

androidx version: androidx.appcompat:appcompat:1.4.1

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ToVisitFragment"
android:id="@+id/to_visit_container">

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:id="@+id/to_visit_coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/to_visit_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:visibility="visible"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/to_visit_collapsing_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/to_visit_map"
                    style="@style/WorldMap"
                    android:contentDescription="@string/world_map"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/to_visit_regions_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="80dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:listitem="@layout/item_region" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/to_visit_button_add"
    style="@style/MyFloatingActionButton"
    android:contentDescription="@string/desc_add_city"
    android:backgroundTint="@color/purple"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />
 </androidx.constraintlayout.widget.ConstraintLayout>

EDIT

After @BenjyTec mentioned the recyclerView item layout file, I found the problem. I have another recyclerView inside the item. I had set isScrollContainer to false, but didn't set nestedScrollView to false on the inner recyclerView.

Here is the working code:

item layout:

    <TextView
        android:id="@+id/region_title"
        style="@style/Title"
        android:layout_marginStart="24dp"
        android:layout_marginTop="24dp"
        android:text="América Latina"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/region_country_list"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:isScrollContainer="false"
        android:nestedScrollingEnabled="false"
        android:layout_marginTop="10dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/region_title"
        tools:listitem="@layout/item_country"/>

Coordinator Layout:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/to_visit_coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/to_visit_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:visibility="visible"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/to_visit_collapsing_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="pin">

                <ImageView
                    android:id="@+id/to_visit_map"
                    android:layout_width="0dp"
                    android:layout_height="0dp"
                    android:scaleType="fitCenter"
                    android:src="@drawable/map_world"
                    android:paddingStart="10dp"
                    android:paddingEnd="10dp"
                    android:background="@color/grey_200"
                    android:contentDescription="@string/world_map"
                    app:layout_constraintDimensionRatio="h,16:11"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/to_visit_regions_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="80dp"
        android:clipToPadding="false"
        tools:listitem="@layout/item_region"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/to_visit_button_add"
        style="@style/MyFloatingActionButton"
        android:contentDescription="@string/desc_add_city"
        android:backgroundTint="@color/purple"
        android:layout_gravity="bottom|end"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Body:
I've created a small sample app to test out the combination of RecyclerView and CollapsingToolbarLayout. The result I get from the sample app looks like this:

Is that what you want to achieve? If yes, and it still does not work, you might want to show your layout file of the RecyclerView items, as the culprit might be there.

Also, your root ConstraintLayout might be useless. If you only need it to place the FloatingActionButton, you can also achieve the same thing by using CoordinatorLayout attribute layout_gravity, as shown below.

Below is the layout for the sample app:

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/to_visit_coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/to_visit_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:visibility="visible"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/to_visit_collapsing_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/to_visit_map"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@drawable/photo"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/to_visit_regions_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="80dp"
        android:clipToPadding="false"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/to_visit_button_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="Description"
        android:layout_margin="@dimen/fab_margin"
        android:layout_gravity="bottom|end" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

And the layout file for the RecyclerView items:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>


来源: stackexchange

问:
Why Conda cannot call correct Python version after activating the environment?
I have the following conda environment under Linux:

```<code>$ conda info -e
# conda environments:
#
py33                     /u21/coyotito/.anaconda/envs/py33
root                  *  /u21/coyotito/.anaconda
</code>```

And py33 is created with this command:

```<code>$ conda create -n py33 python=3.3 anaconda
</code>```

The problem is when I activate py33 it still cannot call Python version 3.3.

```<code>[coyotito@pearl ~]$ source activate py33
(coyotito)[coyotito@pearl ~]$ python --version
Python 2.7.10 :: Anaconda 2.1.0 (64-bit)
(coyotito)[coyotito@pearl ~]$ conda info -e
# conda environments:
#
py33                     /u21/coyotito/.anaconda/envs/py33
root                  *  /u21/coyotito/.anaconda
</code>```

Namely it still calling old python. Notice also that the prompt under bracket is not (py33).

```<code>(coyotito)[coyotito@pearl ~]$ which python
~/.anaconda/bin/python
</code>```

Instead of python in new environment:

```<code>~/.anaconda/envs/py33/bin/python3.3
</code>```

How can I resolve this issue?

Update

My PATH environment in ~/.bash_profile looks like this:

```<code>export PATH=$HOME/.anaconda/bin:$PATH
</code>```

答:
This only happens when you create an environment without specifying any additional packages. I am using Conda 4.10.3

Refer https://github.com/conda/conda/issues/9392#issuecomment-696897058

The following comment from the above link worked in my case:

I noticed that it works if i install a packet when i create the environment.

```<code>antony@antony-fedora : ~/Workspace/tmp : which python /usr/bin/python
antony@antony-fedora : ~/Workspace/tmp : conda create --name my_env
antony@antony-fedora : ~/Workspace/tmp : conda activate my_env
(my_env) antony@antony-fedora : ~/Workspace/tmp : which python
/usr/bin/python
(my_env) antony@antony-fedora : ~/Workspace/tmp : conda create --name my_env pip
(my_env) antony@antony-fedora : ~/Workspace/tmp : conda activate my_env
(my_env) antony@antony-fedora : ~/Workspace/tmp : which python ~/anaconda3/envs/my_env/bin/python
</code>```

Also, recommend adding conda deactivate to the end of your .zshenv or .bash_profile

ContentLicense: CC BY-SA 3.0

Body:
I have the following conda environment under Linux:

$ conda info -e
# conda environments:
#
py33                     /u21/coyotito/.anaconda/envs/py33
root                  *  /u21/coyotito/.anaconda

And py33 is created with this command:

$ conda create -n py33 python=3.3 anaconda

The problem is when I activate py33 it still cannot call Python version 3.3.

[coyotito@pearl ~]$ source activate py33
(coyotito)[coyotito@pearl ~]$ python --version
Python 2.7.10 :: Anaconda 2.1.0 (64-bit)
(coyotito)[coyotito@pearl ~]$ conda info -e
# conda environments:
#
py33                     /u21/coyotito/.anaconda/envs/py33
root                  *  /u21/coyotito/.anaconda

Namely it still calling old python. Notice also that the prompt under bracket is not (py33).

(coyotito)[coyotito@pearl ~]$ which python
~/.anaconda/bin/python

Instead of python in new environment:

~/.anaconda/envs/py33/bin/python3.3

How can I resolve this issue?

Update

My PATH environment in ~/.bash_profile looks like this:

export PATH=$HOME/.anaconda/bin:$PATH

Body:
This only happens when you create an environment without specifying any additional packages. I am using Conda 4.10.3

Refer https://github.com/conda/conda/issues/9392#issuecomment-696897058

The following comment from the above link worked in my case:

I noticed that it works if i install a packet when i create the environment.

antony@antony-fedora : ~/Workspace/tmp : which python /usr/bin/python
antony@antony-fedora : ~/Workspace/tmp : conda create --name my_env
antony@antony-fedora : ~/Workspace/tmp : conda activate my_env
(my_env) antony@antony-fedora : ~/Workspace/tmp : which python
/usr/bin/python
(my_env) antony@antony-fedora : ~/Workspace/tmp : conda create --name my_env pip
(my_env) antony@antony-fedora : ~/Workspace/tmp : conda activate my_env
(my_env) antony@antony-fedora : ~/Workspace/tmp : which python ~/anaconda3/envs/my_env/bin/python

Also, recommend adding conda deactivate to the end of your .zshenv or .bash_profile

ContentLicense: CC BY-SA 4.0


问:
Convert XML to CSV (with node path as header) using XSLT
How can I convert the following XML to CSV using XSLT?

<tXML>

        <Source>XPTO</Source>
        <User_ID>127</User_ID>
        <Message_Type>Ship</Message_Type>
        <Company_ID>105</Company_ID>
        <Msg_Locale>English (United States)</Msg_Locale>
        <Version>2017</Version>

    <Message>
        <Ship>
            <ShipSummary>
                <ComName>XPTO 123</ComName>
                <FacName>6</FacName>
            </ShipSummary>
        </Ship>
    </Message>
</tXML>
```

tXML/Header/Source
tXML/Header/User_ID
tXML/Header/Message_Type
tXML/Header/Company_ID
tXML/Header/Msg_Locale
tXML/Header/Version
tXML/Message/Ship/ShipSummary/ComName
tXML/Message/Ship/ShipSummary/FacName

XPTO
127
Ship
105
English (United States)
2017
XPTO 123
6

How can I get the "node path" for every value, and use that as the header?

答:
When I run the following XSLT with xsltproc, I get your desired output (with one exception, there's an extra blank column at the end).

Much thanks to @Daniel_Haley for their solution to the general problem of printing the node path (please go vote that answer up if you like this).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:strip-space elements="*" />
    <xsl:variable name="delim">;</xsl:variable>

    <xsl:template match="/">

        <xsl:copy>
            <xsl:apply-templates select="node()" mode="header"/>
        </xsl:copy>

        <xsl:text>\n</xsl:text>

        <xsl:copy>
            <xsl:apply-templates select="node()" />
        </xsl:copy>

        <xsl:text>\n</xsl:text>
    </xsl:template>

    <xsl:template match="text()">
        <xsl:copy-of select="." />
        <xsl:value-of select="$delim"/>
    </xsl:template>

    <xsl:template match="text()" mode="header">
        <xsl:for-each select="ancestor::*">
            <xsl:choose>

                <xsl:when test="position() = 1">
                    <xsl:value-of select="local-name()" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat('/',local-name())" />
                </xsl:otherwise>
            </xsl:choose>
            <xsl:if test="(preceding-sibling::*|following-sibling::*)[local-name()=local-name(current())]">
                <xsl:value-of select="concat('[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')" />
            </xsl:if>
        </xsl:for-each>
        <xsl:value-of select="$delim"/>

    </xsl:template>

</xsl:stylesheet>
```

tXML/Header/Source
tXML/Header/User_ID
tXML/Header/Message_Type
tXML/Header/Company_ID
tXML/Header/Msg_Locale
tXML/Header/Version
tXML/Message/Ship/ShipSummary/ComName
tXML/Message/Ship/ShipSummary/FacName

XPTO
127
Ship
105
English (United States)
2017
XPTO 123
6

Body:
How can I convert the following XML to CSV using XSLT?

<tXML>

        <Source>XPTO</Source>
        <User_ID>127</User_ID>
        <Message_Type>Ship</Message_Type>
        <Company_ID>105</Company_ID>
        <Msg_Locale>English (United States)</Msg_Locale>
        <Version>2017</Version>

    <Message>
        <Ship>
            <ShipSummary>
                <ComName>XPTO 123</ComName>
                <FacName>6</FacName>
            </ShipSummary>
        </Ship>
    </Message>
</tXML>

tXML/Header/Source
tXML/Header/User_ID
tXML/Header/Message_Type
tXML/Header/Company_ID
tXML/Header/Msg_Locale
tXML/Header/Version
tXML/Message/Ship/ShipSummary/ComName
tXML/Message/Ship/ShipSummary/FacName

XPTO
127
Ship
105
English (United States)
2017
XPTO 123
6

How can I get the "node path" for every value, and use that as the header?

Body:
When I run the following XSLT with xsltproc, I get your desired output (with one exception, there's an extra blank column at the end).

Much thanks to @Daniel_Haley for their solution to the general problem of printing the node path (please go vote that answer up if you like this).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:strip-space elements="*" />
    <xsl:variable name="delim">;</xsl:variable>

    <xsl:template match="/">
        <!-- Recurse document for header -->
        <xsl:copy>
            <xsl:apply-templates select="node()" mode="header"/>
        </xsl:copy>

        <!-- Linebreak after last column in header -->
        <xsl:text>&#xA;</xsl:text>

        <!-- Recurse document for values -->
        <xsl:copy>
            <xsl:apply-templates select="node()" />
        </xsl:copy>

        <!-- Linebreak after last column in row -->
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

    <xsl:template match="text()">
        <xsl:copy-of select="." />
        <xsl:value-of select="$delim"/>
    </xsl:template>

    <!-- https://stackoverflow.com/a/10112579/246801 -->
    <xsl:template match="text()" mode="header">
        <xsl:for-each select="ancestor::*">
            <xsl:choose>
                <!-- avoid beginning slash (at root) -->
                <xsl:when test="position() = 1">
                    <xsl:value-of select="local-name()" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat('/',local-name())" />
                </xsl:otherwise>
            </xsl:choose>
            <xsl:if test="(preceding-sibling::*|following-sibling::*)[local-name()=local-name(current())]">
                <xsl:value-of select="concat('[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')" />
            </xsl:if>
        </xsl:for-each>
        <xsl:value-of select="$delim"/>
        <!-- <xsl:apply-templates select="node()" /> -->
    </xsl:template>

</xsl:stylesheet>

tXML/Header/Source
tXML/Header/User_ID
tXML/Header/Message_Type
tXML/Header/Company_ID
tXML/Header/Msg_Locale
tXML/Header/Version
tXML/Message/Ship/ShipSummary/ComName
tXML/Message/Ship/ShipSummary/FacName

XPTO
127
Ship
105
English (United States)
2017
XPTO 123
6


问:
Writing all powers of 2 not exceeding given number
here is the code.

```<code>int n,power=2;
cin>>n;
cout<<power<<endl;
while(power<n){
power=power*2;
cout<<power<<endl;
}
</code>```

For example, if i wrote 20, the output should be "2 4 8 16". Instead, it writes me "2 4 8 16 32" What should i change in this code? Thanks.

答:
An alternative suggestion

We can pre-compute the powers of 2, until a defined limit (say 2^30) and then parse the vector again, to print elements not exceeding the given number

```<code>// get the Limit from the user
int limit;
cin >> limit;

std::vector<int> P;
for(int i=1; i<30; i++)
   P.push_back((1 << i));

for(auto c: P)
    if(c < limit)
      std::cout << c << " ";
std::cout << std::endl;
</code>```

Body:
here is the code.

int n,power=2;
cin>>n;
cout<<power<<endl;
while(power<n){
power=power*2;
cout<<power<<endl;
}

For example, if i wrote 20, the output should be "2 4 8 16". Instead, it writes me "2 4 8 16 32" What should i change in this code? Thanks.

Body:
An alternative suggestion

We can pre-compute the powers of 2, until a defined limit (say 2^30) and then parse the vector again, to print elements not exceeding the given number

// get the Limit from the user
int limit;
cin >> limit;

std::vector<int> P;
for(int i=1; i<30; i++)
   P.push_back((1 << i));

for(auto c: P)
    if(c < limit)
      std::cout << c << " ";
std::cout << std::endl;


问:
How to display input value for a date in C
The output has to be printed Date: 2021-FEB-01

After receiving the input month and year value, for example, 2018 January should be displayed 2018-JAN-01.

how could I display YYYY-MMM-DD?

I used else if from Jan to Dec. Is there a simpler code?

```<code>if (month == 1)
   printf("Date: %d-JAN-01\n", year);

else if (month == 2)
   printf("Date: %d-FEB-01\n", year);

...
</code>```

答:
The standard library time.h supports what you are trying to achieve (almost). For example:

```<code>struct tm date = {.tm_mday = 1,
                  .tm_mon = month - 1,       // January == 0
                  .tm_year = year - 1900 } ; // Years since 1900
mktime( &date ) ;
char timstr[] = "YYYY-MMM-DD" ;
strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;

printf( "%s\n", timstr ) ;
</code>```

However the month will be output Mmm rather then MMM, e.g. Jan rather the JAN.  If that is an issue then you might simply coerce the timstr[6] and timstr[7] to upper case thus:

```<code>strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;
timstr[6] = toupper( timstr[6] ) ;
timstr[7] = toupper( timstr[7] ) ;

printf( "%s\n", timstr ) ;
</code>```

or you might define a more generic conversion function for greater flexibility - should you change the format for example:

```<code>#include <ctype.h>

char* strtoupper( char* str )
{
    for( char* cp = str; *cp != 0; cp++ )
    {
        *cp = toupper( *cp ) ;
    }

    return str ;
}
</code>```

then for example:

```<code>printf( "%s\n", strtoupper( timstr ) ) ;
</code>```

A complete example:

```<code>#include <stdio.h>
#include <time.h>
#include <ctype.h>

char* strtoupper( char* str )
{
    for( char* cp = str; *cp != 0; cp++ )
    {
        *cp = toupper( *cp ) ;
    }

    return str ;
}

int main()
{
    int month = 5 ;
    int year = 1967 ;

    struct tm date = {.tm_mday = 1,
                      .tm_mon = month - 1,
                      .tm_year = year - 1900 } ;
    mktime( &date ) ;
    char timstr[] = "YYYY-MMM-DD" ;
    strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;

    printf( "%s\n", strtoupper( timstr ) ) ;

    return 0;
}
</code>```

Outputs:

1967-MAY-01
```
<p>As does:</p>
```#include <stdio.h>
#include <time.h>
#include <ctype.h>

int main()
{
    int month = 5 ;
    int year = 1967 ;

    struct tm date = {.tm_mday = 1,
                      .tm_mon = month - 1,
                      .tm_year = year - 1900 } ;
    mktime( &date ) ;
    char timstr[] = "YYYY-MMM-DD" ;
    strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;
    timstr[6] = toupper( timstr[6] ) ;
    timstr[7] = toupper( timstr[7] ) ;
    printf( "%s\n", timstr ) ;

    return 0;
}
```

Body:
The output has to be printed Date: 2021-FEB-01

After receiving the input month and year value, for example, 2018 January should be displayed 2018-JAN-01.

how could I display YYYY-MMM-DD?

I used else if from Jan to Dec. Is there a simpler code?

if (month == 1)
   printf("Date: %d-JAN-01\n", year);

else if (month == 2)
   printf("Date: %d-FEB-01\n", year);

...

Body:
The standard library time.h supports what you are trying to achieve (almost). For example:

struct tm date = {.tm_mday = 1,
                  .tm_mon = month - 1,       // January == 0
                  .tm_year = year - 1900 } ; // Years since 1900
mktime( &date ) ;
char timstr[] = "YYYY-MMM-DD" ;
strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;

printf( "%s\n", timstr ) ;

However the month will be output Mmm rather then MMM, e.g. Jan rather the JAN.  If that is an issue then you might simply coerce the timstr[6] and timstr[7] to upper case thus:

strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;
timstr[6] = toupper( timstr[6] ) ;
timstr[7] = toupper( timstr[7] ) ;

printf( "%s\n", timstr ) ;

or you might define a more generic conversion function for greater flexibility - should you change the format for example:

#include <ctype.h>

char* strtoupper( char* str )
{
    for( char* cp = str; *cp != 0; cp++ )
    {
        *cp = toupper( *cp ) ;
    }

    return str ;
}

then for example:

printf( "%s\n", strtoupper( timstr ) ) ;

A complete example:

#include <stdio.h>
#include <time.h>
#include <ctype.h>

char* strtoupper( char* str )
{
    for( char* cp = str; *cp != 0; cp++ )
    {
        *cp = toupper( *cp ) ;
    }

    return str ;
}

int main()
{
    int month = 5 ;
    int year = 1967 ;

    struct tm date = {.tm_mday = 1,
                      .tm_mon = month - 1,
                      .tm_year = year - 1900 } ;
    mktime( &date ) ;
    char timstr[] = "YYYY-MMM-DD" ;
    strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;

    printf( "%s\n", strtoupper( timstr ) ) ;

    return 0;
}

Outputs:

1967-MAY-01

As does:

#include <stdio.h>
#include <time.h>
#include <ctype.h>

int main()
{
    int month = 5 ;
    int year = 1967 ;

    struct tm date = {.tm_mday = 1,
                      .tm_mon = month - 1,
                      .tm_year = year - 1900 } ;
    mktime( &date ) ;
    char timstr[] = "YYYY-MMM-DD" ;
    strftime( timstr, sizeof(timstr), "%Y-%b-%d", &date ) ;
    timstr[6] = toupper( timstr[6] ) ;
    timstr[7] = toupper( timstr[7] ) ;
    printf( "%s\n", timstr ) ;

    return 0;
}


问:
Type inference F# - how to generate fresh variables?
i'm trying to develop the algorithm W in f# for type inference, but i would like to understand how to write the function for generating fresh variables properly.

Actually my function is

```<code>let counter = ref -1

let generate_fresh_variable () : string =
    let list_variables = ['a' .. 'z'] |> List.map string
    counter.Value <- !counter + 1
    list_variables.Item(!counter)
</code>```

but i'm not satisfy with this solution, someone can give me other better ideas?

答:
If you wanted to use some more sophisticated F# tricks, you could create an inifinte sequence of names using a sequence expression (which makes it very easy to handle the looping and dealing with >26 names):

```<code>let names = seq {
  for i in Seq.initInfinite id do
    for c in 'a' .. 'z' do
      if i = 0 then yield string c
      else yield string c + string i }
</code>```

A function to get the fresh name would then pick the next name from the sequence. You need to do this using the underlying enumerator. Another nice trick is to hide the state in a local variable and return a function using lambda:

```<code>let freshName =
  let en = names.GetEnumerator()
  fun () ->
    ignore(en.MoveNext())
    en.Current
</code>```

Then just call freshName() as many times as you need.

Body:
i'm trying to develop the algorithm W in f# for type inference, but i would like to understand how to write the function for generating fresh variables properly.

Actually my function is

let counter = ref -1

let generate_fresh_variable () : string =
    let list_variables = ['a' .. 'z'] |> List.map string
    counter.Value <- !counter + 1
    list_variables.Item(!counter)

but i'm not satisfy with this solution, someone can give me other better ideas?

Body:
If you wanted to use some more sophisticated F# tricks, you could create an inifinte sequence of names using a sequence expression (which makes it very easy to handle the looping and dealing with >26 names):

let names = seq {
  for i in Seq.initInfinite id do
    for c in 'a' .. 'z' do
      if i = 0 then yield string c
      else yield string c + string i }

A function to get the fresh name would then pick the next name from the sequence. You need to do this using the underlying enumerator. Another nice trick is to hide the state in a local variable and return a function using lambda:

let freshName =
  let en = names.GetEnumerator()
  fun () ->
    ignore(en.MoveNext())
    en.Current

Then just call freshName() as many times as you need.


问:
What is the name of the feature/syntax that combines curly braces, ampersand and length of character sequences?
I was reading Chapter 9 of the 2nd edition of A Tour of C++ by Bjarne Stroustrup and was puzzled by the use of {&king[0],2} where king is a string variable. I get that it returns the first 2 strings but I don't know what the name is for this to look up more details about it like:

Does the & ampersand indicate that it is a reference or does it switch it to pointer?

In what version was this feature introduced? I know the book is based on C++17 but don't know what version began supporting it.

```<code>// Strings and Regular Expressions
#pragma once
#include <string>

using namespace std;

string cat(string_view sv1, string_view sv2) {
    string res(sv1.length()+sv2.length(), '\0');
    char* p = &res[0];

    for (char c : sv1)                  // one way
        *p++ = c;
    copy(sv2.begin(), sv2.end(), p);    // another way
    return res;
}

void tryCat() {
    string king = "Harold";
    auto s1 = cat(king, "William");             // string and const char*
    auto s2 = cat(king, king);                  // string and string
    auto s3 = cat("Edward", "Stephen"sv);       // const char* and string_view
    auto s4 = cat("Canute"sv, king);
    auto s5 = cat({&king[0],2}, "Henry"sv);     // HaHenry
    auto s6 = cat({&king[0],2}, {&king[2],4});  // Harold
    cout << s6 << endl;
}

int main () {
    tryCat();
}
</code>```

答:
The funcction

```<code>string cat(string_view sv1, string_view sv2) {
</code>```

accepts as its arguments two objects of the type std::string_view.

Such a construction

```<code>{&king[0],2}
</code>```

is used to construct an object of the type std::string_view using the constructor

```<code>constexpr basic_string_view(const charT* str, size_type len);
</code>```

The expression  &king[0] in the above construction has the pointer type char * and yields the address of the first character of a string.

As the variable king is declared like

```<code>string king = "Harold";
</code>```

then in fact the object of the type std::string_view is built from first two characters of the string like "Ha".

Body:
I was reading Chapter 9 of the 2nd edition of A Tour of C++ by Bjarne Stroustrup and was puzzled by the use of {&king[0],2} where king is a string variable. I get that it returns the first 2 strings but I don't know what the name is for this to look up more details about it like:

Does the & ampersand indicate that it is a reference or does it switch it to pointer?

In what version was this feature introduced? I know the book is based on C++17 but don't know what version began supporting it.

// Strings and Regular Expressions
#pragma once
#include <string>

using namespace std;

string cat(string_view sv1, string_view sv2) {
    string res(sv1.length()+sv2.length(), '\0');
    char* p = &res[0];

    for (char c : sv1)                  // one way
        *p++ = c;
    copy(sv2.begin(), sv2.end(), p);    // another way
    return res;
}

void tryCat() {
    string king = "Harold";
    auto s1 = cat(king, "William");             // string and const char*
    auto s2 = cat(king, king);                  // string and string
    auto s3 = cat("Edward", "Stephen"sv);       // const char* and string_view
    auto s4 = cat("Canute"sv, king);
    auto s5 = cat({&king[0],2}, "Henry"sv);     // HaHenry
    auto s6 = cat({&king[0],2}, {&king[2],4});  // Harold
    cout << s6 << endl;
}

int main () {
    tryCat();
}

Body:
The funcction

string cat(string_view sv1, string_view sv2) {

accepts as its arguments two objects of the type std::string_view.

Such a construction

{&king[0],2}

is used to construct an object of the type std::string_view using the constructor

constexpr basic_string_view(const charT* str, size_type len);

The expression  &king[0] in the above construction has the pointer type char * and yields the address of the first character of a string.

As the variable king is declared like

string king = "Harold";

then in fact the object of the type std::string_view is built from first two characters of the string like "Ha".


问:
Add Attributes fields on Inventory Lookup
I want to add the attributes for my inventory lookup on Sales Order and Purchase Order, does anyone know how to? or any ideas?</p>

答:
Updated solution for versions later than 20R1:

Below is the sample scenario to add custom attributes to both CustomerID and InventoryID lookups of Sales Orders (SO301000) screen.

Create the required attributes from Attributes (CS205000) screen.

Add the necessary attribute to the corresponding Customer Classes (AR201000) screen to be added to the CustomerID lookup and to the corresponding Item Classes (IN201000) screen to be added to the InventoryID lookup.

Create a new Attribute class CustomerAttributeSetFieldsAttribute extending CustomerActiveAttribute (since it is used in CustomerID) and override SetColumns by rewriting the same in order to change the FieldList and HeaderList.

public class CustomerAttributeSetFieldsAttribute : CustomerActiveAttribute
{
    public static void SetColumns(PXCache cache, string field, string[] fieldList, string[] headerList)
    {
        PXSelectorAttribute.SetColumns(cache, field, fieldList, headerList);
        foreach (CustomerAttributeSetFieldsAttribute attr in cache.GetAttributes(field).OfType<CustomerAttributeSetFieldsAttribute>())
        {
            attr._FieldList = fieldList;
            attr._HeaderList = headerList;
        }
    }
}
```
<ol start="4">
<li>Override Initialize method and call Activate for activating the attribute by passing proper cache - <em>BAccountR</em> - for <code>CustomerID</code> and <em>InventoryItem</em> - for <code>InventoryID</code>. Also, call SetColumns from the custom attribute for <code>CustomerID</code> <code>CustomerAttributeSetFieldsAttribute</code> and <code>PXSelectorAttribute</code> for <code>InventoryID</code> and pass the cache type (where the lookup is present), field (field name), fieldList (list of names of all the fields including the attributes) and headerList (list of names of all the headers including the attributes).</li>
<li>Override the attributes to merge the newly added attribute to <code>CustomerID</code> by adding <code>CustomerAttributeSetFields</code> to SOOrder_CustomerID_CacheAttached method.</li>
</ol>
<pre class="lang-cs prettyprint-override"><code>public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
    public override void Initialize()
    {
        base.Initialize();
        //for InventoryID lookup
        CR.CRAttributesFieldAttribute.Activate(Base.Caches[typeof(InventoryItem)]);
        PXSelectorAttribute.SetColumns(Base.Caches[typeof(SOLine)],
          "InventoryID", new string[] { "InventoryCD", "Descr", "itemClassID", "Color_ATTRIBUTES" },
           new string[] { "InventoryCD", "Descr", "itemClassID", "$Attributes$-Color" });

        //for CustomerID lookup
        CR.CRAttributesFieldAttribute.Activate(Base.Caches[typeof(BAccountR)]);

        CustomerAttributeSetFieldsAttribute.SetColumns(Base.Caches[typeof(SOOrder)],
          "CustomerID", new string[] { "AcctCD", "acctName", "COMPREV_Attributes" },
           new string[] { "AcctCD", "acctName", "$Attributes$-Company Revenue" });
    }

    [PXMergeAttributes(Method = MergeMethod.Merge)]
    [CustomerAttributeSetFields]
    protected virtual void SOOrder_CustomerID_CacheAttached(PXCache sender)
    {
    }
}
</code>```

Note: Since Customer DAC is derived from BAccount and CustomerActive attribute is derived from Customer, it has the cache type BAccountR and only the attributes which are of the same cache type are available to add to the CustomerID popup. If the user needs to add other attributes of different cache type, it will be better to create a new Attribute and use that instead of CustomerActive.

Body:
Updated solution for versions later than 20R1:

Below is the sample scenario to add custom attributes to both CustomerID and InventoryID lookups of Sales Orders (SO301000) screen.

Create the required attributes from Attributes (CS205000) screen.

Add the necessary attribute to the corresponding Customer Classes (AR201000) screen to be added to the CustomerID lookup and to the corresponding Item Classes (IN201000) screen to be added to the InventoryID lookup.

Create a new Attribute class CustomerAttributeSetFieldsAttribute extending CustomerActiveAttribute (since it is used in CustomerID) and override SetColumns by rewriting the same in order to change the FieldList and HeaderList.

public class CustomerAttributeSetFieldsAttribute : CustomerActiveAttribute
{
    public static void SetColumns(PXCache cache, string field, string[] fieldList, string[] headerList)
    {
        PXSelectorAttribute.SetColumns(cache, field, fieldList, headerList);
        foreach (CustomerAttributeSetFieldsAttribute attr in cache.GetAttributes(field).OfType<CustomerAttributeSetFieldsAttribute>())
        {
            attr._FieldList = fieldList;
            attr._HeaderList = headerList;
        }
    }
}

Override Initialize method and call Activate for activating the attribute by passing proper cache - BAccountR - for CustomerID and InventoryItem - for InventoryID. Also, call SetColumns from the custom attribute for CustomerID CustomerAttributeSetFieldsAttribute and PXSelectorAttribute for InventoryID and pass the cache type (where the lookup is present), field (field name), fieldList (list of names of all the fields including the attributes) and headerList (list of names of all the headers including the attributes).

Override the attributes to merge the newly added attribute to CustomerID by adding CustomerAttributeSetFields to SOOrder_CustomerID_CacheAttached method.

public class SOOrderEntry_Extension : PXGraphExtension<SOOrderEntry>
{
    public override void Initialize()
    {
        base.Initialize();
        //for InventoryID lookup
        CR.CRAttributesFieldAttribute.Activate(Base.Caches[typeof(InventoryItem)]);
        PXSelectorAttribute.SetColumns(Base.Caches[typeof(SOLine)],
          "InventoryID", new string[] { "InventoryCD", "Descr", "itemClassID", "Color_ATTRIBUTES" },
           new string[] { "InventoryCD", "Descr", "itemClassID", "$Attributes$-Color" });

        //for CustomerID lookup
        CR.CRAttributesFieldAttribute.Activate(Base.Caches[typeof(BAccountR)]);

        CustomerAttributeSetFieldsAttribute.SetColumns(Base.Caches[typeof(SOOrder)],
          "CustomerID", new string[] { "AcctCD", "acctName", "COMPREV_Attributes" },
           new string[] { "AcctCD", "acctName", "$Attributes$-Company Revenue" });
    }

    [PXMergeAttributes(Method = MergeMethod.Merge)]
    [CustomerAttributeSetFields]
    protected virtual void SOOrder_CustomerID_CacheAttached(PXCache sender)
    {
    }
}

Note: Since Customer DAC is derived from BAccount and CustomerActive attribute is derived from Customer, it has the cache type BAccountR and only the attributes which are of the same cache type are available to add to the CustomerID popup. If the user needs to add other attributes of different cache type, it will be better to create a new Attribute and use that instead of CustomerActive.


问:
call AWS POST API with AWS Signature Version 4
did someone already called an AWS  Rest API  with AWS Signature Version 4 ?
I'm not sure how to generate this using the hierarchical stage Calling the Rest API  ?
Thank You -</p>

答:
what do you mean by hierarchical stage, do you want to build the whole signature on your own?

Which language are you trying to call it with? There are different packages depending on that, I highly recommend using one of those instead of rebuilding it on your own.

agnostic-aws-signature This worked for me for example...


问:
Merging dataframes in in Python
I am looking for a more efficient way to solve the below problem. I have 1 dataframe which consists of Account Numbers and its parent account. I have another dataframe (taken from a different database) which contains Account Numbers, Parent ID and Account Owner.

The idea is to join the Account Owner from the second dataframe to the first dataframe. While this should be straight forward i.e. doing a left join between both tables, I need to do 2 merges which seems very inefficient way of doing it.

The first join matches on the account number and maps the account owner, then the 2nd join matches on the parent account and populates the account owner. In this example there are 2 rows containing 0 values, they will be left as is.

The reason for 2 checks - if an account doesn't have an owner, it then checks its parent account if it has an owner.

Here is my workings:

Dataframe 1:

```<code>df = pd.DataFrame([[5551455514,555145],
                    [9631475400,963147],
                    [1111111111,111111],
                    [2222222222,222222],
                    [8529875405,852987]],
columns = ['Account','ParentAccount'])
df
</code>```

Dataframe 1 Output:

```<code>Account         ParentAccount
0   5551455514  555145
1   9631475400  963147
2   1111111111  111111
3   2222222222  222222
4   8529875405  852987
</code>```

Dataframe 2:

```<code>df2 = pd.DataFrame([[5551455514,555145,'Name_1'],
                    [9631475400,963147,'Name_2'],
                    [8529871478,852987,'Name_3']],
columns = ['Account','ParentAccount','Account Owner'])
df2
</code>```

Dataframe 2 Output:

```<code>Account         ParentAccount   Account Owner
0   5551455514  555145          Name_1
1   9631475400  963147          Name_2
2   8529871478  852987          Name_3
</code>```

Merging on the Account number, then merging on the parent account:

```<code># left join on account as primary key between both dataframes
df = pd.merge(df, df2, left_on=['Account'], right_on=['Account'],how='left')
# left join on Parent ID as primary key between both dataframes
df = pd.merge(df, df2, left_on=['ParentAccount_x'], right_on=['ParentAccount'],how='left')

# Re-formatting.....
# drop Account column from dataframe 2 as it doesn't need to be include since account already exists in df1
df = df.drop(['ParentAccount_y','Account Owner_x','ParentAccount','Account_y'], axis = 1)
# rename some headers
df.rename(columns = {'Account_x':'Account','ParentAccount_x':'ParentAccount','Account Owner_y':'Account Owner'}, inplace = True)
</code>```

Output:

```<code>Account         ParentAccount   Account Owner
0   5551455514  555145          Name_1
1   9631475400  963147          Name_2
2   1111111111  111111          NaN
3   2222222222  222222          NaN
4   8529875405  852987          Name_3
</code>```

There must be a better way to achieve the above output.

答:
Given your two data frames named df and df2 you can get the desired output by:

```<code>dk = pd.merge(df, df2, how='left', on='ParentAccount').drop(['Account_y'], axis= 1)
dk.rename(columns={'Account_x':'Account'}, inplace=True)
</code>```

This yields:

```<code>    Account ParentAccount   Account Owner
0   5551455514  555145  Name_1
1   9631475400  963147  Name_2
2   1111111111  111111  NaN
3   2222222222  222222  NaN
4   8529875405  852987  Name_3
</code>```

Title: Merging dataframes in in Python

Body:
I am looking for a more efficient way to solve the below problem. I have 1 dataframe which consists of Account Numbers and its parent account. I have another dataframe (taken from a different database) which contains Account Numbers, Parent ID and Account Owner.

The idea is to join the Account Owner from the second dataframe to the first dataframe. While this should be straight forward i.e. doing a left join between both tables, I need to do 2 merges which seems very inefficient way of doing it.

The first join matches on the account number and maps the account owner, then the 2nd join matches on the parent account and populates the account owner. In this example there are 2 rows containing 0 values, they will be left as is.

The reason for 2 checks - if an account doesn't have an owner, it then checks its parent account if it has an owner.

Here is my workings:

Dataframe 1:

df = pd.DataFrame([[5551455514,555145],
                    [9631475400,963147],
                    [1111111111,111111],
                    [2222222222,222222],
                    [8529875405,852987]],
columns = ['Account','ParentAccount'])
df

Dataframe 1 Output:

Account         ParentAccount
0   5551455514  555145
1   9631475400  963147
2   1111111111  111111
3   2222222222  222222
4   8529875405  852987

Dataframe 2:

df2 = pd.DataFrame([[5551455514,555145,'Name_1'],
                    [9631475400,963147,'Name_2'],
                    [8529871478,852987,'Name_3']],
columns = ['Account','ParentAccount','Account Owner'])
df2

Dataframe 2 Output:

Account         ParentAccount   Account Owner
0   5551455514  555145          Name_1
1   9631475400  963147          Name_2
2   8529871478  852987          Name_3

Merging on the Account number, then merging on the parent account:

# left join on account as primary key between both dataframes
df = pd.merge(df, df2, left_on=['Account'], right_on=['Account'],how='left')
# left join on Parent ID as primary key between both dataframes
df = pd.merge(df, df2, left_on=['ParentAccount_x'], right_on=['ParentAccount'],how='left')

# Re-formatting.....
# drop Account column from dataframe 2 as it doesn't need to be include since account already exists in df1
df = df.drop(['ParentAccount_y','Account Owner_x','ParentAccount','Account_y'], axis = 1)
# rename some headers
df.rename(columns = {'Account_x':'Account','ParentAccount_x':'ParentAccount','Account Owner_y':'Account Owner'}, inplace = True)

Output:

Account         ParentAccount   Account Owner
0   5551455514  555145          Name_1
1   9631475400  963147          Name_2
2   1111111111  111111          NaN
3   2222222222  222222          NaN
4   8529875405  852987          Name_3

There must be a better way to achieve the above output.

Body:
Given your two data frames named df and df2 you can get the desired output by:

dk = pd.merge(df, df2, how='left', on='ParentAccount').drop(['Account_y'], axis= 1)
dk.rename(columns={'Account_x':'Account'}, inplace=True)

This yields:

    Account ParentAccount   Account Owner
0   5551455514  555145  Name_1
1   9631475400  963147  Name_2
2   1111111111  111111  NaN
3   2222222222  222222  NaN
4   8529875405  852987  Name_3


问:
JupyterHub Helm install: function "dig" not defined
I tried installing JupyterHub 1.0.1 using Helm 3.4.0, but get this error about a dig function.</p>
```<code>"jupyterhub" already exists with the same configuration, skipping
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jupyterhub" chart repository
Update Complete. ⎈Happy Helming!⎈
Release "jupyterhub" does not exist. Installing it now.
Error: parse error at (jupyterhub/templates/hub/_helpers-passwords.tpl:35): function "dig" not defined
</code>```

答:
If you have Helm version 3.3 and less, then you might face this issue, as dig tool was added to it later to this version. Try upgrading helm to the latest version

Below is the procedure to upgrade helm on LINUX machine

$ wget https://get.helm.sh/helm-v3.8.0-linux-amd64.tar.gz

$ tar -zxvf helm-v3.8.0-linux-amd64.tar.gz

$ mv linux-amd64/helm /usr/local/bin/helm

$ chmod 700 /usr/local/bin/helm

$ exec $SHELL

$ helm version

Body:
I tried installing JupyterHub 1.0.1 using Helm 3.4.0, but get this error about a dig function.

"jupyterhub" already exists with the same configuration, skipping
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jupyterhub" chart repository
Update Complete. ⎈Happy Helming!⎈
Release "jupyterhub" does not exist. Installing it now.
Error: parse error at (jupyterhub/templates/hub/_helpers-passwords.tpl:35): function "dig" not defined


问:
Moving to next form field when full Plotly-Dash Python App
I’m trying to move the focus to the next input field when they reach their max length.
(I’ve heard this called ‘autotabbing’ elsewhere on various stackoverflow pages.)

I’m using dash-bootstrap-components (dbc), but I assume that will not really change the answer vs dcc

The input fields are generated with:

```<code>import dash
from dash import dcc, html, dash_table, Input, Output, State, MATCH, ALL
import dash_bootstrap_components as dbc
from app.data_operations import *

app = dash.Dash()

app.layout = html.Div(

    dbc.Row(
        children=[
            dbc.Col(dbc.Input(id={'identifier': 'form', 'element_id': i}, placeholder='A',
                              type='text', size="lg", maxlength=1, value='')) for i in range(5)
        ],
        justify='between',
    ),
)
</code>```

So far I’ve tried:

adding some random js scripts I found on the internet

a fruitless attempt at using a jQuery package before reading that jQuery doesn’t play nicely with Dash's React.

Is there a Dash / Python solution here?

Or some kind of external script I can add here?

(I’m a real javascript novice, so don't really know how I’d go about writing the functions for that)

答:
This is indeed possible, but the difficulty for me was deferring the javascript execution. pip install dash_defer_js_import does the trick.

My folder structure looks like this:

```<code>Project/
|-- app.py
|-- assets/
|   |-- script.js
</code>```

Any viable content in assets is loaded automatically by Dash, but since the script needs to be deferred, it needs to be ignored when creating the app. (You'd think you can put the script somewhere else but I can't get it to run otherwise for some reason.)

Apart from them that, I just give the element a class name to identify it by. The complete content of app.py looks like this:

import dash
import dash_bootstrap_components as dbc
import dash_defer_js_import as dji
from dash import html

app = dash.Dash(__name__, assets_ignore='script.js')

app.layout = html.Div([
    dbc.Row(
        children=[
            dbc.Col(dbc.Input(id={'identifier': 'form', 'element_id': i}, placeholder='A', className="focus-next",
                              type='text', size="lg", maxlength=1, value='')) for i in range(5)
        ],
        justify='between',
    ),
    dji.Import(src='assets/script.js')
])

app.run_server()
```
<p>In the script, I gather all the elements with the designated class name <code>focus-next</code> and add an event listener that checks if the length of its value equals its <code>maxlength</code> attribute. If yes, focus the next <code>focus-next</code> element in line. Content of <code>assets/script.js</code>:</p>
<pre class="lang-js prettyprint-override"><code>const inputs = document.querySelectorAll('.focus-next')
for (let i = 0; i < inputs.length - 1; i++) {
    inputs[i].addEventListener('input', () => {
        if (String(inputs[i].value).length === parseInt(inputs[i].getAttribute('maxlength')))
            inputs[i + 1].focus()
    })
}
</code>```

Body:
I’m trying to move the focus to the next input field when they reach their max length.
(I’ve heard this called ‘autotabbing’ elsewhere on various stackoverflow pages.)

I’m using dash-bootstrap-components (dbc), but I assume that will not really change the answer vs dcc

The input fields are generated with:

import dash
from dash import dcc, html, dash_table, Input, Output, State, MATCH, ALL
import dash_bootstrap_components as dbc
from app.data_operations import *

app = dash.Dash()

app.layout = html.Div(

    dbc.Row(
        children=[
            dbc.Col(dbc.Input(id={'identifier': 'form', 'element_id': i}, placeholder='A',
                              type='text', size="lg", maxlength=1, value='')) for i in range(5)
        ],
        justify='between',
    ),
)

So far I’ve tried:

adding some random js scripts I found on the internet

a fruitless attempt at using a jQuery package before reading that jQuery doesn’t play nicely with Dash's React.

Is there a Dash / Python solution here?

Or some kind of external script I can add here?

(I’m a real javascript novice, so don't really know how I’d go about writing the functions for that)

Body:
This is indeed possible, but the difficulty for me was deferring the javascript execution. pip install dash_defer_js_import does the trick.

My folder structure looks like this:

Project/
|-- app.py
|-- assets/
|   |-- script.js

Any viable content in assets is loaded automatically by Dash, but since the script needs to be deferred, it needs to be ignored when creating the app. (You'd think you can put the script somewhere else but I can't get it to run otherwise for some reason.)

Apart from them that, I just give the element a class name to identify it by. The complete content of app.py looks like this:

import dash
import dash_bootstrap_components as dbc
import dash_defer_js_import as dji
from dash import html

app = dash.Dash(__name__, assets_ignore='script.js')

app.layout = html.Div([
    dbc.Row(
        children=[
            dbc.Col(dbc.Input(id={'identifier': 'form', 'element_id': i}, placeholder='A', className="focus-next",
                              type='text', size="lg", maxlength=1, value='')) for i in range(5)
        ],
        justify='between',
    ),
    dji.Import(src='assets/script.js')
])

app.run_server()

In the script, I gather all the elements with the designated class name focus-next and add an event listener that checks if the length of its value equals its maxlength attribute. If yes, focus the next focus-next element in line. Content of assets/script.js:

const inputs = document.querySelectorAll('.focus-next')
for (let i = 0; i < inputs.length - 1; i++) {
    inputs[i].addEventListener('input', () => {
        if (String(inputs[i].value).length === parseInt(inputs[i].getAttribute('maxlength')))
            inputs[i + 1].focus()
    })
}


问:
How to use grepl on only part of a string
```<code>Vector<-c("Consider criterion1, criterion2, criterion3, stop considering criterion1,criterion2, criterion3")
Vector2<-c("Consider criterion2, criterion3, stop considering criterion1,criterion2, criterion3")

grepl("criterion1",Vector)
[1] TRUE
</code>```

For this second condition I want to have FALSE as I would like to ignore all characters after the the word stop

```<code>grepl("criterion1",Vector2)
[1] FALSE
</code>```

答:
Few ways to tackle this:

You could remove everything after stop by using sub, to ensure that you only check before stop

```<code>grepl('criterion1', sub('stop.*', '', Vector))
[1]  TRUE

grepl('criterion1', sub('stop.*', '', Vector2))
[1] FALSE
</code>```

Or you could change the pattern altogether to ensure there is no stop before the value being checked.

```<code>grepl('^((?!stop).)*criterion1', Vector, perl = TRUE)
[1] TRUE

grepl('^((?!stop).)*criterion1', Vector2, perl = TRUE)
[1] FALSE
</code>```

Note that grepl is vectorized on x hence we could simply do:

```<code>grepl('^((?!stop).)*criterion1', c(Vector, Vector2), perl = TRUE)
[1]  TRUE FALSE
</code>```

Body:
Vector<-c("Consider criterion1, criterion2, criterion3, stop considering criterion1,criterion2, criterion3")
Vector2<-c("Consider criterion2, criterion3, stop considering criterion1,criterion2, criterion3")

grepl("criterion1",Vector)
[1] TRUE

For this second condition I want to have FALSE as I would like to ignore all characters after the the word stop

grepl("criterion1",Vector2)
[1] FALSE

Body:
Few ways to tackle this:

You could remove everything after stop by using sub, to ensure that you only check before stop

grepl('criterion1', sub('stop.*', '', Vector))
[1]  TRUE

grepl('criterion1', sub('stop.*', '', Vector2))
[1] FALSE

Or you could change the pattern altogether to ensure there is no stop before the value being checked.

grepl('^((?!stop).)*criterion1', Vector, perl = TRUE)
[1] TRUE

grepl('^((?!stop).)*criterion1', Vector2, perl = TRUE)
[1] FALSE

Note that grepl is vectorized on x hence we could simply do:

grepl('^((?!stop).)*criterion1', c(Vector, Vector2), perl = TRUE)
[1]  TRUE FALSE


问:
Vue 3 migrate key per component in template
On vue 2 for place two components side by side in template need be set key per component AND key should be difference (example apply string concat with prefix)

vue 2 work variant

```<code><template v-for="i in items">
                    <trigger   :key="'track_' +i.id" />
                    <otherComp :key="i.id" ></otherComp>
    </template>
</code>```

Now in vue 3 the situation is reversed :D

How can i set difference key like in vue 2 now ?

答:
As the message says, you have to place the key on the template tag.

```<code><template v-for="i in items" :key="i.id">
  <trigger />
  <otherComp />
</template>
</code>```

If for whatever reason you have to add a key on the other components you can do it.

Body:
On vue 2 for place two components side by side in template need be set key per component AND key should be difference (example apply string concat with prefix)

vue 2 work variant

<template v-for="i in items">
                    <trigger   :key="'track_' +i.id" />
                    <otherComp :key="i.id" ></otherComp>
    </template>

Now in vue 3 the situation is reversed :D

How can i set difference key like in vue 2 now ?

Body:
As the message says, you have to place the key on the template tag.

<template v-for="i in items" :key="i.id">
  <trigger />
  <otherComp />
</template>

If for whatever reason you have to add a key on the other components you can do it.


问:
How to check for array in java
I am getting values params[point.id] . i want to check whether params[point.id] is array or not ,how to do this </p>

答: This way: object.getClass().isArray()

Title: How to check for array in java

Body: This way: object.getClass().isArray()


问:
How I can use the differents font size of a *.ttf file?
I downloaded differents *.ttf font files.
In these files there is a lot of available sizes.

However, i see no font-size attributes in the @font-face declaration in css files.

There is style (normal, italic...etc), weight (bold for example), but not any attribute to implement to use the differents size in the file.

```<code>@font-face {
  font-family: 'dragon';
  font-style: normal;
  font-weight: normal;
  src: local('Dragon'), url('./fonts/dragon.ttf') format('truetype');
}
</code>```

Thank you for your help.

答:
Truetype fonts may include glyphs of different styles and weights (so you can specify what the file contains) but they scale so it wouldn't make sense to specify what sizes of fonts the file contains: It contains all of them.

The size-adjust property allows you to apply a multiplier to the scaling so that different fonts can play better together.

Body:
I downloaded differents *.ttf font files.
In these files there is a lot of available sizes.

However, i see no font-size attributes in the @font-face declaration in css files.

There is style (normal, italic...etc), weight (bold for example), but not any attribute to implement to use the differents size in the file.

@font-face {
  font-family: 'dragon';
  font-style: normal;
  font-weight: normal;
  src: local('Dragon'), url('./fonts/dragon.ttf') format('truetype');
}

Thank you for your help.


问:
ASP.NET Core app does not use setting from the appsettings.json, after trying to publish to Azure
My app when executed locally does not read ConnectionString from the appsettings.json.
I had configured "Connected Services" in VS2019 for my ASP.NET Core 3.1 app. Where the SQL DB connection got a wrong DB name (probably got autogenerated). I then have deleted this configuration and ignored it from my profile.
But now when I'm trying to execute this app locally - it is still trying to use DB from that config.

Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot open
database "aspnet-53bc9b9d-9d6a-45d4-1122-2a2761773502" requested by
the login. The login failed.

1. Is there a place it is got cached at or where I need to remove it
manually from?

2. Also why it does not read from my appsettings.json?

appsettings.json:

```<code>**{
  "Serilog": {
    "Using": [
      "Serilog.Sinks.Console",
      "Serilog.Sinks.File",
      "Serilog.Sinks.Seq",
      "Serilog.Sinks.Loggly"
    ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Debug",
        "System": "Debug"
      }
    },
    "Enrich": [
      "FromLogContext",
      "WithMachineName",
      "WithProcessId",
      "WithThreadId"
    ],
    "WriteTo": [
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\ODATA\\Logs\\log.json"
        },
        "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
      }
    ],
    "Properties": {
      "Application": "ODataTestApp"
    }
  },
  "ConnectionStrings": {
    "Database": "Data Source=*MyDBConnectionString*"
  },
  "AllowedHosts": "*",
  "ApplicationInsights": {
    "ConnectionString": "InstrumentationKey=*my-key*/"
  }
}**
</code>```

P.S. I added those Connected Services as part of the Publish to Azure steps. I have tried to Publish my app to Azure, but it failed (for different reasons).

答: It should be appsettings.json.

Body:
My app when executed locally does not read ConnectionString from the appsettings.json.
I had configured "Connected Services" in VS2019 for my ASP.NET Core 3.1 app. Where the SQL DB connection got a wrong DB name (probably got autogenerated). I then have deleted this configuration and ignored it from my profile.
But now when I'm trying to execute this app locally - it is still trying to use DB from that config.

Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot open
database "aspnet-53bc9b9d-9d6a-45d4-1122-2a2761773502" requested by
the login. The login failed.

1. Is there a place it is got cached at or where I need to remove it
manually from?

2. Also why it does not read from my appsettings.json?

appsettings.json:

**{
  "Serilog": {
    "Using": [
      "Serilog.Sinks.Console",
      "Serilog.Sinks.File",
      "Serilog.Sinks.Seq",
      "Serilog.Sinks.Loggly"
    ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Debug",
        "System": "Debug"
      }
    },
    "Enrich": [
      "FromLogContext",
      "WithMachineName",
      "WithProcessId",
      "WithThreadId"
    ],
    "WriteTo": [
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "C:\\ODATA\\Logs\\log.json"
        },
        "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
      }
    ],
    "Properties": {
      "Application": "ODataTestApp"
    }
  },
  "ConnectionStrings": {
    "Database": "Data Source=*MyDBConnectionString*"
  },
  "AllowedHosts": "*",
  "ApplicationInsights": {
    "ConnectionString": "InstrumentationKey=*my-key*/"
  }
}**

P.S. I added those Connected Services as part of the Publish to Azure steps. I have tried to Publish my app to Azure, but it failed (for different reasons).

Body: It should be appsettings.json.


问:
Difference between mockito-core vs mockito-inline
In my project we already have mockito-core dependency. I want to stub static method for which I need to add mockito-inline dependency. So want to understand the difference between them. Can they co-exists?</p>

答:
At least with mockito 3.9 mockito-inline "depends on" mockito-core so...you can declare just mockito-inline...they're not mutually exclusive phew.

https://mvnrepository.com/artifact/org.mockito/mockito-inline/3.9.0


问:
How to implement properly a layer system using Graphics
so im doing a game using custom repaint on a jpanel, with the following implementation

```<code> public synchronized void paintComp(Graphics g) {
        //Buffer is a BufferedImage and it Graphics object
        EnumMap<Layer,Buffer> buffers = new EnumMap<>(Layer.class);
    for (Layer layer : Layer.values()) {
         buffers.put(layer, new Buffer(fsize.x, fsize.y));
    }
        this.ltime = System.currentTimeMillis();
        //there i draw all the game content on buffers' g
        this.scene.render(this, buffers, ltime, 0, 0);
        //then i draw all layers in the right order
        for (Buffer buf : buffers.values()) {
            buf.g.finalize();
            g.drawImage(buf.img, offset.x, offset.y, null);
        }
    }
</code>```

basically, because the game content is organised as a tree, i wanted to draw content on layers then draw those layers on the screen in order to have a better ordering

issue is, i only know how to do that by instantiating 1 bufferedimage per layer each time that function is called, which considering the game is around 60fps and i have 18 layers, i create 1000 bufferedImage per second... is quite suboptimal :')

How could i implement that idea of buffers in a more proper way? i've heard of Rasters, VolatileImage and BufferStrategy but i just couldnt find the infos i needed nor work my way through the javadoc

答: Well, i bypassed that problem by doing lists of things to draw instead of bufferedimages</p>

Body:
so im doing a game using custom repaint on a jpanel, with the following implementation

 public synchronized void paintComp(Graphics g) {
        //Buffer is a BufferedImage and it Graphics object
        EnumMap<Layer,Buffer> buffers = new EnumMap<>(Layer.class);
    for (Layer layer : Layer.values()) {
         buffers.put(layer, new Buffer(fsize.x, fsize.y));
    }
        this.ltime = System.currentTimeMillis();
        //there i draw all the game content on buffers' g
        this.scene.render(this, buffers, ltime, 0, 0);
        //then i draw all layers in the right order
        for (Buffer buf : buffers.values()) {
            buf.g.finalize();
            g.drawImage(buf.img, offset.x, offset.y, null);
        }
    }

basically, because the game content is organised as a tree, i wanted to draw content on layers then draw those layers on the screen in order to have a better ordering

issue is, i only know how to do that by instantiating 1 bufferedimage per layer each time that function is called, which considering the game is around 60fps and i have 18 layers, i create 1000 bufferedImage per second... is quite suboptimal :')

How could i implement that idea of buffers in a more proper way? i've heard of Rasters, VolatileImage and BufferStrategy but i just couldnt find the infos i needed nor work my way through the javadoc


问:
In typescript, how can I safely render an anchor tag in a string as a react component?
In my react application, I am getting data from a database and displaying it on the webpage. One of the data, docs.description is a string like this "Click this link Example".

Currently everything I have tried is just printing out the entire string or just not working. I want to display the text on the site with the links interpreted and displayed as links should be, like: Click this link Example

Here is the section of code if it helps

```<code>export const DocContainer: FC<{docs: AssetDocs}> = ({docs}) => {
  return (
    <div className={styles.docContainer}>
      <Text h2 style={{color:"#26ff91"}}>Docs</Text>
      {docs && docs.description}
    </div>
  );
}
</code>```

Any help would be greatly appreciated! Please let me know if you need more details.

答:
Combining all the valuable input from everyone, I was able to create what I believe to be a safe solution using dangerouslySetInnerHTML combined with sanitizeHtml

```<code>import { Text } from "@zeit-ui/react";
import React, { FC } from "react";
import styles from "./styles.module.css"
import { AssetDocs } from "./types";
import sanitizeHtml from "sanitize-html"

export const DocContainer: FC<{docs: AssetDocs}> = ({docs}) => {

  const createMarkup = () => {
    if (docs.description)
      return {__html: sanitizeHtml(docs.description)};
  }

  return (
    <div className={styles.docContainer}>
      <Text h2 style={{color:"#26ff91"}}>Docs</Text>
      <div dangerouslySetInnerHTML={createMarkup()} />
    </div>
  );
}
</code>```

Thanks everyone!

Body:
In my react application, I am getting data from a database and displaying it on the webpage. One of the data, docs.description is a string like this "Click this link Example".

Currently everything I have tried is just printing out the entire string or just not working. I want to display the text on the site with the links interpreted and displayed as links should be, like: Click this link Example

Here is the section of code if it helps

export const DocContainer: FC<{docs: AssetDocs}> = ({docs}) => {
  return (

      <Text h2 style={{color:"#26ff91"}}>Docs</Text>
      {docs && docs.description}

  );
}

Any help would be greatly appreciated! Please let me know if you need more details.

Body:
Combining all the valuable input from everyone, I was able to create what I believe to be a safe solution using dangerouslySetInnerHTML combined with sanitizeHtml

import { Text } from "@zeit-ui/react";
import React, { FC } from "react";
import styles from "./styles.module.css"
import { AssetDocs } from "./types";
import sanitizeHtml from "sanitize-html"

export const DocContainer: FC<{docs: AssetDocs}> = ({docs}) => {

  const createMarkup = () => {
    if (docs.description)
      return {__html: sanitizeHtml(docs.description)};
  }

  return (
    <div className={styles.docContainer}>
      <Text h2 style={{color:"#26ff91"}}>Docs</Text>
      <div dangerouslySetInnerHTML={createMarkup()} />
    </div>
  );
}

Thanks everyone!


问:
Confused when I should and shouldn't use "const" in C
I have a dictionary that goes like this:

```<code>typedef struct dictNode {
    int key;
    char *value;
    struct dictNode *next;
} Dict;
</code>```

And a get() function that goes like this:

```<code>char *get(const Dict *dict, int key) {
    if(!dict) return NULL;

    Dict *currPtr = dict;

    while(currPtr) {
        if(currPtr->key == key) {
            return currPtr->value;
        }

        currPtr = currPtr->next;
    }
}
</code>```

Compiling this code produces the following error:

dict.c:85: warning: initialization discards qualifiers from pointer target type

This warning refers to the line:

```<code>Dict *currPtr = dict;
</code>```

If I add a "const" before that line like this:

```<code>const Dict *currPtr = dict;
</code>```

The warning goes away...

1) First thing I don't understand is this: I added "const" to the dict argument in get() so that the compiler warns me if I try to change the address dict is pointing to, otherwise I won't be able to access the dictionary in the main program cause I lost the address I was pointing too. Now, I'm creating a new pointer, currPtr, that points to the same place as dict. This way, I use this pointer instead, to traverse the dictionary and keep dict pointer intact. Why do I also need to have const for currPtr?

2) Second thing I don't understand is this: The line currPtr = currPtr->next; is changing the currPtr pointer, so, why doesn't the compile warn me about that if I added a const to currPtr?

Then I have a del() function that goes like this:

```<code>Dict *del(const Dict *dict, int key) {
    if(!dict) return NULL;

    Dict *currPtr = dict;
    Dict *prevPtr = dict;

    while(currPtr) {
        if(currPtr->key == key) {
            prevPtr->next = currPtr->next;
            free(currPtr);
        }

        prevPtr = currPtr;
        currPtr = currPtr->next;
    }

    return dict;
}
</code>```

Please note that I'm aware that this delete function code is not complete, it does not correctly work if I want to delete the first element for instance. It doesn't matter, I'll finish later, it suffices to demonstrate my problem...

3) So, in the get() function I needed to add const to currPtr but in this del() function, I don't need to add const to currPtr nor prevPtr? In both functions I am changing the currPtr pointer and in the case of the del() function I'm changing the prevPtr pointer too. Why does the get() function require me to add a const before currPtr and the del() function does not require me to add a const before currPtr and prevPtr?

I can basically resume this whole post to: When and where exactly in my get() and del() functions should I use const and why, and, when and where I shouldn't?

答:
I think your main confusion comes from misunderstanding the meaning  of

```<code>const char* p;
</code>```

This defines a pointer to a constant character. The address in p can change, but the value pointer cannot. What is forbidden by the compiler is to change *p, not p.

OwnerDisplayName: Nazgulled

ContentLicense: CC BY-SA 2.5

Body:
I have a dictionary that goes like this:

typedef struct dictNode {
    int key;
    char *value;
    struct dictNode *next;
} Dict;

And a get() function that goes like this:

char *get(const Dict *dict, int key) {
    if(!dict) return NULL;

    Dict *currPtr = dict;

    while(currPtr) {
        if(currPtr->key == key) {
            return currPtr->value;
        }

        currPtr = currPtr->next;
    }
}

Compiling this code produces the following error:

dict.c:85: warning: initialization discards qualifiers from pointer target type

This warning refers to the line:

Dict *currPtr = dict;

If I add a "const" before that line like this:

const Dict *currPtr = dict;

The warning goes away...

1) First thing I don't understand is this: I added "const" to the dict argument in get() so that the compiler warns me if I try to change the address dict is pointing to, otherwise I won't be able to access the dictionary in the main program cause I lost the address I was pointing too. Now, I'm creating a new pointer, currPtr, that points to the same place as dict. This way, I use this pointer instead, to traverse the dictionary and keep dict pointer intact. Why do I also need to have const for currPtr?

2) Second thing I don't understand is this: The line currPtr = currPtr->next; is changing the currPtr pointer, so, why doesn't the compile warn me about that if I added a const to currPtr?

Then I have a del() function that goes like this:

Dict *del(const Dict *dict, int key) {
    if(!dict) return NULL;

    Dict *currPtr = dict;
    Dict *prevPtr = dict;

    while(currPtr) {
        if(currPtr->key == key) {
            prevPtr->next = currPtr->next;
            free(currPtr);
        }

        prevPtr = currPtr;
        currPtr = currPtr->next;
    }

    return dict;
}

Please note that I'm aware that this delete function code is not complete, it does not correctly work if I want to delete the first element for instance. It doesn't matter, I'll finish later, it suffices to demonstrate my problem...

3) So, in the get() function I needed to add const to currPtr but in this del() function, I don't need to add const to currPtr nor prevPtr? In both functions I am changing the currPtr pointer and in the case of the del() function I'm changing the prevPtr pointer too. Why does the get() function require me to add a const before currPtr and the del() function does not require me to add a const before currPtr and prevPtr?

I can basically resume this whole post to: When and where exactly in my get() and del() functions should I use const and why, and, when and where I shouldn't?

Body:
I think your main confusion comes from misunderstanding the meaning  of

const char* p;

This defines a pointer to a constant character. The address in p can change, but the value pointer cannot. What is forbidden by the compiler is to change *p, not p.

OwnerDisplayName: David Cournapeau


问:
Google app engine Big table database with Python desktop applications
Just out of curiosity, do Big table can be used as back-end for data storage for DESKTOP applications(stand alone applications).

Suppose a scenario:

Application start and check automatically for Internet access.

Once connection exists, we can perform CRUD operation on Big table through application.

Is this possible? If yes,is there any documents/link available on this.

Thanks,
Sunil

答: You can upload and download data in CSV or XML format through the bulk loader toolhich doesn't solve your problem, w. Alternatively you could develop an API to do your remote CRUD work through.</p>


问:
ios 15 prewarming causing appwillLaunch method when prewarm is done
We had an app in production which was reporting very high time to interact(tti) for ios 15 prewarm.

TTI = timewhenViewController is loaded - mainStartTime

mainStart time is measured inside AppDelegate.swift's willFinishLaunchingWithOptions method like this

```<code>mainStartTime = Date()
</code>```

and when first view controller is loaded we measure tti as

```<code>tti = -(mainStartTime.timeIntervalSinceNow)
</code>```

We observed that for prewarm scenarios mainStartTime was coming very early (approx 2 hours before user even launches the app).

I checked online but found no documentation.
Just wanted to know can it possibly happen that prewarm is calling willFinishLaunchingWithOptions method while prewarming the app.

答:
There is poor documentation about Prewarming:

Prewarming executes an app’s launch sequence up until, but not including, when main() calls UIApplicationMain(::::). https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence#3894431

But prewarming can call both willFinishLaunchingWithOptions and didFinishLaunchingWithOptions from my tests on my iPhone 13 with iOS 15.0.

I’ve created a test app which logs all calls to a string array:

main.swift

var logMessages = [String]()

func addLogMessage(_ text: String) {
    let date = Date().formatted(date: .omitted, time: .standard)
    logMessages.append("\(date): \(text)")
}

autoreleasepool {
    addLogMessage("main.swift")
    UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
}
```
<p><strong>AppDelegate.swift</strong></p>
<pre class="lang-swift prettyprint-override"><code>class AppDelegate: UIResponder, UIApplicationDelegate {

    override init() {
        super.init()
        addLogMessage("AppDelegate.init")
    }

    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        addLogMessage("willFinishLaunchingWithOptions")
        return true
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        addLogMessage("didFinishLaunchingWithOptions")
        return true
    }

    func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
        addLogMessage("applicationProtectedDataDidBecomeAvailable")
    }

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        addLogMessage("configurationForConnecting")
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    …
}
</code>```

SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow? {
        didSet {
            addLogMessage("SceneDelegate.didSet window")
        }
    }

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        addLogMessage("SceneDelegate.willConnectTo")
        guard let _ = (scene as? UIWindowScene) else { return }
    }
    …
}

```
<p>Then did the following:</p>
<ol>
<li>Launch the app</li>
<li>Use it briefly</li>
<li>Force quit the app</li>
<li>Lock my device and leave it for ~30 minutes</li>
<li>Unlock the device</li>
<li>Launch the app again</li>
</ol>
<p>My logs:</p>
```12:28:36 AM: main.swift
12:28:36 AM: AppDelegate.init
12:28:36 AM: willFinishLaunchingWithOptions
12:28:36 AM: didFinishLaunchingWithOptions

12:58:15 AM: applicationProtectedDataDidBecomeAvailable
12:58:15 AM: configurationForConnecting
12:58:15 AM: SceneDelegate.didSet window
12:58:15 AM: SceneDelegate.willConnectTo
12:58:15 AM: viewDidLoad
```

As you can see the system launched my app (prewarm) at 12:28:36 and held in background until my manual start at 12:58:15 and after gave access to protected data and loaded UI.

Body:
We had an app in production which was reporting very high time to interact(tti) for ios 15 prewarm.

TTI = timewhenViewController is loaded - mainStartTime

mainStart time is measured inside AppDelegate.swift's willFinishLaunchingWithOptions method like this

mainStartTime = Date()

and when first view controller is loaded we measure tti as

tti = -(mainStartTime.timeIntervalSinceNow)

We observed that for prewarm scenarios mainStartTime was coming very early (approx 2 hours before user even launches the app).

I checked online but found no documentation.
Just wanted to know can it possibly happen that prewarm is calling willFinishLaunchingWithOptions method while prewarming the app.

Body:
There is poor documentation about Prewarming:

Prewarming executes an app’s launch sequence up until, but not including, when main() calls UIApplicationMain(::::). https://developer.apple.com/documentation/uikit/app_and_environment/responding_to_the_launch_of_your_app/about_the_app_launch_sequence#3894431

But prewarming can call both willFinishLaunchingWithOptions and didFinishLaunchingWithOptions from my tests on my iPhone 13 with iOS 15.0.

I’ve created a test app which logs all calls to a string array:

main.swift

var logMessages = [String]()

func addLogMessage(_ text: String) {
    let date = Date().formatted(date: .omitted, time: .standard)
    logMessages.append("\(date): \(text)")
}

autoreleasepool {
    addLogMessage("main.swift")
    UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
}

AppDelegate.swift

class AppDelegate: UIResponder, UIApplicationDelegate {

    override init() {
        super.init()
        addLogMessage("AppDelegate.init")
    }

    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        addLogMessage("willFinishLaunchingWithOptions")
        return true
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        addLogMessage("didFinishLaunchingWithOptions")
        return true
    }

    func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
        addLogMessage("applicationProtectedDataDidBecomeAvailable")
    }

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        addLogMessage("configurationForConnecting")
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    …
}

SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow? {
        didSet {
            addLogMessage("SceneDelegate.didSet window")
        }
    }

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        addLogMessage("SceneDelegate.willConnectTo")
        guard let _ = (scene as? UIWindowScene) else { return }
    }
    …
}

Then did the following:

Launch the app

Use it briefly

Force quit the app

Lock my device and leave it for ~30 minutes

Unlock the device

Launch the app again

My logs:

12:28:36 AM: main.swift
12:28:36 AM: AppDelegate.init
12:28:36 AM: willFinishLaunchingWithOptions
12:28:36 AM: didFinishLaunchingWithOptions

12:58:15 AM: applicationProtectedDataDidBecomeAvailable
12:58:15 AM: configurationForConnecting
12:58:15 AM: SceneDelegate.didSet window
12:58:15 AM: SceneDelegate.willConnectTo
12:58:15 AM: viewDidLoad

As you can see the system launched my app (prewarm) at 12:28:36 and held in background until my manual start at 12:58:15 and after gave access to protected data and loaded UI.