问:
How to make faster Hyperledger Fabric java Smart Contract install (I want to avoid a timeout)?
I'm trying to deploy a Java Smart Contract on Hyperledger Fabric, and I'm having timeout issues executing the command peer lifecycle chaincode install cp.tar.gz.

The error at the terminal is:

Error: chaincode install failed with status: 500 - error in
  simulation: failed to execute transaction
  baeacb6b68dac2872098105d20cb0398e5ce5b744afd37bf75ab65b0ffc7a754:
  error sending: timeout expired while executing transaction

Monitoring the network, the error occurs like this:

lucid_ganguly|Downloading https://services.gradle.org/distributions/gradle-5.6.2-bin.zip
  peer0.org1.example.com|2020-05-30 03:15:08.175 UTC [endorser]
  callChaincode -> INFO 04d finished chaincode: _lifecycle duration:
  300000ms channel= txID=baeacb6b peer0.org1.example.com|2020-05-30
  03:15:08.176 UTC [endorser] SimulateProposal -> ERRO 04e failed to
  invoke chaincode _lifecycle, error: timeout expired while executing
  transaction

It seems to me that downloading that gradle file is taking too much time. My internet is not so fast, but yesterday it worked fine several times. If I re-execute the command, then the contract is installed correctly, I think because the file is already downloaded into the peer.

Modifying the timeout limit may be avoid the error, but it will still taking a lot of time installing the Smart Contract.

I don't know much about docker. There is some way that the gradle file is not downloaded everytime I restart the network? There is other way to make the install faster?

EDIT: Is it possible that having Kazam open (not recording) make my PC works slower (and perhaps causing timeout)????

答:
This is how hyper ledger works.
1) Your Java code would be gradle project., and when you trigger 'install' in 'cli' container, then the code is simply copied to designated location.
2) Next step would be instantiate. In this step, it is 'gradle build' that actually kicks off and starts downloading all dependencies.

In order to expedite this, first get the 'gradle build' work on your machine. This would result into all depeandancies to be downloaded to your '~/.gradle' folder. Now, 'COPY' this folder to 'hyperledger/fabric-javaenv' docker image, i.e. we are copying all dependencies from your local disk into image. This way, a download from within the docker container would be avoided.

EDIT:
Hope you've cloned the 'fabric samples' code. Once done, go the following location. It is this code that gets installed and instantiated from within the 'cli' container into the peers.

```<code>C:\sw\hlf146-2\fabric-samples\fabcar\java
</code>```

Now perform gradle build. Assuming you have internet accessa and no proxy related harrassment, your build should succeed.

```<code>C:\sw\hlf146-2\fabric-samples\fabcar\java>gradle build
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/6.3/userguide/gradle_daemon.html.
Daemon will be stopped at the end of the build stopping after processing

> Task :buildEnvironment

------------------------------------------------------------
Root project
------------------------------------------------------------

classpath
No dependencies

A web-based, searchable dependency report is available by adding the --scan option.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 16s
1 actionable task: 1 executed
</code>```

Once successful, the gradle build would have downloaded all of the dependancies into following folder

```<code>c:\users\your-user-name\.gradle
</code>```

Hope you have already downloaded fabric images too onto your machine. Dont worry about the sizes of the fabric images in my output below. I was monkeying around and so you see certain images to be 'huge' like 4.58 GB. Also ignore 'dev-peerX.orgX' images below. You'd have them created by the time you get the network UP.

```<code>C:\sw\hlf146-2\fabric-samples\fabcar\java>docker image ls
REPOSITORY                                                                                TAG                 IMAGE ID            CREATED             SIZE
dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   latest              32aca2e8365e        4 hours ago         4.58GB
dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   latest              89f8611e67f7        4 hours ago         4.58GB
hyperledger/fabric-javaenv                                                                               1.4                 190c5452a677        22 hours ago        4.56GB
hyperledger/fabric-ccenv                                                                                1.4                 774f228847d4        36 hours ago        1.79GB
openjdk                                                                                latest              0ce6496aae74        6 weeks ago         497MB
hyperledger/fabric-ca                                                                                1.4                 3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                1.4.6               3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                latest              3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-tools                                                                                1.4.6               0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-tools                                                                                latest              0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-orderer                                                                               1.4                 84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               1.4.6               84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               latest              84eaba5388e7        3 months ago        120MB
hyperledger/fabric-peer                                                                                1.4                 5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                1.4.6               5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                latest              5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-zookeeper                                                                             0.4                 ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             0.4.18              ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             latest              ede9389347db        7 months ago        276MB
hyperledger/fabric-kafka                                                                                0.4                 caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                0.4.18              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                latest              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-couchdb                                                                               0.4                 d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               0.4.18              d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               latest              d369d4eaa0fd        7 months ago        261MB
</code>```

Now in the above image list it is 'hyperledger/fabric-javaenv' image that would be used by HLF to compile your chain code from within the 'cli' container. It is this image that we'd like to enrich with 'c:\users\your-user-name.gradle' dependancies from your machine. Also, at the time of this writing, the 'hyperledger/fabric-javaenv' image was using gradle 4.5 version, and I wanted to use latest gradle version. So, I also copied gradle 6.3 (although Gradle 6.4 was the latest at the time of this writing) too to the 'hyperledger/fabric-javaenv' image.

So for this, in a new folder put a file named 'Dockerfile' (with no file extension) in it with the following contents (from here on I'm assuming you'll have some knowledge on docker, otherwise, you should stop here. Learn some basics of Docker and resume from here).

```<code>FROM hyperledger/fabric-javaenv:1.4
RUN rm -rf /root/.gradle
RUN rm -rf /opt/gradle

ADD ./gradle.zip /opt/
RUN unzip -o /opt/gradle.zip -d /opt/

ADD ./.gradle.zip /root/.gradle/
RUN unzip -o /root/.gradle/.gradle.zip -d /root/.gradle
ENV PATH="/opt/gradle/gradle-6.3/bin:${PATH}"
ENV GRADLE_HOME="opt/gradle/gradle-6.3"
RUN chmod 777 /opt/gradle/gradle-6.3/bin/*
ENV JAVA_HOME="/opt/java/openjdk"
</code>```

Now zip c:\users\your-user-name.gradle folder contents (not the folder itself) as '.gradle.zip' and place it in the above folder. Next also place gradle.zip (this would be gradle software downloaded, and when you unzip this gradle.zip, it should have gradle-6.3 in it, and that would have all of Gradle software. You can edit above 'Dockerfile' to have right accordingly otherwise).

As I'm running all of this on windows, I have 'docker desktop' installed on my machine and selected 'switch to linux containers' too. If you do not have this software, you need to get this installed. Again assuming you are not behind a proxy, you'll not have all of that proxy related harrasment and things should be seamless for Docker installation.

Next we need to 'build' docker image using above 'Dockerfile'.

