问:
Execution failed for task ':app:bundleDevReleaseJsAndAssets'
When I run my Jenkins build for my React Native project it fails with the following errors:

```<code>Unable to resolve module `reactotron-core-client` from `/Users/nfib/Jenkins/Jenkins-Workspaces/ENGA/ENGAL/node_modules/reactotron-redux/dist/index.js`: Module does not exist in the module map

Execution failed for task ':app:bundleDevReleaseJsAndAssets'.
</code>```

I followed the recommended rm -rf node_modules && npm install but I am not exactly sure that this would help, since it seems to me like it's a generic solution from the npm team.

React-Native version: 0.53.3 with "reactotron-react-native": "3.5.0", "reactotron-redux": "3.1.0",

How can I ensure this does not continue to happen?

答:
The issue is your Jenkins build server is unable to locate the reactotron-core-client module which is necessary to complete your Jenkins build. You can see this from your stack trace:

Unable to resolve module reactotron-core-client

The recommended solution from the npm team of:

```<code>rm -rf node_modules && npm install
</code>```

is a generic solution because this command will remove your previous node_modules directory containing your project's dependencies and then reinstall the listed dependencies within in your project's package.json file. This may resolve issues stemming from your lock file as well as versioning issues if npm has been updated on your build server.

This solution may resolve your issue if all of your project's required libraries are listed within your package.json file. However, if the reactotron-core-client library isn't listed as a required dependency within your package.json file this problem will persist moving forward. Perhaps you could try the following:

npm i --save reactotron-core-client

as this will save and install the reactotron-core-client dependency for your project. By save I mean list this library as dependency within your package.json file.

Ideally, moving forward your best bet is to keep your package.json file up-to-date with your project's dependencies as well as installing dependencies prior to attempting a Jenkins build.

Hopefully that helps!

Body:
When I run my Jenkins build for my React Native project it fails with the following errors:

Unable to resolve module `reactotron-core-client` from `/Users/nfib/Jenkins/Jenkins-Workspaces/ENGA/ENGAL/node_modules/reactotron-redux/dist/index.js`: Module does not exist in the module map

Execution failed for task ':app:bundleDevReleaseJsAndAssets'.

I followed the recommended rm -rf node_modules && npm install but I am not exactly sure that this would help, since it seems to me like it's a generic solution from the npm team.

React-Native version: 0.53.3 with "reactotron-react-native": "3.5.0", "reactotron-redux": "3.1.0",

How can I ensure this does not continue to happen?

Body:
The issue is your Jenkins build server is unable to locate the reactotron-core-client module which is necessary to complete your Jenkins build. You can see this from your stack trace:

Unable to resolve module reactotron-core-client

The recommended solution from the npm team of:

rm -rf node_modules && npm install

is a generic solution because this command will remove your previous node_modules directory containing your project's dependencies and then reinstall the listed dependencies within in your project's package.json file. This may resolve issues stemming from your lock file as well as versioning issues if npm has been updated on your build server.

This solution may resolve your issue if all of your project's required libraries are listed within your package.json file. However, if the reactotron-core-client library isn't listed as a required dependency within your package.json file this problem will persist moving forward. Perhaps you could try the following:

npm i --save reactotron-core-client

as this will save and install the reactotron-core-client dependency for your project. By save I mean list this library as dependency within your package.json file.

Ideally, moving forward your best bet is to keep your package.json file up-to-date with your project's dependencies as well as installing dependencies prior to attempting a Jenkins build.

Hopefully that helps!


来源: stackexchange

问:
Kafka Producer and Consumer Issues
I have two issues with Apache Kafka.

Issue 1

Push 100,000 messages to Kafka

Shutdown zookeeper and kafka services with Ctrl-C before the consumer
consumes all the 100,000 messages (This was simulated by having a
Thread.sleep(1000) in the consume method).

Discovery

The consumer continued to write the messages on the console after the zookeeper and kafka services have been shutdown.

Expectation

The consumer should stop consuming messages and restart from the index of the last message + 1 after the zookeeper and kafka have been brought up.

Question

How do I make the consumer continue from the index + 1 of the last consumed message.

Issue 2

Push 100,000 messages to Kafka

Shutdown zookeeper and kafka services with Ctrl-C before the consumer
consumes all the 100,000 messages (This was simulated by having a
Thread.sleep(1000) in the consume method).

Kills the spring boot application consuming the messages

Bring up zookeeper and kafka services.

Bring up the spring boot application responsible for consuming messages.

Discovery

The consumer consumes all the messages from beginning ignoring the last consumed message.

Expectation

The consumer should start consuming from index + 1 of the last consumed message before the spring boot application was brought down.

Question

How do I make the consumer continue from the index + 1 of the last consumed message.

Code Snippets

KafkaConsumerConfig

```<code>@Configuration
@EnableKafka
public class KafkaConsumerConfig
{
    @Bean
    public Map<String, Object> consumerConfigs()
    {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "basic-group");
        return props;
    }

    @Bean
    public ConsumerFactory<Integer, String> consumerFactory()
    {
        return new DefaultKafkaConsumerFactory<>(consumerConfigs());
    }

    @Bean
    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>>
            kafkaListenerContainerFactory()
    {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(3);
        factory.getContainerProperties().setPollTimeout(100);
        return factory;
    }
}
</code>```

KafkaProducerConfig

```<code>@Configuration
    public class KafkaProducerConfig
    {
        @Bean
        public ProducerFactory<Integer, String> producerFactory()
        {
            return new DefaultKafkaProducerFactory<>(producerConfigs());
        }

        @Bean
        public Map<String, Object> producerConfigs()
        {
            Map<String, Object> props = new HashMap<>();
            props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
            props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
            props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
            return props;
        }

        @Bean
        public KafkaTemplate<Integer, String> kafkaTemplate()
        {
            return new KafkaTemplate<>(producerFactory());
        }
    }
</code>```

KafkaProducer

```<code>@Component
public class KafkaProducer
{

    @Autowired
    private KafkaTemplate kafkaTemplate;

    public void sendMessage(String message, final String topicName)
    {

        ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message);

        future.addCallback(new ListenableFutureCallback<SendResult<String, String>>()
        {

            @Override
            public void onSuccess(SendResult<String, String> result)
            {
                System.out.println("Sent message=[" + message
                        + "] with offset=[" + result.getRecordMetadata().offset() + "]");
            }

            @Override
            public void onFailure(Throwable ex)
            {
                System.out.println("Unable to send message=["
                        + message + "] due to : " + ex.getMessage());
            }
        });
    }
}
</code>```

KafkaConsumer

```<code>@Component
public class KafkaConsumer
{

    @KafkaListener(id = "basic", topics = "test-1", clientIdPrefix = "test-prefix-id", autoStartup = "true", concurrency = "3")
    public void multipleTransactionNotification(@Payload final String message)
    {
        try
        {
            Thread.sleep(1000);
            System.out.println(message);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
</code>```

TestApplication

```<code>@SpringBootApplication
public class TestApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(TestApplication.class, args);
    }

   @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx, KafkaProducer producer, NIPKafkaConsumer consumer) {
        return args -> {

            for (int i = 0; i < 100_000; i++)
            {
                producer.sendMessage("New Message-" + i, "test-1");
            }

        };
    }

}
</code>```

答:
Issue 1

Spring Kafka does a KafkaConsumer.poll() to fetch records and then calls your listener for each record.

So if the batch contains 100 records, it will take 100 seconds to proceed the whole batch with your actual KafkaListener.

Issue 2

Consumer commits offsets to know where to resume from.

Default behavior is to automatically commit offset every 5 seconds. My guess is you kill your consumer before it commits its offset, that's why it restarts from the beginning.

See enable.auto.commit and auto.commit.interval.ms Kafka consumer configuration.

You can also manually commit your offsets.

See also auto.offset.reset to define what your consumer should do when it has no initial offset.

ContentLicense: CC BY-SA 4.0

Title: Kafka Producer and Consumer Issues

Body:
I have two issues with Apache Kafka.

Issue 1

Push 100,000 messages to Kafka

Shutdown zookeeper and kafka services with Ctrl-C before the consumer
consumes all the 100,000 messages (This was simulated by having a
Thread.sleep(1000) in the consume method).

Discovery

The consumer continued to write the messages on the console after the zookeeper and kafka services have been shutdown.

Expectation

The consumer should stop consuming messages and restart from the index of the last message + 1 after the zookeeper and kafka have been brought up.

Question

How do I make the consumer continue from the index + 1 of the last consumed message.

Issue 2

Push 100,000 messages to Kafka

Shutdown zookeeper and kafka services with Ctrl-C before the consumer
consumes all the 100,000 messages (This was simulated by having a
Thread.sleep(1000) in the consume method).

Kills the spring boot application consuming the messages

Bring up zookeeper and kafka services.

Bring up the spring boot application responsible for consuming messages.

Discovery

The consumer consumes all the messages from beginning ignoring the last consumed message.

Expectation

The consumer should start consuming from index + 1 of the last consumed message before the spring boot application was brought down.

Question

How do I make the consumer continue from the index + 1 of the last consumed message.

Code Snippets