```<code>Microsoft Windows [Version 10.0.17763.1217]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\sw\hlf-scripts\javaenv-image-2>dir
 Volume in drive C is Windows
 Volume Serial Number is AE8A-E101

 Directory of C:\sw\hlf-scripts\javaenv-image-2

02-06-2020  00:20    <DIR>          .
02-06-2020  00:20    <DIR>          ..
02-06-2020  00:19        68,813,513 .gradle.zip
01-06-2020  21:21               412 Dockerfile
01-06-2020  17:15       101,876,236 gradle.zip

C:\sw\hlf-scripts\javaenv-image-2>docker build .
Sending build context to Docker daemon  170.7MB
Step 1/11 : FROM hyperledger/fabric-javaenv:1.4
 ---> 190c5452a677
Step 2/11 : RUN rm -rf /root/.gradle
 ---> Running in 1bee6799c989
Removing intermediate container 1bee6799c989
 ---> e80c78e7f151
Step 3/11 : RUN rm -rf /opt/gradle
 ---> Running in 8b92d2062a0e
Removing intermediate container 8b92d2062a0e
 ---> 9a8b7ebfd19a
Step 4/11 : ADD ./gradle.zip /opt/
 ---> 6c32d08ac3d6
Step 5/11 : RUN unzip -o /opt/gradle.zip -d /opt/
 ---> Running in db8bbf7af51c
Archive:  /opt/gradle.zip
   creating: /opt/gradle/
   creating: /opt/gradle/gradle-6.3/
   creating: /opt/gradle/gradle-6.3/bin/
  inflating: /opt/gradle/gradle-6.3/bin/gradle
  inflating: /opt/gradle/gradle-6.3/bin/gradle.bat

    ...

  inflating: /opt/gradle/gradle-6.3/lib/xml-apis-1.4.01.jar
  inflating: /opt/gradle/gradle-6.3/LICENSE
  inflating: /opt/gradle/gradle-6.3/NOTICE
  inflating: /opt/gradle/gradle-6.3/README
Removing intermediate container db8bbf7af51c
 ---> 00b1723e518d
Step 6/11 : ADD ./.gradle.zip /root/.gradle/
 ---> 19cab7daafba
Step 7/11 : RUN unzip -o /root/.gradle/.gradle.zip -d /root/.gradle
 ---> Running in cda0aad70e6f
Archive:  /root/.gradle/.gradle.zip
   creating: /root/.gradle/6.3/
   creating: /root/.gradle/6.3/fileChanges/
 extracting: /root/.gradle/6.3/fileChanges/last-build.bin
   creating: /root/.gradle/6.3/fileHashes/

    ...

 extracting: /root/.gradle/vcs-1/gc.properties
   creating: /root/.gradle/workers/
Removing intermediate container cda0aad70e6f
 ---> bd42d756dcf7
Step 8/11 : ENV PATH="/opt/gradle/gradle-6.3/bin:${PATH}"
 ---> Running in 3d84e00c5b82
Removing intermediate container 3d84e00c5b82
 ---> ef445b162906
Step 9/11 : ENV GRADLE_HOME="opt/gradle/gradle-6.3"
 ---> Running in 41c1a2017e9f
Removing intermediate container 41c1a2017e9f
 ---> c77880c756fd
Step 10/11 : RUN chmod 777 /opt/gradle/gradle-6.3/bin/*
 ---> Running in 77eb321c94ce
Removing intermediate container 77eb321c94ce
 ---> 3e4e65c47c61
Step 11/11 : ENV JAVA_HOME="/opt/java/openjdk"
 ---> Running in 4bc72d56e33d
Removing intermediate container 4bc72d56e33d
 ---> eba22c19da02
Successfully built eba22c19da02
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

C:\sw\hlf-scripts\javaenv-image-2>
</code>```

Check docker image list, and you should find the newly crated image in there. In the below list, see the first one, that is the one created now. It has REPOSITORY and TAG as . Observe that the IMAGEID for this newly created image is 'eba22c19da02'.  This would later be used in command below.

```<code>C:\sw\hlf-scripts\javaenv-image-2>docker image ls
REPOSITORY                                                                                TAG                 IMAGE ID            CREATED             SIZE
<none>                                                                                <none>              eba22c19da02        4 minutes ago       4.94GB
dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   latest              32aca2e8365e        5 hours ago         4.58GB
dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   latest              89f8611e67f7        5 hours ago         4.58GB
hyperledger/fabric-javaenv                                                                               1.4                 190c5452a677        22 hours ago        4.56GB
hyperledger/fabric-ccenv                                                                                1.4                 774f228847d4        37 hours ago        1.79GB
openjdk                                                                                latest              0ce6496aae74        6 weeks ago         497MB
hyperledger/fabric-ca                                                                                1.4                 3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                1.4.6               3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                latest              3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-tools                                                                                1.4.6               0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-tools                                                                                latest              0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-orderer                                                                               1.4                 84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               1.4.6               84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               latest              84eaba5388e7        3 months ago        120MB
hyperledger/fabric-peer                                                                                1.4                 5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                1.4.6               5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                latest              5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-zookeeper                                                                             0.4                 ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             0.4.18              ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             latest              ede9389347db        7 months ago        276MB
hyperledger/fabric-kafka                                                                                0.4                 caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                0.4.18              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                latest              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-couchdb                                                                               0.4                 d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               0.4.18              d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               latest              d369d4eaa0fd        7 months ago        261MB
</code>```

Now we want to tell docker to use this newly created image as 'hyperledger/fabric-javaenv' image (which later would be picked up by HLF during HLF network creation). I'm running HLF 1.4 for all of this, and ':1.4' is given in the tag below. After the command is run, you can now observe that 'eba22c19da02' is now populated as 'hyperledger/fabric-javaenv' and TAG as 1.4

```<code>C:\sw\hlf-scripts\javaenv-image-2>docker tag eba22c19da02 hyperledger/fabric-javaenv:1.4

C:\sw\hlf-scripts\javaenv-image-2>docker image ls
REPOSITORY                                                                                TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-javaenv                                                                               1.4                 eba22c19da02        8 minutes ago       4.94GB
dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   latest              32aca2e8365e        5 hours ago         4.58GB
dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   latest              89f8611e67f7        5 hours ago         4.58GB
hyperledger/fabric-ccenv                                                                                1.4                 774f228847d4        37 hours ago        1.79GB
openjdk                                                                                latest              0ce6496aae74        6 weeks ago         497MB
hyperledger/fabric-ca                                                                                1.4                 3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                1.4.6               3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                latest              3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-tools                                                                                1.4.6               0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-tools                                                                                latest              0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-orderer                                                                               1.4                 84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               1.4.6               84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               latest              84eaba5388e7        3 months ago        120MB
hyperledger/fabric-peer                                                                                1.4                 5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                1.4.6               5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                latest              5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-zookeeper                                                                             0.4                 ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             0.4.18              ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             latest              ede9389347db        7 months ago        276MB
hyperledger/fabric-kafka                                                                                0.4                 caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                0.4.18              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                latest              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-couchdb                                                                               0.4                 d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               0.4.18              d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               latest              d369d4eaa0fd        7 months ago        261MB

C:\sw\hlf-scripts\javaenv-image-2>
</code>```

Now proceed with your Java HLF network creation and your chain code install and isntantiate should succeed.

Body:
This is how hyper ledger works.
1) Your Java code would be gradle project., and when you trigger 'install' in 'cli' container, then the code is simply copied to designated location.
2) Next step would be instantiate. In this step, it is 'gradle build' that actually kicks off and starts downloading all dependencies.