KafkaConsumerConfig

@Configuration
@EnableKafka
public class KafkaConsumerConfig
{
    @Bean
    public Map<String, Object> consumerConfigs()
    {
        Map<String, Object> props = new HashMap<>();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "basic-group");
        return props;
    }

    @Bean
    public ConsumerFactory<Integer, String> consumerFactory()
    {
        return new DefaultKafkaConsumerFactory<>(consumerConfigs());
    }

    @Bean
    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<Integer, String>>
            kafkaListenerContainerFactory()
    {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(3);
        factory.getContainerProperties().setPollTimeout(100);
        return factory;
    }
}

KafkaProducerConfig

@Configuration
    public class KafkaProducerConfig
    {
        @Bean
        public ProducerFactory<Integer, String> producerFactory()
        {
            return new DefaultKafkaProducerFactory<>(producerConfigs());
        }

        @Bean
        public Map<String, Object> producerConfigs()
        {
            Map<String, Object> props = new HashMap<>();
            props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
            props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
            props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
            return props;
        }

        @Bean
        public KafkaTemplate<Integer, String> kafkaTemplate()
        {
            return new KafkaTemplate<>(producerFactory());
        }
    }

KafkaProducer

@Component
public class KafkaProducer
{

    @Autowired
    private KafkaTemplate kafkaTemplate;

    public void sendMessage(String message, final String topicName)
    {

        ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topicName, message);

        future.addCallback(new ListenableFutureCallback<SendResult<String, String>>()
        {

            @Override
            public void onSuccess(SendResult<String, String> result)
            {
                System.out.println("Sent message=[" + message
                        + "] with offset=[" + result.getRecordMetadata().offset() + "]");
            }

            @Override
            public void onFailure(Throwable ex)
            {
                System.out.println("Unable to send message=["
                        + message + "] due to : " + ex.getMessage());
            }
        });
    }
}

KafkaConsumer

@Component
public class KafkaConsumer
{

    @KafkaListener(id = "basic", topics = "test-1", clientIdPrefix = "test-prefix-id", autoStartup = "true", concurrency = "3")
    public void multipleTransactionNotification(@Payload final String message)
    {
        try
        {
            Thread.sleep(1000);
            System.out.println(message);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

TestApplication

@SpringBootApplication
public class TestApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(TestApplication.class, args);
    }

   @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx, KafkaProducer producer, NIPKafkaConsumer consumer) {
        return args -> {

            for (int i = 0; i < 100_000; i++)
            {
                producer.sendMessage("New Message-" + i, "test-1");
            }

        };
    }

}


问:
What is the most efficient way to make random label location adjust to window size?
I have a label centered by the X coordinate on a form, and I'm trying to make it adjust its location on form resize.
So, I'm handling the Resize event to update label Location property.

```<code>private void SecondaryWindow_Resize(object sender, EventArgs e)
{
    lblStartPointX = this.Width / 2 - lblSecondary1.Width / 2;
    lblStartPointY = lblSecondary1.Location.Y;
    lblSecondary1.Location = new Point(lblStartPointX, lblStartPointY);
}
</code>```

It seems I can't directly assign some value to lblSecondary1.Location.X property (compiler considers it a mistake), so I came up with this code.

But it strikes me as not very efficient way to do the task... Just how much Point objects are created if you constantly resize the window, I wonder?

答:
Since you want your Label to remain centered in the X coordinates when the Form resizes, move it's position to the center of the Form when it loads, setting the the Label's Anchor to AnchorStyles.Top:

```<code>private void form1_Load(object sender, EventArgs e)
{
    label1.Anchor = AnchorStyles.Top;
    label1.Location = new Point((this.Width - label1.Width) / 2, label1.Top);
}
</code>```

It will keep its position when the Form.Width is resized.

If you want to keep it centered in both dimension, center it and remove any anchors. The control will remain in the middle of its parent Form:

```<code>private void form1_Load(object sender, EventArgs e)
{
    label1.Anchor = AnchorStyles.None;
    label1.Location = new Point((this.Width - label1.Width) / 2,
                                (this.Height - label1.Height) / 2);
}
</code>```

Body:
I have a label centered by the X coordinate on a form, and I'm trying to make it adjust its location on form resize.
So, I'm handling the Resize event to update label Location property.

private void SecondaryWindow_Resize(object sender, EventArgs e)
{
    lblStartPointX = this.Width / 2 - lblSecondary1.Width / 2;
    lblStartPointY = lblSecondary1.Location.Y;
    lblSecondary1.Location = new Point(lblStartPointX, lblStartPointY);
}

It seems I can't directly assign some value to lblSecondary1.Location.X property (compiler considers it a mistake), so I came up with this code.

But it strikes me as not very efficient way to do the task... Just how much Point objects are created if you constantly resize the window, I wonder?

Body:
Since you want your Label to remain centered in the X coordinates when the Form resizes, move it's position to the center of the Form when it loads, setting the the Label's Anchor to AnchorStyles.Top:

private void form1_Load(object sender, EventArgs e)
{
    label1.Anchor = AnchorStyles.Top;
    label1.Location = new Point((this.Width - label1.Width) / 2, label1.Top);
}

It will keep its position when the Form.Width is resized.

If you want to keep it centered in both dimension, center it and remove any anchors. The control will remain in the middle of its parent Form:

private void form1_Load(object sender, EventArgs e)
{
    label1.Anchor = AnchorStyles.None;
    label1.Location = new Point((this.Width - label1.Width) / 2,
                                (this.Height - label1.Height) / 2);
}


问:
POST values not received in PHP when submitted with .NET WebClient class
I'm trying to send some POST data with the .NET WebClient class as following:

```<code>WebClient objWebClient = new WebClient();

NameValueCollection objNameValueCollection = new NameValueCollection();
objNameValueCollection.Add("variable1", value1);
objNameValueCollection.Add("variable2", value2);
objNameValueCollection.Add("variable3", value3);

byte[] bytes = objWebClient.UploadValues(objURI, "POST", objNameValueCollection);
MessageBox.Show(Encoding.ASCII.GetString(bytes));
</code>```

But when I print the POST values in PHP with

```<code>var_dump($_POST)
</code>```

I'll get an empty string.

What I'm doing wrong here?
Why are the POST values obviously not submitted to the PHP script?

Thanks in advance for any ideas
Andreas

答:
I've found the solution myself now and just want to share the result.

It had nothing to do with my code itself. The problem was that I've added a redirect to my Apache configuration to redirect all requests from my domain www.ab-tools.de to www.ab-tools.com.

But the .NET application still posted the data to a script below the old domain.

As a redirect drops all POST data, the script did not get the data from the .NET application.

That was really a stupid mistake - it took me a while till I understood that. ;-)

Best regards and thanks again for all replies
Andreas

ContentLicense: CC BY-SA 3.0

Body:
I'm trying to send some POST data with the .NET WebClient class as following:

WebClient objWebClient = new WebClient();

NameValueCollection objNameValueCollection = new NameValueCollection();
objNameValueCollection.Add("variable1", value1);
objNameValueCollection.Add("variable2", value2);
objNameValueCollection.Add("variable3", value3);

byte[] bytes = objWebClient.UploadValues(objURI, "POST", objNameValueCollection);
MessageBox.Show(Encoding.ASCII.GetString(bytes));

But when I print the POST values in PHP with

var_dump($_POST)

I'll get an empty string.

What I'm doing wrong here?
Why are the POST values obviously not submitted to the PHP script?

Thanks in advance for any ideas
Andreas


问:
changing object keys acording to an array
i have an object and 2 arrays. i want to change object keys according to arr2, object keys and arr1 values are identical while arr1 and arr2 placement of values in arrays are identical but not values themselves, while i don't want to ask how to solve it want to know how should i approach this problem, thank you for your time

```<code>    const object = {
        name1: "some value",
        name3: "some value",
        name2: "some value",
        etc...}
    const arr1 = ["name1", "name2", "name3"]
    const arr2 = ["Name1", "Name2", "Name3"]
</code>```

expected outcome

```<code>    const newObject = {
        Name1: "some value",
        Name3: "some value",
        Name2: "some value",
        etc...}
</code>```

答:
You can simply do this:</p>

```<code>var output={};
arr1.forEach(function(el, index){
   output[arr2[index]] = object[el];
}, this);
</code>```

Body:
i have an object and 2 arrays. i want to change object keys according to arr2, object keys and arr1 values are identical while arr1 and arr2 placement of values in arrays are identical but not values themselves, while i don't want to ask how to solve it want to know how should i approach this problem, thank you for your time

    const object = {
        name1: "some value",
        name3: "some value",
        name2: "some value",
        etc...}
    const arr1 = ["name1", "name2", "name3"]
    const arr2 = ["Name1", "Name2", "Name3"]

expected outcome

    const newObject = {
        Name1: "some value",
        Name3: "some value",
        Name2: "some value",
        etc...}

Body:
You can simply do this:

var output={};
arr1.forEach(function(el, index){
   output[arr2[index]] = object[el];
}, this);


问:
Calling a firebase cloud function from nodejs
I want to call a cloud function from firebase from another nodejs server or just a nodejs script.

My firebase function is an onCall function.

I am using https://www.npmjs.com/package/firebase-admin for interacting with firebase but it doesn't seem to have a way of calling cloud functions...

Can I do it any other way? Like a http request?

答:
If you want to invoke a callable Function from server code, you will have to follow its protocol documentation in order to make sure the request is valid.

It's probably easier just to use a regular HTTP type function.  It should be easy to share its logic with a callable function by sharing the common code in another normal JavaScript function.


问:
Fedora 8 howto rebuild custom PHP?
I am running a wiki server for my group at work and recently moved it to a Fedora 8 OS.  Everything works great except that an extension I wrote that contacts an MsSql server fails because the function mssql_connect is not there.

On my old server I used "Free TDS" (with ./configure --prefix=/usr/local/freetds --enable-msdblib) and built PHP with:

./configure \

--with-apxs2=/usr/local/apache/bin/apxs \

--with-mysql=/usr/local/mysql \

--with-mssql=/usr/local/freetds \

--enable-safe-mode \

--enable-ftp \

--enable-inline-optimization \

--enable-magic-quotes --enable-xml \

--with-gd \

--with-zlib-dir=/usr/lib \

--with-jpeg-dir=/usr/local/lib

Is there a way I can easily rebuild PHP with the "--with-mssql=/usr/local/freetds" configuration on Fedora?  I would like to use yum to do this, but I don't see how.  More to the point, I would like to avoid having to build everything from scratch.  It's not that I don't know how, I would just like to avoid it.

Thanks for your your advice,

~Eric

答: So, the answer to adding mssql is as easy as "yum install php-mssql".  Fixed my problem without any messing around.  FreeTDS is installed an easily configurable.  Thanks everyone who tried to answer or left a comment.</p>

OwnerDisplayName: EToreo

ContentLicense: CC BY-SA 2.5

Title: Fedora 8 howto rebuild custom PHP?

LastEditorDisplayName: Cade Roux


问:
Get SSL Certificate 'Issued to'
I want to know how can I get Local Computer SSL certificates Issued to field values. I used this command to show all SSL certificates informations but it did not show me Issued To field

GET-CHILDITEM -Path 'Cert:\LocalMachine\' –RECURSE | FORMAT-LIST –PROPERTY *

答:
You can try and parse them from the Issuer field:

```<code>Get-ChildItem -Path 'Cert:\LocalMachine\' -Recurse |                                            #'# dummy comment to correct code-highlighting in SO
    Where-Object { !$_.PsIsContainer } |
    ForEach-Object {
        # get at most two parts out of the $_.Issuer string
        $issuer = '{0}, {1}' -f ([regex] 'O=([^,]+)').Match($_.Issuer).Groups[1].Value,
                                ([regex] 'CN=([^,]+)').Match($_.Issuer).Groups[1].Value
        [PSCustomObject]@{
            FriendlyName = $_.FriendlyName
            Issuer       = $issuer.Trim(', "')
            Subject      = $_.Subject
        }
    } | Format-List
</code>```

On my machine it returns stuff like:

```<code>FriendlyName : Sectigo
Issuer       : The USERTRUST Network, USERTrust RSA Certification Authority
Subject      : CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, S=New Jersey, C=US

FriendlyName : Go Daddy Class 2 Certification Authority
Issuer       : The Go Daddy Group
Subject      : OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US

FriendlyName : VeriSign
Issuer       : VeriSign
Subject      : OU=VeriSign Commercial Software Publishers CA, O="VeriSign, Inc.", L=Internet
</code>```

Title: Get SSL Certificate 'Issued to'

Body:
You can try and parse them from the Issuer field:

Get-ChildItem -Path 'Cert:\LocalMachine\' -Recurse |                                            #'# dummy comment to correct code-highlighting in SO
    Where-Object { !$_.PsIsContainer } |
    ForEach-Object {
        # get at most two parts out of the $_.Issuer string
        $issuer = '{0}, {1}' -f ([regex] 'O=([^,]+)').Match($_.Issuer).Groups[1].Value,
                                ([regex] 'CN=([^,]+)').Match($_.Issuer).Groups[1].Value
        [PSCustomObject]@{
            FriendlyName = $_.FriendlyName
            Issuer       = $issuer.Trim(', "')
            Subject      = $_.Subject
        }
    } | Format-List

On my machine it returns stuff like:

FriendlyName : Sectigo
Issuer       : The USERTRUST Network, USERTrust RSA Certification Authority
Subject      : CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, S=New Jersey, C=US

FriendlyName : Go Daddy Class 2 Certification Authority
Issuer       : The Go Daddy Group
Subject      : OU=Go Daddy Class 2 Certification Authority, O="The Go Daddy Group, Inc.", C=US

FriendlyName : VeriSign
Issuer       : VeriSign
Subject      : OU=VeriSign Commercial Software Publishers CA, O="VeriSign, Inc.", L=Internet


问:
Formulate an Arbitrary for pair of lists of ints of the same length
I need some help to do this exercise about generators in f#.

The functions

```<code>List.zip : ('a list -> 'b list -> ('a * 'b) list)
</code>```

and

```<code>List.unzip : (('a * 'b) list -> 'a list * 'b list)
</code>```

are inverse of each other, under the condition that they operate on lists
of the same length.
Formulate an Arbitrary for pair of lists of ints of the same length

I tried to write some code:

```<code>let length xs ys =
    List.length xs = List.length ys

let samelength =
    Arb.filter length Arb.from<int list>
</code>```

It doesn't work, I get a type mismatch at length in samelength:

Error: type mismatch. Expecting a 'a list -> bool but given a 'a list -> 'b list -> bool. The type bool does not match the type 'a list -> bool.

Edit:

As suggested I tried to follow the outline of steps but I'm stuck.

```<code>let sizegen =
    Arb.filter (fun x -> x > 0) Arb.from<int>

let listgen =
    let size = sizegen
    let xs = Gen.listOfLength size
    let ys = Gen.listOfLength size
    xs, ys
</code>```

And of course I have the error type mismatch:

Error: type mistmatch. Expected to have type int but here has type Arbitrary<int>

Edit

I solved the exercise but it seems that my generator is not working when I do the test, it looks another one is invoked.

```<code>let samelength (xs, ys) =
   List.length xs = List.length ys

let arbMyGen2 = Arb.filter samelength Arb.from<int list * int list>

type MyGeneratorZ =
   static member arbMyGen2() =
    {
        new Arbitrary<int list * int list>() with
            override x.Generator = arbMyGen2 |> Arb.toGen
            override x.Shrinker t = Seq.empty
    }

let _ = Arb.register<MyGeneratorZ>()

let pro_zip (xs: int list, ys: int list) =
   (xs, ys) = List.unzip(List.zip xs ys)

do Check.Quick pro_zip
</code>```

I get the error:

Error:  System.ArgumentException: list1 is 1 element shorter than list2

But why? My generator should only generate two lists of the same length.

答:
If we look at the API reference for the Arb module, and hover over the definition of filter, you'll see that the type of Arb.filter is:

```<code>pred:('a -> bool) -> a:Arbitrary<'a> -> a:Arbitrary<'a>
</code>```

This means that the predicate should be a function of one parameter that returns a bool. But your length function is a function of two parameters. You want to turn it into a function of just one parameter.

Think of it this way. When you write Arb.filter length Arb.from<int list>, what you're saying is "I want to generate an arbitrary int list (just one at a time), and filter it according to the length rule." But the length rule you've written takes two lists and compares their length. If FsCheck generates just a single list of ints, what will it compare its length to? There's no second list to compare to, so the compiler can't actually turn your code into something that makes sense.

What you probably wanted to do (though there's a problem with this, which I'll get to in a minute) was generate a pair of lists, then pass it to your length predicate. I.e., you probably wanted Arb.from<int list * int list>. That will generate a pair of integer lists, completely independent from each other. Then you'll still get a type mismatch in your length function, but you just have to turn its signature from let length xs ys = to let length (xs,ys) =, e.g. have it receive a single argument that contains a pair of lists, instead of having each list as a separate argument. After those tweaks, your code looks like:

```<code>let length (xs,ys) =
    List.length xs = List.length ys

let samelength =
    Arb.filter length Arb.from<int list * int list>
</code>```

But there are still problems with this. Specifically, if we look at the FsCheck documentation, we find this warning:

When using Gen.filter, be sure to provide a predicate with a high chance of returning true. If the predicate discards 'too many' candidates, it may cause tests to run slower, or to not terminate at all.

This applies to Arb.filter just as much as to Gen.filter, by the way. The way your code currently stands, this is a problem, because your filter will discard most pairs of lists. Since the lists are generated independently of each other, it will most often happen that they have different lengths, so your filter will return false most of the time. I'd suggest a different approach. Since you've said that this is an exercise, I won't write the code for you since you'll learn more by doing it yourself; I'll just give you an outline of the steps you'll want to take.