In order to expedite this, first get the 'gradle build' work on your machine. This would result into all depeandancies to be downloaded to your '~/.gradle' folder. Now, 'COPY' this folder to 'hyperledger/fabric-javaenv' docker image, i.e. we are copying all dependencies from your local disk into image. This way, a download from within the docker container would be avoided.

EDIT:
Hope you've cloned the 'fabric samples' code. Once done, go the following location. It is this code that gets installed and instantiated from within the 'cli' container into the peers.

C:\sw\hlf146-2\fabric-samples\fabcar\java

Now perform gradle build. Assuming you have internet accessa and no proxy related harrassment, your build should succeed.

C:\sw\hlf146-2\fabric-samples\fabcar\java>gradle build
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/6.3/userguide/gradle_daemon.html.
Daemon will be stopped at the end of the build stopping after processing

> Task :buildEnvironment

------------------------------------------------------------
Root project
------------------------------------------------------------

classpath
No dependencies

A web-based, searchable dependency report is available by adding the --scan option.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 16s
1 actionable task: 1 executed

Once successful, the gradle build would have downloaded all of the dependancies into following folder

c:\users\your-user-name\.gradle

Hope you have already downloaded fabric images too onto your machine. Dont worry about the sizes of the fabric images in my output below. I was monkeying around and so you see certain images to be 'huge' like 4.58 GB. Also ignore 'dev-peerX.orgX' images below. You'd have them created by the time you get the network UP.

C:\sw\hlf146-2\fabric-samples\fabcar\java>docker image ls
REPOSITORY                                                                                TAG                 IMAGE ID            CREATED             SIZE
dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   latest              32aca2e8365e        4 hours ago         4.58GB
dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   latest              89f8611e67f7        4 hours ago         4.58GB
hyperledger/fabric-javaenv                                                                               1.4                 190c5452a677        22 hours ago        4.56GB
hyperledger/fabric-ccenv                                                                                1.4                 774f228847d4        36 hours ago        1.79GB
openjdk                                                                                latest              0ce6496aae74        6 weeks ago         497MB
hyperledger/fabric-ca                                                                                1.4                 3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                1.4.6               3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                latest              3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-tools                                                                                1.4.6               0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-tools                                                                                latest              0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-orderer                                                                               1.4                 84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               1.4.6               84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               latest              84eaba5388e7        3 months ago        120MB
hyperledger/fabric-peer                                                                                1.4                 5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                1.4.6               5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                latest              5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-zookeeper                                                                             0.4                 ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             0.4.18              ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             latest              ede9389347db        7 months ago        276MB
hyperledger/fabric-kafka                                                                                0.4                 caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                0.4.18              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                latest              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-couchdb                                                                               0.4                 d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               0.4.18              d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               latest              d369d4eaa0fd        7 months ago        261MB

Now in the above image list it is 'hyperledger/fabric-javaenv' image that would be used by HLF to compile your chain code from within the 'cli' container. It is this image that we'd like to enrich with 'c:\users\your-user-name.gradle' dependancies from your machine. Also, at the time of this writing, the 'hyperledger/fabric-javaenv' image was using gradle 4.5 version, and I wanted to use latest gradle version. So, I also copied gradle 6.3 (although Gradle 6.4 was the latest at the time of this writing) too to the 'hyperledger/fabric-javaenv' image.

So for this, in a new folder put a file named 'Dockerfile' (with no file extension) in it with the following contents (from here on I'm assuming you'll have some knowledge on docker, otherwise, you should stop here. Learn some basics of Docker and resume from here).

FROM hyperledger/fabric-javaenv:1.4
RUN rm -rf /root/.gradle
RUN rm -rf /opt/gradle

ADD ./gradle.zip /opt/
RUN unzip -o /opt/gradle.zip -d /opt/