Generate a non-negative int n that will be the size of both lists in the pair. (For bonus points, use Gen.sized to get the "current size" of the data you should generate, and generate n as a value between 0 and size, so that your list-pair generator, like FsCheck's default list generator, will create lists that start small and slowly grow larger).

Use Gen.listOfLength n to generate both lists. (You could even do Gen.two (Gen.listOfLength n) to easily generate a pair of lists of the same size).

Don't forget to write an appropriate shrinker for a pair of lists, because the exercise wants you to generate a proper Arbitrary, and an Arbitrary that doesn't have a shrinker is not very useful in practice. You can probably do something with Arb.mapFilter here, where the mapper is id because you're already generating lists of matching length, but the filter is your length predicate. Then use Arb.fromGenShrink to turn your generator and shrinker functions into a proper Arbitrary instance.

If that outline isn't enough for you to get it working, ask another question about wherever you're stuck and I'll be glad to help out however I can.

Edit:

In your edit where you're trying to write a list generator using sizegen, you have the following code that doesn't work:

```<code>let listgen =
    let size = sizegen
    let xs = Gen.listOfLength size
    let ys = Gen.listOfLength size
    xs, ys
</code>```

Here sizegen is a Gen<int> and you're wanting to extract the int parameter from it. There are several ways to do this, but the simplest is the gen { ... } computation expression that FsCheck has provided for us.

BTW, if you don't know what computation expressions are, they're some of F#'s most powerful features: they are highly complex under the hood, but they allow you to write very simple-looking code. You should bookmark https://fsharpforfunandprofit.com/series/computation-expressions.html and https://fsharpforfunandprofit.com/series/map-and-bind-and-apply-oh-my.html and plan to read them later. Don't worry if you don't understand them on your first, or second, or even fifth reading: that's fine. Just keep coming back to these two series of articles, and using computation expressions like gen or seq in practice, and eventually the concepts will become clear. And every time you read these series, you'll learn more, and get closer to that moment of enlightenment when it all "clicks" in your brain.

But back to your code. As I said, you want to use the gen { ... } computation expression. Inside a gen { ... } expression, the let! assignment will "unwrap" a Gen<Foo> object into the generated Foo, which you can then use in further code. Which is what you want to do with your size int. So we'll just wrap a gen { ... } expression around your code, and get the following:

```<code>let listgen =
    gen {
        let! size = sizegen
        let xs = Gen.listOfLength size
        let ys = Gen.listOfLength size
        return (xs, ys)
    }
</code>```

Note that I also added a return keyword on the last line. Inside a computation expression, return has the opposite effect of let!. The let! keyword unwraps a value (the type goes from Gen<Foo> to Foo), while the return keyword wraps a value (the type goes from Foo to Gen<Foo>). So that return line takes an int list * int list and turns it into a Gen<int list * int list>. There's some very complex code going on under the hood, but at the surface level of the computation expression, you just need to think in terms of "unwrapping" and "wrapping" types to decide whether to use let! or return.

Body:
I need some help to do this exercise about generators in f#.

The functions

List.zip : ('a list -> 'b list -> ('a * 'b) list)

and

List.unzip : (('a * 'b) list -> 'a list * 'b list)

are inverse of each other, under the condition that they operate on lists
of the same length.
Formulate an Arbitrary for pair of lists of ints of the same length

I tried to write some code:

let length xs ys =
    List.length xs = List.length ys

let samelength =
    Arb.filter length Arb.from<int list>

It doesn't work, I get a type mismatch at length in samelength:

Error: type mismatch. Expecting a 'a list -> bool but given a 'a list -> 'b list -> bool. The type bool does not match the type 'a list -> bool.

Edit:

As suggested I tried to follow the outline of steps but I'm stuck.

let sizegen =
    Arb.filter (fun x -> x > 0) Arb.from<int>

let listgen =
    let size = sizegen
    let xs = Gen.listOfLength size
    let ys = Gen.listOfLength size
    xs, ys

And of course I have the error type mismatch:

Error: type mistmatch. Expected to have type int but here has type Arbitrary<int>

Edit

I solved the exercise but it seems that my generator is not working when I do the test, it looks another one is invoked.

let samelength (xs, ys) =
   List.length xs = List.length ys

let arbMyGen2 = Arb.filter samelength Arb.from<int list * int list>

type MyGeneratorZ =
   static member arbMyGen2() =
    {
        new Arbitrary<int list * int list>() with
            override x.Generator = arbMyGen2 |> Arb.toGen
            override x.Shrinker t = Seq.empty
    }

let _ = Arb.register<MyGeneratorZ>()

let pro_zip (xs: int list, ys: int list) =
   (xs, ys) = List.unzip(List.zip xs ys)

do Check.Quick pro_zip

I get the error:

Error:  System.ArgumentException: list1 is 1 element shorter than list2

But why? My generator should only generate two lists of the same length.

Body:
If we look at the API reference for the Arb module, and hover over the definition of filter, you'll see that the type of Arb.filter is:

pred:('a -> bool) -> a:Arbitrary<'a> -> a:Arbitrary<'a>

This means that the predicate should be a function of one parameter that returns a bool. But your length function is a function of two parameters. You want to turn it into a function of just one parameter.

Think of it this way. When you write Arb.filter length Arb.from<int list>, what you're saying is "I want to generate an arbitrary int list (just one at a time), and filter it according to the length rule." But the length rule you've written takes two lists and compares their length. If FsCheck generates just a single list of ints, what will it compare its length to? There's no second list to compare to, so the compiler can't actually turn your code into something that makes sense.

What you probably wanted to do (though there's a problem with this, which I'll get to in a minute) was generate a pair of lists, then pass it to your length predicate. I.e., you probably wanted Arb.from<int list * int list>. That will generate a pair of integer lists, completely independent from each other. Then you'll still get a type mismatch in your length function, but you just have to turn its signature from let length xs ys = to let length (xs,ys) =, e.g. have it receive a single argument that contains a pair of lists, instead of having each list as a separate argument. After those tweaks, your code looks like:

let length (xs,ys) =
    List.length xs = List.length ys

let samelength =
    Arb.filter length Arb.from<int list * int list>

But there are still problems with this. Specifically, if we look at the FsCheck documentation, we find this warning:

When using Gen.filter, be sure to provide a predicate with a high chance of returning true. If the predicate discards 'too many' candidates, it may cause tests to run slower, or to not terminate at all.

This applies to Arb.filter just as much as to Gen.filter, by the way. The way your code currently stands, this is a problem, because your filter will discard most pairs of lists. Since the lists are generated independently of each other, it will most often happen that they have different lengths, so your filter will return false most of the time. I'd suggest a different approach. Since you've said that this is an exercise, I won't write the code for you since you'll learn more by doing it yourself; I'll just give you an outline of the steps you'll want to take.

Generate a non-negative int n that will be the size of both lists in the pair. (For bonus points, use Gen.sized to get the "current size" of the data you should generate, and generate n as a value between 0 and size, so that your list-pair generator, like FsCheck's default list generator, will create lists that start small and slowly grow larger).

Use Gen.listOfLength n to generate both lists. (You could even do Gen.two (Gen.listOfLength n) to easily generate a pair of lists of the same size).

Don't forget to write an appropriate shrinker for a pair of lists, because the exercise wants you to generate a proper Arbitrary, and an Arbitrary that doesn't have a shrinker is not very useful in practice. You can probably do something with Arb.mapFilter here, where the mapper is id because you're already generating lists of matching length, but the filter is your length predicate. Then use Arb.fromGenShrink to turn your generator and shrinker functions into a proper Arbitrary instance.

If that outline isn't enough for you to get it working, ask another question about wherever you're stuck and I'll be glad to help out however I can.

Edit:

In your edit where you're trying to write a list generator using sizegen, you have the following code that doesn't work:

let listgen =
    let size = sizegen
    let xs = Gen.listOfLength size
    let ys = Gen.listOfLength size
    xs, ys

Here sizegen is a Gen<int> and you're wanting to extract the int parameter from it. There are several ways to do this, but the simplest is the gen { ... } computation expression that FsCheck has provided for us.

BTW, if you don't know what computation expressions are, they're some of F#'s most powerful features: they are highly complex under the hood, but they allow you to write very simple-looking code. You should bookmark https://fsharpforfunandprofit.com/series/computation-expressions.html and https://fsharpforfunandprofit.com/series/map-and-bind-and-apply-oh-my.html and plan to read them later. Don't worry if you don't understand them on your first, or second, or even fifth reading: that's fine. Just keep coming back to these two series of articles, and using computation expressions like gen or seq in practice, and eventually the concepts will become clear. And every time you read these series, you'll learn more, and get closer to that moment of enlightenment when it all "clicks" in your brain.

But back to your code. As I said, you want to use the gen { ... } computation expression. Inside a gen { ... } expression, the let! assignment will "unwrap" a Gen<Foo> object into the generated Foo, which you can then use in further code. Which is what you want to do with your size int. So we'll just wrap a gen { ... } expression around your code, and get the following:

let listgen =
    gen {
        let! size = sizegen
        let xs = Gen.listOfLength size
        let ys = Gen.listOfLength size
        return (xs, ys)
    }

Note that I also added a return keyword on the last line. Inside a computation expression, return has the opposite effect of let!. The let! keyword unwraps a value (the type goes from Gen<Foo> to Foo), while the return keyword wraps a value (the type goes from Foo to Gen<Foo>). So that return line takes an int list * int list and turns it into a Gen<int list * int list>. There's some very complex code going on under the hood, but at the surface level of the computation expression, you just need to think in terms of "unwrapping" and "wrapping" types to decide whether to use let! or return.


问:
How to restore inapp purchase product properly in iOS Swift
I have both Non-Consumable and Auto-Renewable Subscription in my product list. So when i try to restore purchases, I get all the purchases made. Now what should be the approach when restoring the purchase.

In my case i have two product that charges monthly and yearly and one that is non-consumable and gives lifetime access. So while testing, i made several transactions. But when restoring, i noticed i get all the purchased transactions list from which i need to restore a valid product for the user. So how do i know which item to restore?

From the docs, i found a way to verify a subscription and verify a product. But from my response i can see, i have both monthly and lifetime product that is valid for restoring. What should i do here?

This is my code

```<code>    @IBAction func restoreButtonPressed(_ sender: Any) {
            //        SubscriptionService.shared.restorePurchases()
            if self.premium != nil {
                // contact alert
                self.showActionSheet(title: "Contact us", message: "Tell us your query at \(Settings.requestEmail)", email: Settings.requestEmail)
                return
            }

            notificationShown = false
            hud.show(in: self.view)

    //        let appleValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: Payment.sharedSecret)

            SwiftyStoreKit.restorePurchases(atomically: true) { results in
                for purchase in results.restoredPurchases {
                    print("//////////////////////")
                    print(purchase.productId)
                    print("Original Transaction Date: \((purchase.originalTransaction?.transactionDate)!)")
                    print("Original Transaction State: \((purchase.originalTransaction?.transactionState)!)")
                    print("Transaction Date: \((purchase.transaction.transactionDate)!)")
                    print("Transaction State: \((purchase.transaction.transactionState))")
                    print("//////////////////////")

                    if purchase.productId == Payment.lifetime {
                        SubscriptionService.shared.verifyPurchase(productId: purchase.productId, transactionDate: purchase.originalTransaction?.transactionDate, completion: { (success) in
                            self.hud.dismiss(afterDelay: 3.0)
                            if success {
                                Premium().check().done { premium in
                                    self.premium = premium
                                    self.initiatePremiumView()
                                    self.initPurchaseButton()
                                }
                            } else {
                                if self.notificationShown == false {
                                    self.showNotification(title: "No item to restore", buttonTitle: "", type: .failure)
                                    self.notificationShown = true
                                }
                            }
                            if purchase.needsFinishTransaction {
                                SwiftyStoreKit.finishTransaction(purchase.transaction)
                            }
                        })
                    } else {
                        SubscriptionService.shared.verifySubscription(productId: purchase.productId, transactionDate: purchase.originalTransaction?.transactionDate, completion: { (success) in
                            self.hud.dismiss(afterDelay: 3.0)
                            if success {
                                Premium().check().done { premium in
                                    self.premium = premium
                                    self.initiatePremiumView()
                                    self.initPurchaseButton()
                                    }.catch { _ in }
                            } else {
                                if self.notificationShown == false {
                                    self.showNotification(title: "No item to restore", buttonTitle: "", type: .failure)
                                    self.notificationShown = true
                                }
                            }
                        })
                    }
                    if purchase.needsFinishTransaction {
                        // Deliver content from server, then:
                        SwiftyStoreKit.finishTransaction(purchase.transaction)
                    }
                }

            }
            //            self.showAlert(self.alertForRestorePurchases(results))
        }

func verifySubscription(productId: String, transactionDate: Date?, completion: @escaping (Bool) -> ()) {
        let appleValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: Payment.sharedSecret)

        SwiftyStoreKit.verifyReceipt(using: appleValidator, forceRefresh: false) { result in
            switch result {
            case .success(let receipt):
//                print(receipt.count)
                if receipt.count > 0 {
                    let purchaseResult = SwiftyStoreKit.verifySubscription(
                        ofType: .autoRenewable, // or .nonRenewing (see below)
                        productId: productId,
                        inReceipt: receipt)

                    switch purchaseResult {
                    case .purchased(let expiryDate, let items):
                        // give premium access
                        let premium = Premium(hasFullAccess: true, subscribedProduct: productId, expires: expiryDate, purchaseDate: transactionDate)
                        premium.giveFullAccess().done { result in
                            // show full access Dialog
                            completion(true)
                            }.catch { error in
                                // give error msg
                                completion(false)
//                                print("hell no")
                        }
//                        print("\(productId) is valid until \(expiryDate)\n\n")
                    case .expired(let expiryDate, let items):
                        // remove premium access
                        completion(false)
                        Premium().removePremiumAccess().done {_ in }.catch {_ in }
//                        print("\(productId) is expired since \(expiryDate)\n\n")
                    case .notPurchased:
                        // remove premium access
                        completion(false)
                        Premium().removePremiumAccess().done {_ in }.catch {_ in }
//                        print("The user has never purchased \(productId)")
                    }
                }
            //                print("Verify receipt success: \(receipt)")
            case .error(let error):
                print("Verify receipt failed: \(error)")
            }
        }
    }

    func verifyPurchase(productId: String, transactionDate: Date?, completion: @escaping (Bool) -> ()) {
        let appleValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: Payment.sharedSecret)

        SwiftyStoreKit.verifyReceipt(using: appleValidator, forceRefresh: false) { result in
            switch result {
            case .success(let receipt):
                if receipt.count > 0 {
                    let purchaseResult = SwiftyStoreKit.verifyPurchase(
                        productId: productId,
                        inReceipt: receipt)

                    switch purchaseResult {
                    case .purchased(let receiptItem):
                        let premium = Premium(hasFullAccess: true, subscribedProduct: productId, expires: nil, purchaseDate: transactionDate)
                        premium.giveFullAccess().done { result in
                            // show full access Dialog
                            completion(true)
                            }.catch { error in
                                // give error msg
                                completion(false)
//                                print("hell no")
                        }
//                        print("\(productId) is purchased: \(receiptItem)")
                    case .notPurchased:
                        completion(false)
                        Premium().removePremiumAccess().done {_ in }.catch {_ in }
                    }
                }
            //                print("Verify receipt success: \(receipt)")
            case .error(let error):
                print("Verify receipt failed: \(error)")
            }
        }
    }
</code>```

**Full Purchased product list when restoring: **

```<code>//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:32:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:39:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:17:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:35:03 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:29:08 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:10:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:09:36 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:20:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 10:52:29 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: yearly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 12:14:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:30:01 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: yearly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 12:17:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:14:36 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:22:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:27:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:44:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:34:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:25:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:17:10 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:22:55 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:25:01 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:30:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 10:31:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: lifetime
Original Transaction Date: 2019-04-24 11:06:13 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 09:23:14 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:20:01 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:05:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:15:37 +0000
Transaction State: restored
//////////////////////
</code>```

答:
You should check for the active subscription sorted from latest and unlock them if it's active. It's depend on your subscription logic by the way.

In my case, I check for following order.

a) If there is a lifetime plan purchased, it will be un-locked for
  lifetime.

b) If no lifetime purchased, then will check for subscription in a
  sorted purchase list and find out if there any subscription active and
  unlock it if exist.

Also, I check for any unfinished purchase, then unlock content and mark it finished after unlock.

Body:
I have both Non-Consumable and Auto-Renewable Subscription in my product list. So when i try to restore purchases, I get all the purchases made. Now what should be the approach when restoring the purchase.

In my case i have two product that charges monthly and yearly and one that is non-consumable and gives lifetime access. So while testing, i made several transactions. But when restoring, i noticed i get all the purchased transactions list from which i need to restore a valid product for the user. So how do i know which item to restore?

From the docs, i found a way to verify a subscription and verify a product. But from my response i can see, i have both monthly and lifetime product that is valid for restoring. What should i do here?

This is my code

    @IBAction func restoreButtonPressed(_ sender: Any) {
            //        SubscriptionService.shared.restorePurchases()
            if self.premium != nil {
                // contact alert
                self.showActionSheet(title: "Contact us", message: "Tell us your query at \(Settings.requestEmail)", email: Settings.requestEmail)
                return
            }

            notificationShown = false
            hud.show(in: self.view)

    //        let appleValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: Payment.sharedSecret)

            SwiftyStoreKit.restorePurchases(atomically: true) { results in
                for purchase in results.restoredPurchases {
                    print("//////////////////////")
                    print(purchase.productId)
                    print("Original Transaction Date: \((purchase.originalTransaction?.transactionDate)!)")
                    print("Original Transaction State: \((purchase.originalTransaction?.transactionState)!)")
                    print("Transaction Date: \((purchase.transaction.transactionDate)!)")
                    print("Transaction State: \((purchase.transaction.transactionState))")
                    print("//////////////////////")

                    if purchase.productId == Payment.lifetime {
                        SubscriptionService.shared.verifyPurchase(productId: purchase.productId, transactionDate: purchase.originalTransaction?.transactionDate, completion: { (success) in
                            self.hud.dismiss(afterDelay: 3.0)
                            if success {
                                Premium().check().done { premium in
                                    self.premium = premium
                                    self.initiatePremiumView()
                                    self.initPurchaseButton()
                                }
                            } else {
                                if self.notificationShown == false {
                                    self.showNotification(title: "No item to restore", buttonTitle: "", type: .failure)
                                    self.notificationShown = true
                                }
                            }
                            if purchase.needsFinishTransaction {
                                SwiftyStoreKit.finishTransaction(purchase.transaction)
                            }
                        })
                    } else {
                        SubscriptionService.shared.verifySubscription(productId: purchase.productId, transactionDate: purchase.originalTransaction?.transactionDate, completion: { (success) in
                            self.hud.dismiss(afterDelay: 3.0)
                            if success {
                                Premium().check().done { premium in
                                    self.premium = premium
                                    self.initiatePremiumView()
                                    self.initPurchaseButton()
                                    }.catch { _ in }
                            } else {
                                if self.notificationShown == false {
                                    self.showNotification(title: "No item to restore", buttonTitle: "", type: .failure)
                                    self.notificationShown = true
                                }
                            }
                        })
                    }
                    if purchase.needsFinishTransaction {
                        // Deliver content from server, then:
                        SwiftyStoreKit.finishTransaction(purchase.transaction)
                    }
                }

            }
            //            self.showAlert(self.alertForRestorePurchases(results))
        }

func verifySubscription(productId: String, transactionDate: Date?, completion: @escaping (Bool) -> ()) {
        let appleValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: Payment.sharedSecret)

        SwiftyStoreKit.verifyReceipt(using: appleValidator, forceRefresh: false) { result in
            switch result {
            case .success(let receipt):
//                print(receipt.count)
                if receipt.count > 0 {
                    let purchaseResult = SwiftyStoreKit.verifySubscription(
                        ofType: .autoRenewable, // or .nonRenewing (see below)
                        productId: productId,
                        inReceipt: receipt)

                    switch purchaseResult {
                    case .purchased(let expiryDate, let items):
                        // give premium access
                        let premium = Premium(hasFullAccess: true, subscribedProduct: productId, expires: expiryDate, purchaseDate: transactionDate)
                        premium.giveFullAccess().done { result in
                            // show full access Dialog
                            completion(true)
                            }.catch { error in
                                // give error msg
                                completion(false)
//                                print("hell no")
                        }
//                        print("\(productId) is valid until \(expiryDate)\n\n")
                    case .expired(let expiryDate, let items):
                        // remove premium access
                        completion(false)
                        Premium().removePremiumAccess().done {_ in }.catch {_ in }
//                        print("\(productId) is expired since \(expiryDate)\n\n")
                    case .notPurchased:
                        // remove premium access
                        completion(false)
                        Premium().removePremiumAccess().done {_ in }.catch {_ in }
//                        print("The user has never purchased \(productId)")
                    }
                }
            //                print("Verify receipt success: \(receipt)")
            case .error(let error):
                print("Verify receipt failed: \(error)")
            }
        }
    }

    func verifyPurchase(productId: String, transactionDate: Date?, completion: @escaping (Bool) -> ()) {
        let appleValidator = AppleReceiptValidator(service: .sandbox, sharedSecret: Payment.sharedSecret)

        SwiftyStoreKit.verifyReceipt(using: appleValidator, forceRefresh: false) { result in
            switch result {
            case .success(let receipt):
                if receipt.count > 0 {
                    let purchaseResult = SwiftyStoreKit.verifyPurchase(
                        productId: productId,
                        inReceipt: receipt)

                    switch purchaseResult {
                    case .purchased(let receiptItem):
                        let premium = Premium(hasFullAccess: true, subscribedProduct: productId, expires: nil, purchaseDate: transactionDate)
                        premium.giveFullAccess().done { result in
                            // show full access Dialog
                            completion(true)
                            }.catch { error in
                                // give error msg
                                completion(false)
//                                print("hell no")
                        }
//                        print("\(productId) is purchased: \(receiptItem)")
                    case .notPurchased:
                        completion(false)
                        Premium().removePremiumAccess().done {_ in }.catch {_ in }
                    }
                }
            //                print("Verify receipt success: \(receipt)")
            case .error(let error):
                print("Verify receipt failed: \(error)")
            }
        }
    }

**Full Purchased product list when restoring: **

//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:32:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:39:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:17:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:35:03 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:29:08 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:10:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:09:36 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:20:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 10:52:29 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: yearly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 12:14:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:30:01 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: yearly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 12:17:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:14:36 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:22:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-23 13:27:35 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:44:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:34:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:25:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:17:10 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 06:22:55 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:25:01 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:30:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 10:31:38 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: lifetime
Original Transaction Date: 2019-04-24 11:06:13 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 09:23:14 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-24 09:20:01 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:05:37 +0000
Transaction State: restored
//////////////////////
//////////////////////
Product Id: monthly
Original Transaction Date: 2019-04-23 12:14:36 +0000
Original Transaction State: purchased
Transaction Date: 2019-04-25 07:15:37 +0000
Transaction State: restored
//////////////////////


问:
Ansible uri module
I have web url and i have two options enable/disable , Now I am writing ansible playbook to do this which is in Powershell script

My ansible playbook

```<code>---
- hosts: localhost
  vars:
    applauncher: "xweb"
    jobState: "Disable"
    serverName: "NETBATCH"
    jobName: "Loan1"

  tasks:
    - name: edit app jobs
      uri:
         url: 'http://{{ applauncher }}/Edit/{{ jobState }}?Server={{ serverName }}&JobName={{ jobName }}'
         method: POST
         user: xxxx
         password: xxx
</code>```