ADD ./.gradle.zip /root/.gradle/
RUN unzip -o /root/.gradle/.gradle.zip -d /root/.gradle
ENV PATH="/opt/gradle/gradle-6.3/bin:${PATH}"
ENV GRADLE_HOME="opt/gradle/gradle-6.3"
RUN chmod 777 /opt/gradle/gradle-6.3/bin/*
ENV JAVA_HOME="/opt/java/openjdk"

Now zip c:\users\your-user-name.gradle folder contents (not the folder itself) as '.gradle.zip' and place it in the above folder. Next also place gradle.zip (this would be gradle software downloaded, and when you unzip this gradle.zip, it should have gradle-6.3 in it, and that would have all of Gradle software. You can edit above 'Dockerfile' to have right accordingly otherwise).

As I'm running all of this on windows, I have 'docker desktop' installed on my machine and selected 'switch to linux containers' too. If you do not have this software, you need to get this installed. Again assuming you are not behind a proxy, you'll not have all of that proxy related harrasment and things should be seamless for Docker installation.

Next we need to 'build' docker image using above 'Dockerfile'.

Microsoft Windows [Version 10.0.17763.1217]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\sw\hlf-scripts\javaenv-image-2>dir
 Volume in drive C is Windows
 Volume Serial Number is AE8A-E101

 Directory of C:\sw\hlf-scripts\javaenv-image-2

02-06-2020  00:20    <DIR>          .
02-06-2020  00:20    <DIR>          ..
02-06-2020  00:19        68,813,513 .gradle.zip
01-06-2020  21:21               412 Dockerfile
01-06-2020  17:15       101,876,236 gradle.zip

C:\sw\hlf-scripts\javaenv-image-2>docker build .
Sending build context to Docker daemon  170.7MB
Step 1/11 : FROM hyperledger/fabric-javaenv:1.4
 ---> 190c5452a677
Step 2/11 : RUN rm -rf /root/.gradle
 ---> Running in 1bee6799c989
Removing intermediate container 1bee6799c989
 ---> e80c78e7f151
Step 3/11 : RUN rm -rf /opt/gradle
 ---> Running in 8b92d2062a0e
Removing intermediate container 8b92d2062a0e
 ---> 9a8b7ebfd19a
Step 4/11 : ADD ./gradle.zip /opt/
 ---> 6c32d08ac3d6
Step 5/11 : RUN unzip -o /opt/gradle.zip -d /opt/
 ---> Running in db8bbf7af51c
Archive:  /opt/gradle.zip
   creating: /opt/gradle/
   creating: /opt/gradle/gradle-6.3/
   creating: /opt/gradle/gradle-6.3/bin/
  inflating: /opt/gradle/gradle-6.3/bin/gradle
  inflating: /opt/gradle/gradle-6.3/bin/gradle.bat

    ...

  inflating: /opt/gradle/gradle-6.3/lib/xml-apis-1.4.01.jar
  inflating: /opt/gradle/gradle-6.3/LICENSE
  inflating: /opt/gradle/gradle-6.3/NOTICE
  inflating: /opt/gradle/gradle-6.3/README
Removing intermediate container db8bbf7af51c
 ---> 00b1723e518d
Step 6/11 : ADD ./.gradle.zip /root/.gradle/
 ---> 19cab7daafba
Step 7/11 : RUN unzip -o /root/.gradle/.gradle.zip -d /root/.gradle
 ---> Running in cda0aad70e6f
Archive:  /root/.gradle/.gradle.zip
   creating: /root/.gradle/6.3/
   creating: /root/.gradle/6.3/fileChanges/
 extracting: /root/.gradle/6.3/fileChanges/last-build.bin
   creating: /root/.gradle/6.3/fileHashes/

    ...

 extracting: /root/.gradle/vcs-1/gc.properties
   creating: /root/.gradle/workers/
Removing intermediate container cda0aad70e6f
 ---> bd42d756dcf7
Step 8/11 : ENV PATH="/opt/gradle/gradle-6.3/bin:${PATH}"
 ---> Running in 3d84e00c5b82
Removing intermediate container 3d84e00c5b82
 ---> ef445b162906
Step 9/11 : ENV GRADLE_HOME="opt/gradle/gradle-6.3"
 ---> Running in 41c1a2017e9f
Removing intermediate container 41c1a2017e9f
 ---> c77880c756fd
Step 10/11 : RUN chmod 777 /opt/gradle/gradle-6.3/bin/*
 ---> Running in 77eb321c94ce
Removing intermediate container 77eb321c94ce
 ---> 3e4e65c47c61
Step 11/11 : ENV JAVA_HOME="/opt/java/openjdk"
 ---> Running in 4bc72d56e33d
Removing intermediate container 4bc72d56e33d
 ---> eba22c19da02
Successfully built eba22c19da02
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

C:\sw\hlf-scripts\javaenv-image-2>

Check docker image list, and you should find the newly crated image in there. In the below list, see the first one, that is the one created now. It has REPOSITORY and TAG as . Observe that the IMAGEID for this newly created image is 'eba22c19da02'.  This would later be used in command below.

C:\sw\hlf-scripts\javaenv-image-2>docker image ls
REPOSITORY                                                                                TAG                 IMAGE ID            CREATED             SIZE
<none>                                                                                <none>              eba22c19da02        4 minutes ago       4.94GB
dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   latest              32aca2e8365e        5 hours ago         4.58GB
dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   latest              89f8611e67f7        5 hours ago         4.58GB
hyperledger/fabric-javaenv                                                                               1.4                 190c5452a677        22 hours ago        4.56GB
hyperledger/fabric-ccenv                                                                                1.4                 774f228847d4        37 hours ago        1.79GB
openjdk                                                                                latest              0ce6496aae74        6 weeks ago         497MB
hyperledger/fabric-ca                                                                                1.4                 3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                1.4.6               3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                latest              3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-tools                                                                                1.4.6               0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-tools                                                                                latest              0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-orderer                                                                               1.4                 84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               1.4.6               84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               latest              84eaba5388e7        3 months ago        120MB
hyperledger/fabric-peer                                                                                1.4                 5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                1.4.6               5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                latest              5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-zookeeper                                                                             0.4                 ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             0.4.18              ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             latest              ede9389347db        7 months ago        276MB
hyperledger/fabric-kafka                                                                                0.4                 caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                0.4.18              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                latest              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-couchdb                                                                               0.4                 d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               0.4.18              d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               latest              d369d4eaa0fd        7 months ago        261MB

Now we want to tell docker to use this newly created image as 'hyperledger/fabric-javaenv' image (which later would be picked up by HLF during HLF network creation). I'm running HLF 1.4 for all of this, and ':1.4' is given in the tag below. After the command is run, you can now observe that 'eba22c19da02' is now populated as 'hyperledger/fabric-javaenv' and TAG as 1.4

C:\sw\hlf-scripts\javaenv-image-2>docker tag eba22c19da02 hyperledger/fabric-javaenv:1.4

C:\sw\hlf-scripts\javaenv-image-2>docker image ls
REPOSITORY                                                                                TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-javaenv                                                                               1.4                 eba22c19da02        8 minutes ago       4.94GB
dev-peer0.org2.example.com-fabcar-1.0-264b0a1cb5efbecaac5cf8990339c24474dc8435c6e10f10f2be565d555d0e94   latest              32aca2e8365e        5 hours ago         4.58GB
dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba   latest              89f8611e67f7        5 hours ago         4.58GB
hyperledger/fabric-ccenv                                                                                1.4                 774f228847d4        37 hours ago        1.79GB
openjdk                                                                                latest              0ce6496aae74        6 weeks ago         497MB
hyperledger/fabric-ca                                                                                1.4                 3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                1.4.6               3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-ca                                                                                latest              3b96a893c1e4        3 months ago        150MB
hyperledger/fabric-tools                                                                                1.4.6               0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-tools                                                                                latest              0f9743ac0662        3 months ago        1.49GB
hyperledger/fabric-orderer                                                                               1.4                 84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               1.4.6               84eaba5388e7        3 months ago        120MB
hyperledger/fabric-orderer                                                                               latest              84eaba5388e7        3 months ago        120MB
hyperledger/fabric-peer                                                                                1.4                 5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                1.4.6               5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-peer                                                                                latest              5a52faa5d8c2        3 months ago        128MB
hyperledger/fabric-zookeeper                                                                             0.4                 ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             0.4.18              ede9389347db        7 months ago        276MB
hyperledger/fabric-zookeeper                                                                             latest              ede9389347db        7 months ago        276MB
hyperledger/fabric-kafka                                                                                0.4                 caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                0.4.18              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-kafka                                                                                latest              caaae0474ef2        7 months ago        270MB
hyperledger/fabric-couchdb                                                                               0.4                 d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               0.4.18              d369d4eaa0fd        7 months ago        261MB
hyperledger/fabric-couchdb                                                                               latest              d369d4eaa0fd        7 months ago        261MB

C:\sw\hlf-scripts\javaenv-image-2>

Now proceed with your Java HLF network creation and your chain code install and isntantiate should succeed.


来源: stackexchange

问:
Java: Handling ' - ' character in custom component text field
I have a custom text field that only accepts numbers in it.

Everything works fine except when I try to handle the negative (-) sign.

```<code>public void processKeyEvent(KeyEvent ev) {

   char c = ev.getKeyChar();
   [...]

   if(c == '-' && getDocument().getLength() > 0 ){
      ev.consume();
   }else{
      super.processKeyEvent(ev);
   }
}
</code>```

This works fine when I start with the sign - but not when I already have numbers and want to add a - in front.

What I really need is a way to get the position at which this character is inserted but I can't find that.

Any ideas?

答:
You can get the current position inside a text field via the method JTextComponent.getCaretPosition().

It might be easier to fulfill this task with either a DocumentListener or an InputVerifier on your text component.

ContentLicense: CC BY-SA 3.0

Body:
I have a custom text field that only accepts numbers in it.

Everything works fine except when I try to handle the negative (-) sign.

public void processKeyEvent(KeyEvent ev) {

   char c = ev.getKeyChar();
   [...]

   if(c == '-' && getDocument().getLength() > 0 ){
      ev.consume();
   }else{
      super.processKeyEvent(ev);
   }
}

This works fine when I start with the sign - but not when I already have numbers and want to add a - in front.

What I really need is a way to get the position at which this character is inserted but I can't find that.

Any ideas?


问:
Yes(1)/No(0) output by applying multiple conditions in excel
I've been given Product Id against the order ids. Product Ids and Order Ids are provided in two different columns, adjacent to each other. The output expected out of the "Information Provided" table is that for all the order ids, which all product ids have been purchased. If purchased, then 1, otherwise it should be 0. The expected output is filled for A and B order ids. And this whole table should be automated.

Assume the Information Table is provided in the given format i.e., 2 columns for Product Ids and 2 columns for Order id.

I tried doing it through if and And function, but the output is 0 even for those which are actually present. Kindly help me out how to automate the binary output.

The tables are shown in the image file.

答:
Binary COUNTIFS

For columns A, B, C, D and the results starting in cell G2:

```<code>=1*OR(COUNTIFS($A$2:$A$11,G$1,$B$2:$B$11,$F2),COUNTIFS($C$2:$C$11,G$1,$D$2:$D$11,$F2))
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Binary COUNTIFS

For columns A, B, C, D and the results starting in cell G2:

=1*OR(COUNTIFS($A$2:$A$11,G$1,$B$2:$B$11,$F2),COUNTIFS($C$2:$C$11,G$1,$D$2:$D$11,$F2))


问:
Is there any way to emulate inline let expressions in JavaScript?
I'm writing a compiler from a functional language to JavaScript. Since my language is based on expressions, it is natural to compile it to a JavaScript expression too. The problem is that when compiling let expressions, we need the ability to declare and assign variables "inline". For example:

```<code>function foo(x) {
  return (let y = x * x; y);
}
</code>```

This code, obviously, doesn't work since we can't use let inside expressions. One solution would be to wrap everything inside a lambda:

```<code>function foo(x) {
  return (()=>{let y = x*x; return y})();
}
</code>```

But this has a significant runtime cost in some cases. The other alternative would be to just adjust the compiler to produce statements instead of expressions, but this would be a non-trivial change and I'd rather avoid it if possible.

Is there any way to declare and assign local variables to JavaScript as an expression rather than a statement that has no extra runtime costs?

答:
No, there is not.

You should consider using the standard lambda calculus technique where let x = … in … is equivalent to (x => …)(…). Then have another pass of your compiler remove the superfluous function expressions, introducing statements where possible.

An alternative might be to use the do { let x = …; … } syntax from the do expressions proposal, allowing you to use their transpiler plugin for generating function-less code.

Body:
I'm writing a compiler from a functional language to JavaScript. Since my language is based on expressions, it is natural to compile it to a JavaScript expression too. The problem is that when compiling let expressions, we need the ability to declare and assign variables "inline". For example:

function foo(x) {
  return (let y = x * x; y);
}

This code, obviously, doesn't work since we can't use let inside expressions. One solution would be to wrap everything inside a lambda:

function foo(x) {
  return (()=>{let y = x*x; return y})();
}

But this has a significant runtime cost in some cases. The other alternative would be to just adjust the compiler to produce statements instead of expressions, but this would be a non-trivial change and I'd rather avoid it if possible.

Is there any way to declare and assign local variables to JavaScript as an expression rather than a statement that has no extra runtime costs?


问:
Overlapping/crowded labels on y-axis python
I'am kind of in a rush to finish this for tomorrows presentation towards the project owner. We are a small group of economic students in germany trying to figure out machine learning with python. We set up a Random Forest Classifier and are desperate to show the estimators important features in a neat plot. By applying google search we came up with the following solution that kind of does the trick, but leaves us unsatisfied due to the overlapping of the labels on the y-axis. The code we used looks like this:

```<code>feature_importances = clf.best_estimator_.feature_importances_
feature_importances = 100 * (feature_importances / feature_importances.max())
sorted_idx = np.argsort(feature_importances)

pos = np.arange(sorted_idx.shape[0])
plt.barh(pos, feature_importances[sorted_idx], align='center', height=0.8)
plt.yticks(pos, df_year_four.columns[sorted_idx])
plt.show()
</code>```

Due to privacy let me say this: The feature names on the y-axis are overlapping (there are about 30 of them). I was looking into the documentation of matplotlib in order to get an understanding of how to do this by myself, unfortunately I couldn't find anything helpful. Seems like training and testing models is easier than understanding matplotlib and creating plots :D

Thank you so much for helping out and taking the time, I appreciate it.

答:
You are using np.argsort that will return a numpy array with many indices. And you are using that array as labels for your Y-Axis thus there is overlapping of labels.

My suggestion will be to use an index for sorted_idx like,

plt.yticks(pos, df_year_four.columns[sorted_idx[0]])

This will plot only for 1 label.

Body:
I'am kind of in a rush to finish this for tomorrows presentation towards the project owner. We are a small group of economic students in germany trying to figure out machine learning with python. We set up a Random Forest Classifier and are desperate to show the estimators important features in a neat plot. By applying google search we came up with the following solution that kind of does the trick, but leaves us unsatisfied due to the overlapping of the labels on the y-axis. The code we used looks like this:

feature_importances = clf.best_estimator_.feature_importances_
feature_importances = 100 * (feature_importances / feature_importances.max())
sorted_idx = np.argsort(feature_importances)

pos = np.arange(sorted_idx.shape[0])
plt.barh(pos, feature_importances[sorted_idx], align='center', height=0.8)
plt.yticks(pos, df_year_four.columns[sorted_idx])
plt.show()

Due to privacy let me say this: The feature names on the y-axis are overlapping (there are about 30 of them). I was looking into the documentation of matplotlib in order to get an understanding of how to do this by myself, unfortunately I couldn't find anything helpful. Seems like training and testing models is easier than understanding matplotlib and creating plots :D

Thank you so much for helping out and taking the time, I appreciate it.


问:
How to make function?
```<code>plt.figure(1)
plt.subplot(121)
sns.distplot(df['Age'])
plt.subplot(122)
df['Age'].plot.box(figsize=(16,5))
plt.show()
</code>```

The only changes from one plot to another is the variable name (Age, Day_Scheduled...).  You could create a function that accepts the dataframe df and the variable's name as arguments and creates a plot. This way, every time you need to do this exact same plot, but using different variables, you can do just by calling this custom function, using something like

function_name(dataframe = df, variable = "Day_Scheduled")

答:
Define the function like this:

```<code>def make_figure(dataframe=df, variable="Day_Scheduled"):
    plt.figure(1)
    plt.subplot(121)
    sns.distplot(dataframe[variable])
    plt.subplot(122)
    dataframe[variable].plot.box(figsize=(16,5))
    plt.show()
</code>```

And call it like this to generate a new figure for each variable:

```<code>field_names = ["Age", "Day_Scheduled"]
for name in field_names:
    make_figure(df, name)
</code>```

Title: How to make function?

Body:
plt.figure(1)
plt.subplot(121)
sns.distplot(df['Age'])
plt.subplot(122)
df['Age'].plot.box(figsize=(16,5))
plt.show()

The only changes from one plot to another is the variable name (Age, Day_Scheduled...).  You could create a function that accepts the dataframe df and the variable's name as arguments and creates a plot. This way, every time you need to do this exact same plot, but using different variables, you can do just by calling this custom function, using something like

function_name(dataframe = df, variable = "Day_Scheduled")

Body:
Define the function like this:

def make_figure(dataframe=df, variable="Day_Scheduled"):
    plt.figure(1)
    plt.subplot(121)
    sns.distplot(dataframe[variable])
    plt.subplot(122)
    dataframe[variable].plot.box(figsize=(16,5))
    plt.show()

And call it like this to generate a new figure for each variable:

field_names = ["Age", "Day_Scheduled"]
for name in field_names:
    make_figure(df, name)


答:
You can use this strategy.

First use your starting timestamp as a constant: 1577833200.0

Create a subquery with the common minute where happen the action:

```<code>((1577833200.0 - 1577833200.0) /60) = 0
((1577833201.0 - 1577833200.0) /60) = 0
((1577833202.0 - 1577833200.0) /60) = 0
...
...
((1577833261.0 - 1577833200.0) /60) = 1
</code>```

This calculation will output the same value for the concurrent records that happen in the same minute.

Then you need to create another query grouped by the minute value

```<code>select minute, avg(tel1) as avg_tel1, avg(tel2) as avg_tel2 from
  (select ((`timestamp` - 1577833200.0) / 60) as minute, tel1, tel2 from plik3 as temp)
group by minute;
</code>```

Title: Counting the average for many rows

Body:
Each line is a second (timestamp increases by a second)
I want to calculate the average values for tel1 and tel2 for every minute.
Can you help?

CREATE TABLE "plik3" (
    "timestamp" REAL,
    "tel1"  REAL,
    "tel2"  REAL
);

1577833200.0    0.0         0.0
1577833201.0    0.0         0.0
1577833202.0    0.4000317   0.0
1577833203.0    0.80006206  0.80006146
1577833204.0    0.0         0.40002593
1577833205.0    0.400032    0.0
1577833206.0    0.800055    0.400024
1577833207.0    0.0         1.2000787
1577833208.0    0.40002337  0.8000576
1577833209.0    0.0         0.40002495
1577833210.0    0.0         0.0
1577833211.0    0.4000275   0.0
1577833212.0    0.400032    0.40003648
1577833213.0    0.0         1.2000787
1577833214.0    0.0         0.40003487
1577833215.0    0.8000595   0.0
1577833216.0    0.40002593  0.40003297

the base is large. 13,046,098 lines

Body:
You can use this strategy.

First use your starting timestamp as a constant: 1577833200.0

Create a subquery with the common minute where happen the action:

((1577833200.0 - 1577833200.0) /60) = 0
((1577833201.0 - 1577833200.0) /60) = 0
((1577833202.0 - 1577833200.0) /60) = 0
...
...
((1577833261.0 - 1577833200.0) /60) = 1

This calculation will output the same value for the concurrent records that happen in the same minute.

Then you need to create another query grouped by the minute value

select minute, avg(tel1) as avg_tel1, avg(tel2) as avg_tel2 from
  (select ((`timestamp` - 1577833200.0) / 60) as minute, tel1, tel2 from plik3 as temp)
group by minute;


问:
Is there a way to have one DB set to Antelope and another DB set to Barracuda on the same shared hosting server?
Now my MySQL (5.6) uses Antelope as the file format. for another system I need the DB to be set to Barracuda file format.

Is there a way to have one DB set to Antelope and another DB set to Barracuda on the same shared hosting server?

The same question regarding innodb_large_prefix - can I set it only to one DB in a shared hosting server without changing it to all the DB on this shared hosting server?

Thanks!
Ram

答:
You cannot have two instances of MySQL talking to the same set of files.  Not even if everything is identical.

You can have two instances of MySQL, each with its own, separate, copy of the data.

You can have two instances of MySQL, one "replicating" from the other, with the same data, but separate disk files for this copies of the data.

When a single instance of MySQL is running with Barracuda, it can (in theory) have some tables that are using Antelope.  The VARIABLE in my.cnf controls the "max".  That is, when set to B, it can handle A or B.  When set to A, it cannot handle B.  (Note: they eventually eliminated both.)

Which do you really want?

innodb_large_prefix is related.  (Note, also, that it has been removed in a later release.)  Perhaps this is really what you need -- 5 ways to deal with a certain error:  http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes


问:
Use Parameterized Selector (Selector Factory) in React Functional Components with useSelector from React-Redux

Parameterized selector / selector factory

It's a function accepts parameters to generate selector, as we can imagine, each time the function is called, a new selector is generated, see below example:

const makeGetSomeSelector = ({ param1, param2, ...}) =>
    createSelector(
       parentSelector,        // suppose it's declared before
       result =>  result.getIn([param1, param2, ...], defaultValue)
    )
```

<h3>General case</h3>

<p>Now, we want to use it in React functional component, and since react-redux introduced useSelector, and based on its provided example, in component it should be look like this:</p>

<pre class="lang-js prettyprint-override"><code>import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';

const MyComponent = ({ param1, param2, ... }) => {
    const getSomeSelector = useMemo(
       () => makeGetSomeSelector({param1, param2, ...}),
       [param1, param2, ...]
    );
    const selectorResult = useSelector(getSomeSelector);
    ...
}
</code>```

Case when it comes to constants

So far, everything make sense. However, there is a case that the parameters are not dynamic (e.g. from props, states, etc.), instead, they are constants! Then it becomes:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';
import { const1, const2, ... } from 'XXX/constants.js';

const MyComponent = () => {
    const getSomeSelector = useMemo(
       () => makeGetSomeSelector({const1, const2, ...}),
       []          // note that here we don't have any dependencies.
    );
    const selectorResult = useSelector(getSomeSelector);
    ...
}
```

<p>However someone asked me why not use the following way:</p>

<pre class="lang-js prettyprint-override"><code>import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';
import { const1, const2, ... } from 'XXX/constants.js';

const getSomeSelector = makeGetSomeSelector({const1, const2, ...});
// declare outside of component, since all params are just constants.

const MyComponent = () => {
    const selectorResult = useSelector(getSomeSelector);
    ...
}
</code>```

Question

Which one is correct one or both are fine?

The correctness means the result (and potentially, all intermediate results) of selector is indeed memorized/cached and won't lead to some problem like new selector is created and lost memoize feature?

If anyone could elaborate how the selector factory works with useSelector (beside react-redux's example) will be more helpful!

答:
The static selector can be used when it is called only once. For example: you have a list of items that can be filtered. The items are in state.data and the filters come from props then you can do something like this:

```<code>import { createSelector, defaultMemoize } from 'reselect';
const makeMemArray = () => {
  const mem = defaultMemoize((...array) => array);
  return (...array) => mem.apply(undefined, array);
};
const createSelectFilteredData = createSelector(
  (filter) => filter,
  (filter) => {
    const memArray = makeMemArray();
    //if data is [1,2,3] and after filter you get [1,2]
    //  and the next render data is [1,2] and the filter
    //  still returns [1,2] it will not be memoized because
    //  the array returned by array.filter is a new array
    //  you can get arround this by using makeMemArray
    return createSelector(
      (state) => state.data,
      (data) => memArray(filterData(data, filter))
    );
  }
);
const Component = ({filter})=>{
  //the filter parameter is curried, createSelectFilteredData(filter)
  //  returns a memoized function that will be re created when
  //  filter changes, that function takes state and will filter
  //  state.data using filter value(s)
  const items = useSelector(createSelectFilteredData(filter))
}
</code>```

But if the situation is slightly different and you have a list of items where you want to get one item from then there will be multiple Item components using the selector with different item.id and nothing will be memoized. In that case you can use React.useMemo as you did in your example:

```<code>const createSelectItem = (itemId) =>
  createSelector(
    (state) => state.items,
    (items) => items.find(({ id }) => id === itemId)
  );
const Item = ({ id }) => {
  //Each Item has it's own selectItem selector that is
  //  (re) created only when id changes
  const selectItem = React.useMemo(
    () => createSelectItem(id),
    [id]
  );
  const item = useSelector(selectItem);
  //if you were to do const item = useSelector(createSelectItem(id))
  //  then nothing will be memoized because selector is re created
  //  on every render.
  //Even if you would define createSelectItem as previous example
  //  of createSelectFilteredData and List would have ids [1,2,3]
  //  then the first time you crate the selector it will get 1 passed
  //  the second time it is called it gets 2 passed the 3rd time 3
  //  next render the first time it's called with 1 so noting memoized
  //  because the last time it was called with 3, then it's called with 2
  //  nothing memoized again because last time it was called with 1 ...
};
const List = ({ ids }) => (
  <ul>
    {ids.map((id) => (
      <Item key={id} id={id} />
    ))}
  </ul>
);
</code>```

Body:
Parameterized selector / selector factory

It's a function accepts parameters to generate selector, as we can imagine, each time the function is called, a new selector is generated, see below example:

const makeGetSomeSelector = ({ param1, param2, ...}) =>
    createSelector(
       parentSelector,        // suppose it's declared before
       result =>  result.getIn([param1, param2, ...], defaultValue)
    )

General case

Now, we want to use it in React functional component, and since react-redux introduced useSelector, and based on its provided example, in component it should be look like this:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';

const MyComponent = ({ param1, param2, ... }) => {
    const getSomeSelector = useMemo(
       () => makeGetSomeSelector({param1, param2, ...}),
       [param1, param2, ...]
    );
    const selectorResult = useSelector(getSomeSelector);
    ...
}

Case when it comes to constants

So far, everything make sense. However, there is a case that the parameters are not dynamic (e.g. from props, states, etc.), instead, they are constants! Then it becomes:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';
import { const1, const2, ... } from 'XXX/constants.js';

const MyComponent = () => {
    const getSomeSelector = useMemo(
       () => makeGetSomeSelector({const1, const2, ...}),
       []          // note that here we don't have any dependencies.
    );
    const selectorResult = useSelector(getSomeSelector);
    ...
}

However someone asked me why not use the following way:

import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { makeGetSomeSelector } from 'XXX/selectors.js';
import { const1, const2, ... } from 'XXX/constants.js';

const getSomeSelector = makeGetSomeSelector({const1, const2, ...});
// declare outside of component, since all params are just constants.

const MyComponent = () => {
    const selectorResult = useSelector(getSomeSelector);
    ...
}

Question

Which one is correct one or both are fine?

The correctness means the result (and potentially, all intermediate results) of selector is indeed memorized/cached and won't lead to some problem like new selector is created and lost memoize feature?

If anyone could elaborate how the selector factory works with useSelector (beside react-redux's example) will be more helpful!

Body:
The static selector can be used when it is called only once. For example: you have a list of items that can be filtered. The items are in state.data and the filters come from props then you can do something like this:

import { createSelector, defaultMemoize } from 'reselect';
const makeMemArray = () => {
  const mem = defaultMemoize((...array) => array);
  return (...array) => mem.apply(undefined, array);
};
const createSelectFilteredData = createSelector(
  (filter) => filter,
  (filter) => {
    const memArray = makeMemArray();
    //if data is [1,2,3] and after filter you get [1,2]
    //  and the next render data is [1,2] and the filter
    //  still returns [1,2] it will not be memoized because
    //  the array returned by array.filter is a new array
    //  you can get arround this by using makeMemArray
    return createSelector(
      (state) => state.data,
      (data) => memArray(filterData(data, filter))
    );
  }
);
const Component = ({filter})=>{
  //the filter parameter is curried, createSelectFilteredData(filter)
  //  returns a memoized function that will be re created when
  //  filter changes, that function takes state and will filter
  //  state.data using filter value(s)
  const items = useSelector(createSelectFilteredData(filter))
}

But if the situation is slightly different and you have a list of items where you want to get one item from then there will be multiple Item components using the selector with different item.id and nothing will be memoized. In that case you can use React.useMemo as you did in your example:

const createSelectItem = (itemId) =>
  createSelector(
    (state) => state.items,
    (items) => items.find(({ id }) => id === itemId)
  );
const Item = ({ id }) => {
  //Each Item has it's own selectItem selector that is
  //  (re) created only when id changes
  const selectItem = React.useMemo(
    () => createSelectItem(id),
    [id]
  );
  const item = useSelector(selectItem);
  //if you were to do const item = useSelector(createSelectItem(id))
  //  then nothing will be memoized because selector is re created
  //  on every render.
  //Even if you would define createSelectItem as previous example
  //  of createSelectFilteredData and List would have ids [1,2,3]
  //  then the first time you crate the selector it will get 1 passed
  //  the second time it is called it gets 2 passed the 3rd time 3
  //  next render the first time it's called with 1 so noting memoized
  //  because the last time it was called with 3, then it's called with 2
  //  nothing memoized again because last time it was called with 1 ...
};
const List = ({ ids }) => (
  <ul>
    {ids.map((id) => (
      <Item key={id} id={id} />
    ))}
  </ul>
);


问:
is it possible to explain why this returns 21
Hello this isn't an assignment or anything but can you explain why this returns 2 1.</p>
```<code>#include <string>
using namespace std;
void fun(int);
int main()
{
    int a = 0;
    fun(a);
    return 0;
}

void fun(int n)
{
    if (n < 2)
    {
        fun(++n);
        cout << n<<" ";
    }
}
</code>```

答:
You can think about recursion as nesting the functions inside of each other.

You pass n = 0.

```<code>fun(n=0)
{
    if (0 < 2)
    {
        // ++n alters n to be equal to n+1 for our current scope.
        fun(++n); // n = 1 now, fun gets called with n = 1
        {
            fun(n=1)
            {
                if (1 < 2)
                {
                    fun(++n); // n = 2 now, fun gets called with n = 2
                    {
                        fun(2)
                        {
                            if(2 < 2) // returns false
                        }
                    } // we exit this scope without doing anything futher
                    cout << n << " "; // n = 2 in this scope, here we print the 2
                }
            }
        } // now we exit this scope
        cout << n<<" "; // n = 1 in this scope, here we print the 1
    }
}
</code>```

Please let me know how I can clarify this further.

Body:
Hello this isn't an assignment or anything but can you explain why this returns 2 1.

#include <string>
using namespace std;
void fun(int);
int main()
{
    int a = 0;
    fun(a);
    return 0;
}

void fun(int n)
{
    if (n < 2)
    {
        fun(++n);
        cout << n<<" ";
    }
}

Body:
You can think about recursion as nesting the functions inside of each other.

You pass n = 0.

fun(n=0)
{
    if (0 < 2)
    {
        // ++n alters n to be equal to n+1 for our current scope.
        fun(++n); // n = 1 now, fun gets called with n = 1
        {
            fun(n=1)
            {
                if (1 < 2)
                {
                    fun(++n); // n = 2 now, fun gets called with n = 2
                    {
                        fun(2)
                        {
                            if(2 < 2) // returns false
                        }
                    } // we exit this scope without doing anything futher
                    cout << n << " "; // n = 2 in this scope, here we print the 2
                }
            }
        } // now we exit this scope
        cout << n<<" "; // n = 1 in this scope, here we print the 1
    }
}

Please let me know how I can clarify this further.


问:
Web scraping using Click button
Team, I am trying to click on load more button, I'm able to click and run the macro with no issues for only one click. that is for one time.
I need help for the below points

I'm trying to automate the code to repeat the click button until the page loads all the data for web scraping.

Also, i need a code to check the load more button in the web page exists or not before web scraping the data to excel. If "Load more" button not found proceed with the next code. (FYI Load more exists at the bottom of my web page).

Thanks and please reply me if my question is not clear.

below is the Html code before clicking load more button

```<code><button type="button" class="btn primary btn-primary modal-button-print add-notes" data-bind="click: getNotes, visible: isLoadMoreButtonEnable() && !$root.providerShouldAcceptDecline()">
  <i class="fa fa-refresh" aria-hidden="true"></i>Load More
</button>
</code>```

below is the Html code after clicking load more button multiple times until it   loads full data

```<code><button class="btn primary btn-primary modal-button-print add-notes" style="display: none;" type="button" data-bind="click: getWoNotes, visible: isLoadMoreNotesButtonEnable() && !$root.providerShouldAcceptDecline()">
                <i class="fa fa-refresh" aria-hidden="true"></i>Load More Work Order Notes
            </button>
</code>```

The difference i see from the above html code is style="display: none;" got added after i click button multiple times till it loads full data in web page.

I have a sample web site that looks similar to my webpage.
I took this link here to just show how the page loads in my website.

```<code>Sub abc()

Set IE = New InternetExplorer
Link = my url
.
.
.
.
For L = 2 To Lr1
    IE.navigate Link
    Set Html = New MSHTML.HTMLDocument
    Set Ws = Scraping
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))
    IE.document.querySelector("button[type=button]").Click
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))
    IE.document.querySelector("button[type=button]").Click
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))
    IE.document.querySelector("button[type=button]").Click
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))

    Html.body.innerHTML = IE.document.querySelectorAll(".list").Item(1).outerHTML
    Set Tariku = Html.querySelectorAll(".columns")
    Set data = Html.querySelectorAll(".datalist")
        With Ws

        ' Do all the stuff

        End With
        IE.document.querySelector("#Logout").Click
        IE.Quit
       Exit Sub

  Next L

End Sub
</code>```

答:
You can try this. Is it possible for you to post the URL if it don't work?</p>

```<code>Sub Abc()

Dim browser As Object
Dim url As String
Dim nodeButton As Object
Dim noButtonFound As Boolean

  url = "Your URL here"

  'Initialize Internet Explorer, set visibility,
  'call URL and wait until page is fully loaded
  Set browser = CreateObject("internetexplorer.application")
  browser.Visible = False
  browser.navigate url
  Do Until browser.ReadyState = 4: DoEvents: Loop

  'Click button as often as found
  Do
    'Try to catch button
    Set nodeButton = browser.document.getElementsByTagName("button")(0)

    'Check if button was found
    If Not nodeButton Is Nothing Then
      'Check if it has an style attribute
      If nodeButton.hasAttribute("style") Then
        'Check if button is visible
        If nodeButton.getAttribute("style") <> "display: none;" Then
          'Click button
          nodeButton.Click

          'Wait for load more data
          Application.Wait (Now + TimeSerial(0, 0, 5))
        End If
          'No visible button found, leave loop
          noButtonFound = True
        End If
      Else
        'No visible button found, leave loop
        noButtonFound = True
      End If
    Else
      'No visible button found, leave loop
      noButtonFound = True
    End If
  Loop Until noButtonFound

  'All dynamic data was load
  'Do here what ever you want
  'But I think you don't need a new html document
End Sub
</code>```

Title: Web scraping using Click button

Body:
Team, I am trying to click on load more button, I'm able to click and run the macro with no issues for only one click. that is for one time.
I need help for the below points

I'm trying to automate the code to repeat the click button until the page loads all the data for web scraping.

Also, i need a code to check the load more button in the web page exists or not before web scraping the data to excel. If "Load more" button not found proceed with the next code. (FYI Load more exists at the bottom of my web page).

Thanks and please reply me if my question is not clear.

below is the Html code before clicking load more button

<button type="button" class="btn primary btn-primary modal-button-print add-notes" data-bind="click: getNotes, visible: isLoadMoreButtonEnable() && !$root.providerShouldAcceptDecline()">
  Load More
</button>

below is the Html code after clicking load more button multiple times until it   loads full data

<button class="btn primary btn-primary modal-button-print add-notes" style="display: none;" type="button" data-bind="click: getWoNotes, visible: isLoadMoreNotesButtonEnable() && !$root.providerShouldAcceptDecline()">
                Load More Work Order Notes
            </button>

The difference i see from the above html code is style="display: none;" got added after i click button multiple times till it loads full data in web page.

I have a sample web site that looks similar to my webpage.
I took this link here to just show how the page loads in my website.

Sub abc()

Set IE = New InternetExplorer
Link = my url
.
.
.
.
For L = 2 To Lr1
    IE.navigate Link
    Set Html = New MSHTML.HTMLDocument
    Set Ws = Scraping
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))
    IE.document.querySelector("button[type=button]").Click
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))
    IE.document.querySelector("button[type=button]").Click
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))
    IE.document.querySelector("button[type=button]").Click
    Do
    DoEvents: Loop Until IE.readyState = READYSTATE_COMPLETE
    Application.Wait (Now + TimeValue("00:00:05"))

    Html.body.innerHTML = IE.document.querySelectorAll(".list").Item(1).outerHTML
    Set Tariku = Html.querySelectorAll(".columns")
    Set data = Html.querySelectorAll(".datalist")
        With Ws

        ' Do all the stuff

        End With
        IE.document.querySelector("#Logout").Click
        IE.Quit
       Exit Sub

  Next L

End Sub

Body:
You can try this. Is it possible for you to post the URL if it don't work?

Sub Abc()

Dim browser As Object
Dim url As String
Dim nodeButton As Object
Dim noButtonFound As Boolean

  url = "Your URL here"

  'Initialize Internet Explorer, set visibility,
  'call URL and wait until page is fully loaded
  Set browser = CreateObject("internetexplorer.application")
  browser.Visible = False
  browser.navigate url
  Do Until browser.ReadyState = 4: DoEvents: Loop

  'Click button as often as found
  Do
    'Try to catch button
    Set nodeButton = browser.document.getElementsByTagName("button")(0)

    'Check if button was found
    If Not nodeButton Is Nothing Then
      'Check if it has an style attribute
      If nodeButton.hasAttribute("style") Then
        'Check if button is visible
        If nodeButton.getAttribute("style") <> "display: none;" Then
          'Click button
          nodeButton.Click

          'Wait for load more data
          Application.Wait (Now + TimeSerial(0, 0, 5))
        End If
          'No visible button found, leave loop
          noButtonFound = True
        End If
      Else
        'No visible button found, leave loop
        noButtonFound = True
      End If
    Else
      'No visible button found, leave loop
      noButtonFound = True
    End If
  Loop Until noButtonFound

  'All dynamic data was load
  'Do here what ever you want
  'But I think you don't need a new html document
End Sub