I am passing extra vars to disable and enable option , Is it possible to use this option in uri module and which method I should use to select disable/enable option in URL

答: I think this is what you are after, but it took me a while to figure out what you are asking for. Read about vars_prompt playbook keyword: https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html</p>

Title: Ansible uri module

Body:
I have web url and i have two options enable/disable , Now I am writing ansible playbook to do this which is in Powershell script

My ansible playbook

---
- hosts: localhost
  vars:
    applauncher: "xweb"
    jobState: "Disable"
    serverName: "NETBATCH"
    jobName: "Loan1"

  tasks:
    - name: edit app jobs
      uri:
         url: 'http://{{ applauncher }}/Edit/{{ jobState }}?Server={{ serverName }}&JobName={{ jobName }}'
         method: POST
         user: xxxx
         password: xxx

I am passing extra vars to disable and enable option , Is it possible to use this option in uri module and which method I should use to select disable/enable option in URL


问:
How to get parameters of a step with multiple pipelines in cucumber for the java code?
I have below steps in my feature file for a scenario.

```<code>Given my_first_step

And my_second_step
  | Themes          | one | three |

  | Service Windows | two | four  |

And my_third_step

  | Create Apps |

  | Config      |
</code>```

we can get parameters of 'my_third_step' as below in the java code as a list

public void my_third_step(List listOfItems) {}

but how can get parameters in 'my_second_step' ?
I need to get a rows as array of elements in the java code. How can I do that ?

答:
Using Header we can implement Data Table in much clean & precise way and considering Data Table looks like below one -

```<code>And my_second_step
    | Heading_1        | Heading_2 | Heading_3 |
    |  Themes          |    one    | three     |
    |  Service Windows |    two    | four      |

public void my_second_step(DataTable table) throws Throwable {

List<Map<String, String>> list = table.asMaps(String.class,String.class);

System.out.println(list.get(0).get("Heading_1") + " : " + list.get(1).get("Heading_1"));
System.out.println(list.get(0).get("Heading_2") + " : " + list.get(1).get("Heading_2"));
System.out.println(list.get(0).get("Heading_3") + " : " + list.get(1).get("Heading_3"));

}
</code>```

Body:
I have below steps in my feature file for a scenario.

Given my_first_step

And my_second_step
  | Themes          | one | three |

  | Service Windows | two | four  |

And my_third_step

  | Create Apps |

  | Config      |

we can get parameters of 'my_third_step' as below in the java code as a list

public void my_third_step(List listOfItems) {}

but how can get parameters in 'my_second_step' ?
I need to get a rows as array of elements in the java code. How can I do that ?

Body:
Using Header we can implement Data Table in much clean & precise way and considering Data Table looks like below one -

And my_second_step
    | Heading_1        | Heading_2 | Heading_3 |
    |  Themes          |    one    | three     |
    |  Service Windows |    two    | four      |

public void my_second_step(DataTable table) throws Throwable {

List<Map<String, String>> list = table.asMaps(String.class,String.class);

System.out.println(list.get(0).get("Heading_1") + " : " + list.get(1).get("Heading_1"));
System.out.println(list.get(0).get("Heading_2") + " : " + list.get(1).get("Heading_2"));
System.out.println(list.get(0).get("Heading_3") + " : " + list.get(1).get("Heading_3"));

}


问:
docker compose build single container
Using Compose, if I run docker-compose build, it will rebuild all the containers :

```<code>> docker-compose build
Building elasticsearch
Step 1 : FROM elasticsearch:2.1
 ---> a05cc7ed3f32
Step 2 : RUN /usr/share/elasticsearch/bin/plugin install analysis-phonetic
 ---> Using cache
 ---> ec07bbdb8a18
Successfully built ec07bbdb8a18
Building search
Step 1 : FROM php:5.5.28-fpm
 ---> fcd24d1058c0
...
</code>```

Even when rebuilding using cache, this takes time. So my question is:

Is there a way to rebuild only one specific container?

答:
```<code>docker-compose up -d --no-deps --build <service_name>
</code>```

Source

Title: docker compose build single container

Body:
Using Compose, if I run docker-compose build, it will rebuild all the containers :

> docker-compose build
Building elasticsearch
Step 1 : FROM elasticsearch:2.1
 ---> a05cc7ed3f32
Step 2 : RUN /usr/share/elasticsearch/bin/plugin install analysis-phonetic
 ---> Using cache
 ---> ec07bbdb8a18
Successfully built ec07bbdb8a18
Building search
Step 1 : FROM php:5.5.28-fpm
 ---> fcd24d1058c0
...

Even when rebuilding using cache, this takes time. So my question is:

Is there a way to rebuild only one specific container?

Body:
docker-compose up -d --no-deps --build <service_name>

Source


问:
How to search for specific words and values in a long string?
Ok my objective is:

1.Read in a text file. e.g containing text like this, teacher/student/1/sn/2/3/4/5/9/f/tn/02/

2.pass it to a string.

3.then beable to extract different parts of the string and place them in different arrays.

The bit I dont know how to do is the extracting specific parts of the string?
Is it possible to search for / and to treat what comes after it as a specific peice of information until the next / is read?

Or perhaps there is a more efficient approach?

Help and advice sought

Kindest regards
Adrian

答:
If your strings always have separator, you can split them:

```<code>var string:String = "teacher/student/1/sn/2/3/4/5/9/f/tn/02/";
var parts:Array = string.split("/"); // ["teacher", "student", ...]
</code>```

To search specific words, RegExp might be good:

```<code>var re:RegExp = /teacher|student/;
var match:Object = re.exec(string); //match[0] = "teacher"
</code>```

Of course, check out the docs.

Body:
If your strings always have separator, you can split them:

var string:String = "teacher/student/1/sn/2/3/4/5/9/f/tn/02/";
var parts:Array = string.split("/"); // ["teacher", "student", ...]

To search specific words, RegExp might be good:

var re:RegExp = /teacher|student/;
var match:Object = re.exec(string); //match[0] = "teacher"

Of course, check out the docs.


问:
Localhost port closed on Mac (Chrome) - need to get it working
I am new to development on a local environment. I have setup my local env to run on localhost:8888.

Last night, my computer died when it ran out of battery -- I don't think this had anything to do with my problem, but just to provide background information. When I booted my local env back up, I get the following error:

```<code>This site can’t be reached localhost refused to connect.
Try:

Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
</code>```

I ran a port scan on the Network Utility app and my localhost is not up.

```<code>Port Scan has started…

Port Scanning host: 0.0.0.0

     Open TCP Port:     5432        postgresql
     Open TCP Port:     6001
Port Scan has completed…
</code>```

What can I do to get it back up and running? This is on Chrome with a Mac running OSX 10.14.4.

Firewalls are currently down, so that isn't an issue, and I am able to access all other websites.

Can anyone provide any insight?

答:
I guess you are trying to develop a web application or a website, if yes maybe you just need to restart your local web server, which is necessary to test the web thing.

Then the webpage is available again in your localhost, just check in the configuration file to know which is the correct port.

Body:
I am new to development on a local environment. I have setup my local env to run on localhost:8888.

Last night, my computer died when it ran out of battery -- I don't think this had anything to do with my problem, but just to provide background information. When I booted my local env back up, I get the following error:

This site can’t be reached localhost refused to connect.
Try:

Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED

I ran a port scan on the Network Utility app and my localhost is not up.

Port Scan has started…

Port Scanning host: 0.0.0.0

     Open TCP Port:     5432        postgresql
     Open TCP Port:     6001
Port Scan has completed…

What can I do to get it back up and running? This is on Chrome with a Mac running OSX 10.14.4.

Firewalls are currently down, so that isn't an issue, and I am able to access all other websites.

Can anyone provide any insight?


问:
How can I select only some child nodes from an XML file in C#?
I have an XML file that I want to parse. It is longer than what I shall post here, but only this part interests me in this question:

```<code>       <Team>
        <TeamId>1187457</TeamId>
        <TeamName>Zanardi Redwings</TeamName>
        <Arena>
          <ArenaId>1184019</ArenaId>
          <ArenaName>Evolution</ArenaName>
        </Arena>
        <League>
          <LeagueId>37</LeagueId>
          <LeagueName>România</LeagueName>
        </League>
        <Country>
          <CountryId>36</CountryId>
          <CountryName>România</CountryName>
        </Country>
        <LeagueLevelUnit>
          <LeagueLevelUnitId>4109</LeagueLevelUnitId>
          <LeagueLevelUnitName>V.171</LeagueLevelUnitName>
        </LeagueLevelUnit>
        <Region>
          <RegionId>799</RegionId>
          <RegionName>Prahova</RegionName>
        </Region>
        <YouthTeam>
          <YouthTeamId>2337461</YouthTeamId>
          <YouthTeamName>Little Redwings</YouthTeamName>
          <YouthLeague>
            <YouthLeagueId>436902</YouthLeagueId>
            <YouthLeagueName>Normandie Ligue des jeunes</YouthLeagueName>
          </YouthLeague>
        </YouthTeam>
      </Team>
</code>```

From the part above, I only need to read the data from the TeamId and TeamName child nodes. To achieve this, I wrote the following code:

```<code>Nodes = Node.SelectNodes("Team");
foreach (XmlNode j in Nodes)
  {
    XmlNodeList TeamDetails = j.SelectNodes("*");
    foreach (XmlNode k in TeamDetails)
      {
         switch (k.Name)
           {
             case "TeamName":
               {
                  UserTeamNames[counter] = k.InnerXml;
                  break;
               }
             case "TeamId":
               {
                  if (!int.TryParse(k.InnerXml, out UserTeamIDs[counter]))
                   {
                      ShowErrorMessageBox("Parsing TeamID from XML file failed!"); //A function which sets some parameters for MessageBox.Show() then calls it
                   }
                  break;
                }
            }
       }
   }
</code>```

In the code above, counter is an int variable, which I need in other part of the code.

The code works perfectly, but I want to eliminate the useless looping and testing when the node I am working on is not either TeamName or TeamID.

I suspect the answer I am looking for has something to do with XPath expressions, but I am not sure.

How can I read the data from only the mentioned nodes, without any useless operations?

答:
You can filter the xml document using linq then work with your filtered data.</p>

```<code>using System;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Xml;

static void Main(string[] args)
{
    var document = new XDocument();

    // use path to your xml file
    using (FileStream fs = File.OpenRead("examp.xml"))
    {
        using (XmlTextReader reader = new XmlTextReader(fs))
        {
            document = XDocument.Load(reader);
        }
    }

    int value;
    var query = (from element in document.Element("Base").Elements("Team")
                 where int.TryParse(element.Element("TeamId").Value.ToString(), out value)
                 select new
                 {
                     TeamName = element.Element("TeamName").Value,
                     TeamId = element.Element("TeamId").Value
                 }).ToList();

    // do further processing with filtered data
    foreach (var item in query)
    {
        Console.WriteLine($"{item.TeamName}: {item.TeamId}");
    }

    Console.ReadKey();
}
</code>```

Body:
I have an XML file that I want to parse. It is longer than what I shall post here, but only this part interests me in this question:

       <Team>
        <TeamId>1187457</TeamId>
        <TeamName>Zanardi Redwings</TeamName>
        <Arena>
          <ArenaId>1184019</ArenaId>
          <ArenaName>Evolution</ArenaName>
        </Arena>
        <League>
          <LeagueId>37</LeagueId>
          <LeagueName>România</LeagueName>
        </League>
        <Country>
          <CountryId>36</CountryId>
          <CountryName>România</CountryName>
        </Country>
        <LeagueLevelUnit>
          <LeagueLevelUnitId>4109</LeagueLevelUnitId>
          <LeagueLevelUnitName>V.171</LeagueLevelUnitName>
        </LeagueLevelUnit>
        <Region>
          <RegionId>799</RegionId>
          <RegionName>Prahova</RegionName>
        </Region>
        <YouthTeam>
          <YouthTeamId>2337461</YouthTeamId>
          <YouthTeamName>Little Redwings</YouthTeamName>
          <YouthLeague>
            <YouthLeagueId>436902</YouthLeagueId>
            <YouthLeagueName>Normandie Ligue des jeunes</YouthLeagueName>
          </YouthLeague>
        </YouthTeam>
      </Team>

From the part above, I only need to read the data from the TeamId and TeamName child nodes. To achieve this, I wrote the following code:

Nodes = Node.SelectNodes("Team");
foreach (XmlNode j in Nodes)
  {
    XmlNodeList TeamDetails = j.SelectNodes("*");
    foreach (XmlNode k in TeamDetails)
      {
         switch (k.Name)
           {
             case "TeamName":
               {
                  UserTeamNames[counter] = k.InnerXml;
                  break;
               }
             case "TeamId":
               {
                  if (!int.TryParse(k.InnerXml, out UserTeamIDs[counter]))
                   {
                      ShowErrorMessageBox("Parsing TeamID from XML file failed!"); //A function which sets some parameters for MessageBox.Show() then calls it
                   }
                  break;
                }
            }
       }
   }

In the code above, counter is an int variable, which I need in other part of the code.

The code works perfectly, but I want to eliminate the useless looping and testing when the node I am working on is not either TeamName or TeamID.

I suspect the answer I am looking for has something to do with XPath expressions, but I am not sure.

How can I read the data from only the mentioned nodes, without any useless operations?

Body:
You can filter the xml document using linq then work with your filtered data.

using System;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Xml;

static void Main(string[] args)
{
    var document = new XDocument();

    // use path to your xml file
    using (FileStream fs = File.OpenRead("examp.xml"))
    {
        using (XmlTextReader reader = new XmlTextReader(fs))
        {
            document = XDocument.Load(reader);
        }
    }

    int value;
    var query = (from element in document.Element("Base").Elements("Team")
                 where int.TryParse(element.Element("TeamId").Value.ToString(), out value)
                 select new
                 {
                     TeamName = element.Element("TeamName").Value,
                     TeamId = element.Element("TeamId").Value
                 }).ToList();

    // do further processing with filtered data
    foreach (var item in query)
    {
        Console.WriteLine($"{item.TeamName}: {item.TeamId}");
    }

    Console.ReadKey();
}


问:
How to automate data mapping from two excel sheets
I have two excel sheets. One Excel sheet contains the user responses (option selected by the user a/1,b/2,c/3,d/4,e/5) for the survey questions/variables and other file contains the the actual value for each of these options

Please find the example scenario

Excel file 1 contains OUTPUT data as shown below

Excel file 2 contains INPUT/DICTIONARY data as shown below

I expect my output where the options like a,b,c,d are replaced with actual values

答:
Approach

Use openpyxl read the excel file containing the mappings.

Each mapping is in the form of [number].[space][label] Eg. 1. Male, So split the string using '. ', so you get the number and its corresponding label. Store it in a dictionary

Read the file containing the inputs, now these inputs will be used as the keys for reading labels from dictionaries

Replace cell original value from the value of dictionary

Save workbook. Done!

File containing user inputs (file1.xlsx)

File containing mappings (file2.xlsx)

Code

```<code>from openpyxl import Workbook, load_workbook

#########################
#   Creating Mappings   #
#########################

# Opening file containing mappings
filename = 'file2.xlsx'

wb = load_workbook(filename)
first_sheet = wb.get_sheet_names()[0]
worksheet = wb.get_sheet_by_name(first_sheet)

# Dictonaries to store mappings
gender = {}
ethnicity = {}

#here you iterate over the rows in the specific column
for row in range(2,worksheet.max_row + 1):

    # Making a dict for gender
    for column in "A":  #Gender Col
        cell_name = "{}{}".format(column, row)
        try:
            data = worksheet[cell_name].value.split('. ') #Split data into label and number
            if data[0] not in gender:
                gender[data[0]] = data[1]
        except:
            pass

    # Making a dict for Ethnicity
    for column in "B":  #Ethnicity Col
        cell_name = "{}{}".format(column, row)
        try:
            data = worksheet[cell_name].value.split('. ') #Split data into label and number
            if data[0] not in ethnicity:
                ethnicity[data[0]] = data[1]
        except:
            pass

#########################
#   Replacing Inputs    #
#########################

# Loading file containing User Input
filename = 'file1.xlsx'

wb = load_workbook(filename)
first_sheet = wb.get_sheet_names()[0]
worksheet = wb.get_sheet_by_name(first_sheet)

#here you iterate over the rows in the specific column
for row in range(2,worksheet.max_row + 1):

    # Mapping gender input to label
    for column in "A":  #Gendedr Col
        cell_name = "{}{}".format(column, row)
        try:
            worksheet[cell_name].value = gender[str(worksheet[cell_name].value)]
        except Exception as e:
            pass

    # Mapping ethnicity input to label
    for column in "B":  #Ethnicity Col
        cell_name = "{}{}".format(column, row)
        try:
            worksheet[cell_name].value = ethnicity[str(worksheet[cell_name].value)]
        except:
            pass

wb.save(filename)
</code>```

Output

Body:
Approach

Use openpyxl read the excel file containing the mappings.

Each mapping is in the form of [number].[space][label] Eg. 1. Male, So split the string using '. ', so you get the number and its corresponding label. Store it in a dictionary

Read the file containing the inputs, now these inputs will be used as the keys for reading labels from dictionaries

Replace cell original value from the value of dictionary

Save workbook. Done!

File containing user inputs (file1.xlsx)

File containing mappings (file2.xlsx)

Code

from openpyxl import Workbook, load_workbook

#########################
#   Creating Mappings   #
#########################

# Opening file containing mappings
filename = 'file2.xlsx'

wb = load_workbook(filename)
first_sheet = wb.get_sheet_names()[0]
worksheet = wb.get_sheet_by_name(first_sheet)

# Dictonaries to store mappings
gender = {}
ethnicity = {}

#here you iterate over the rows in the specific column
for row in range(2,worksheet.max_row + 1):

    # Making a dict for gender
    for column in "A":  #Gender Col
        cell_name = "{}{}".format(column, row)
        try:
            data = worksheet[cell_name].value.split('. ') #Split data into label and number
            if data[0] not in gender:
                gender[data[0]] = data[1]
        except:
            pass

    # Making a dict for Ethnicity
    for column in "B":  #Ethnicity Col
        cell_name = "{}{}".format(column, row)
        try:
            data = worksheet[cell_name].value.split('. ') #Split data into label and number
            if data[0] not in ethnicity:
                ethnicity[data[0]] = data[1]
        except:
            pass

#########################
#   Replacing Inputs    #
#########################

# Loading file containing User Input
filename = 'file1.xlsx'

wb = load_workbook(filename)
first_sheet = wb.get_sheet_names()[0]
worksheet = wb.get_sheet_by_name(first_sheet)

#here you iterate over the rows in the specific column
for row in range(2,worksheet.max_row + 1):

    # Mapping gender input to label
    for column in "A":  #Gendedr Col
        cell_name = "{}{}".format(column, row)
        try:
            worksheet[cell_name].value = gender[str(worksheet[cell_name].value)]
        except Exception as e:
            pass

    # Mapping ethnicity input to label
    for column in "B":  #Ethnicity Col
        cell_name = "{}{}".format(column, row)
        try:
            worksheet[cell_name].value = ethnicity[str(worksheet[cell_name].value)]
        except:
            pass

wb.save(filename)

Output


问:
Python - Multiple persistent modifiable rectangle selector
I am currently trying to display an image with several highlighted and modifiable region of interests. I want to solve it by using for example the rectangleselector from the matplotlib.widgets.

The issue is just I am not able to blend in multiple persistent dragable resizeable bounding boxes.

The example is here.

If you have an alternative approach please let me know.

I would like to have like in the aforementioned example multiple rectangle selector objects. I hope you can help me.

答:
I have found a nice library as an alternative: PyQtGraph - ROI.

Here is a nice code example:

```<code>v3 = w3.addViewBox(row=1, col=0, lockAspect=True) # adds a content area
                                                  # to the existing layout

r3a = pg.ROI([0,0], [10,10])  #creates a bounding box which i need
v3.addItem(r3a) #adding it to the scene
## handles scaling horizontally around center
r3a.addScaleHandle([1, 0.5], [0.5, 0.5]) #append the box with dragable handles
r3a.addScaleHandle([0, 0.5], [0.5, 0.5]) #for nice resizing purposes

## handles scaling vertically from opposite edge
r3a.addScaleHandle([0.5, 0], [0.5, 1])
r3a.addScaleHandle([0.5, 1], [0.5, 0])

## handles scaling both vertically and horizontally
r3a.addScaleHandle([1, 1], [0, 0])
r3a.addScaleHandle([0, 0], [1, 1])
</code>```

Body:
I have found a nice library as an alternative: PyQtGraph - ROI.

Here is a nice code example:

v3 = w3.addViewBox(row=1, col=0, lockAspect=True) # adds a content area
                                                  # to the existing layout

r3a = pg.ROI([0,0], [10,10])  #creates a bounding box which i need
v3.addItem(r3a) #adding it to the scene
## handles scaling horizontally around center
r3a.addScaleHandle([1, 0.5], [0.5, 0.5]) #append the box with dragable handles
r3a.addScaleHandle([0, 0.5], [0.5, 0.5]) #for nice resizing purposes

## handles scaling vertically from opposite edge
r3a.addScaleHandle([0.5, 0], [0.5, 1])
r3a.addScaleHandle([0.5, 1], [0.5, 0])

## handles scaling both vertically and horizontally
r3a.addScaleHandle([1, 1], [0, 0])
r3a.addScaleHandle([0, 0], [1, 1])