问:
Declare multiple worksheets as variables
I am trying to declare some variables for the worksheets in this way

```<code>Dim e
For Each e In Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", "E5", "STP", "STF", "RH", "CR", "MC", "AW")
    Set wsData = ThisWorkbook.Worksheets(e)
Next e
</code>```

Is it possible to declare all the worksheets using the 1d array ..? If not, is there a workaround to smart approach to do that ..?
example wsData to refer to the worksheet "Data"
and wsCL to refer to the worksheet "CL" and so on.

答:
Array of Worksheets

The Code

```<code>Option Explicit

Sub WorksheetGroup()
    Dim wsArray As Variant, wsData As Variant, i As Long
    wsArray = Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", _
      "E5", "STP", "STF", "RH", "CR", "MC", "AW")
    wsData = getWorksheets(wsArray)
    ' e.g.
    For i = 0 To UBound(wsData)
        Debug.Print wsData(i).Name
    Next i
End Sub

Function getWorksheets(wsArray As Variant) As Variant
    Dim wsData As Variant, ws As Variant, i As Long
    ReDim wsData(UBound(wsArray))
    For Each ws In wsArray
        Set wsData(i) = ThisWorkbook.Worksheets(ws)
        i = i + 1
    Next ws
    getWorksheets = wsData
End Function
</code>```

Helper Sub

```<code>Sub AddSheets()
    Dim e As Variant
    For Each e In Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", _
      "E5", "STP", "STF", "RH", "CR", "MC", "AW")
        ThisWorkbook.Worksheets.Add , ActiveSheet
        ActiveSheet.Name = e
    Next e
End Sub
</code>```

EDIT

A Collection Version

The main differences are that you have to use Set, you have to use Add so you don't need i and that the collection is one-based. Additionally there is the Key parameter which could possibly be exploited.

```<code>Sub WorksheetGroupColl()
    Dim wsArray, wsColl As Collection, i As Long
    wsArray = Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", _
      "E5", "STP", "STF", "RH", "CR", "MC", "AW")
    Set wsColl = getWorksheetsColl(wsArray)
    ' e.g.
    For i = 1 To wsColl.Count
        Debug.Print wsColl(i).Name
    Next i
End Sub

Function getWorksheetsColl(wsArray As Variant) As Collection
    Dim wsColl As New Collection, ws As Variant
    For Each ws In wsArray
        wsColl.Add ThisWorkbook.Worksheets(ws) ' There are more parameters.
    Next ws
    Set getWorksheetsColl = wsColl
End Function
</code>```

Body:
I am trying to declare some variables for the worksheets in this way

Dim e
For Each e In Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", "E5", "STP", "STF", "RH", "CR", "MC", "AW")
    Set wsData = ThisWorkbook.Worksheets(e)
Next e

Is it possible to declare all the worksheets using the 1d array ..? If not, is there a workaround to smart approach to do that ..?
example wsData to refer to the worksheet "Data"
and wsCL to refer to the worksheet "CL" and so on.

Body:
Array of Worksheets

The Code

Option Explicit

Sub WorksheetGroup()
    Dim wsArray As Variant, wsData As Variant, i As Long
    wsArray = Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", _
      "E5", "STP", "STF", "RH", "CR", "MC", "AW")
    wsData = getWorksheets(wsArray)
    ' e.g.
    For i = 0 To UBound(wsData)
        Debug.Print wsData(i).Name
    Next i
End Sub

Function getWorksheets(wsArray As Variant) As Variant
    Dim wsData As Variant, ws As Variant, i As Long
    ReDim wsData(UBound(wsArray))
    For Each ws In wsArray
        Set wsData(i) = ThisWorkbook.Worksheets(ws)
        i = i + 1
    Next ws
    getWorksheets = wsData
End Function

Helper Sub

Sub AddSheets()
    Dim e As Variant
    For Each e In Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", _
      "E5", "STP", "STF", "RH", "CR", "MC", "AW")
        ThisWorkbook.Worksheets.Add , ActiveSheet
        ActiveSheet.Name = e
    Next e
End Sub

EDIT

A Collection Version

The main differences are that you have to use Set, you have to use Add so you don't need i and that the collection is one-based. Additionally there is the Key parameter which could possibly be exploited.

Sub WorksheetGroupColl()
    Dim wsArray, wsColl As Collection, i As Long
    wsArray = Array("Data", "CL", "SE", "GE", "E1", "E2", "E3", "E4", _
      "E5", "STP", "STF", "RH", "CR", "MC", "AW")
    Set wsColl = getWorksheetsColl(wsArray)
    ' e.g.
    For i = 1 To wsColl.Count
        Debug.Print wsColl(i).Name
    Next i
End Sub

Function getWorksheetsColl(wsArray As Variant) As Collection
    Dim wsColl As New Collection, ws As Variant
    For Each ws In wsArray
        wsColl.Add ThisWorkbook.Worksheets(ws) ' There are more parameters.
    Next ws
    Set getWorksheetsColl = wsColl
End Function


来源: stackexchange

问:
Image collage in recycler adapter
I have a typical recycler adapter set up. Some of the items in the adapter have images, sometimes just one image, sometimes 20. I want to create an image collage, like the one below, depending on the number of images in each item:

I have 10 different layouts. The first is to be used when the item only has 1 image (1 ImageView in the layout), another used when the item has 2 images (2 ImageViews in the layout), another used when the item has 3 images, etc. If the item has over 10 images, it uses the layout with 10 ImageViews and hides the rest of the images. The layouts are named:

one_image.xml

two_images.xml

three_images.xml

... etc ...

Here is my Recycler adapter:

```<code>public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

    private static Context context;
    private List<Message> mDataset;

    public RecyclerAdapter(Context context, List<Message> myDataset) {
        this.context = context;
        this.mDataset = myDataset;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener {
        public TextView title;

        public ViewHolder(View view) {
            super(view);
            view.setOnCreateContextMenuListener(this);

            title = (TextView) view.findViewById(R.id.title);
        }
    }

    @Override
    public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, parent, false);
        ViewHolder vh = new ViewHolder((LinearLayout) view);

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Message item = mDataset.get(position);

        holder.title.setText(item.getTitle());

        int numImages = item.getImages().size();
        if (numImages > 0) {
            // Show image collage
        }
    }

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

}
</code>```

Here is the main layout, message_layout.xml:

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

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    // Image collage layout

</LinearLayout>
</code>```

And this is one of the image collage layouts, two_images.xml:

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

    <ImageView
        android:id="@+id/image_one"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        />

    <ImageView
        android:id="@+id/image_two"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        />

</LinearLayout>
</code>```

So the question is, how do I load/inflate the correct layout depending on the number of images into the recycler adapter, and populate the layout with the images?

答:
You should create a custom ViewHolder for each one of your layouts.

Imagine you have this ViewHolder: TwoImagesViewHolder

```<code>public class TwoImagesViewHolder extends RecyclerView.ViewHolder {
    public TextView title;
    public ImageView imageOne;
    public ImageView imageTwo;

    public TwoImagesViewHolder(@NonNull View view) {
        super(view);
        title = (TextView)view.findViewById(R.id.title);
        imageOne = (ImageView)view.findViewById(R.id.image_one);
        imageTwo = (ImageView)view.findViewById(R.id.image_two);
    }
}
</code>```

Inside the adapter you can use your holder like this:

```<code>@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Message item = mDataset.get(position);
    int numImages = item.getImages().size();
    if (numImages == 2) {
        return new TwoImagesViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, parent, false))
    }

    // Add all the conditions for your custom ViewHolders

    return DefaultViewHolder; // Define a Default holder
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Message item = mDataset.get(position);
    int numImages = item.getImages().size();
    if (numImages == 2) {
      // Show image collage
      TwoImagesViewHolder holder = (TwoImagesViewHolder)viewHolder;
      holder.title.setText(item.getTitle());
      holder.image_one.setImageResource(...);
      holder.image_two.setImageResource(...);
    }

    // Add all the conditions for your custom ViewHolders
}
</code>```

You need to create all your conditions to instance the correct layout holder and remember to have the same conditions for the onCreateViewHolder and onBindViewHolder.

ContentLicense: CC BY-SA 3.0

Title: Image collage in recycler adapter

Body:
I have a typical recycler adapter set up. Some of the items in the adapter have images, sometimes just one image, sometimes 20. I want to create an image collage, like the one below, depending on the number of images in each item:

I have 10 different layouts. The first is to be used when the item only has 1 image (1 ImageView in the layout), another used when the item has 2 images (2 ImageViews in the layout), another used when the item has 3 images, etc. If the item has over 10 images, it uses the layout with 10 ImageViews and hides the rest of the images. The layouts are named:

one_image.xml

two_images.xml

three_images.xml

... etc ...

Here is my Recycler adapter:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {

    private static Context context;
    private List<Message> mDataset;

    public RecyclerAdapter(Context context, List<Message> myDataset) {
        this.context = context;
        this.mDataset = myDataset;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener {
        public TextView title;

        public ViewHolder(View view) {
            super(view);
            view.setOnCreateContextMenuListener(this);

            title = (TextView) view.findViewById(R.id.title);
        }
    }

    @Override
    public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, parent, false);
        ViewHolder vh = new ViewHolder((LinearLayout) view);

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Message item = mDataset.get(position);

        holder.title.setText(item.getTitle());

        int numImages = item.getImages().size();
        if (numImages > 0) {
            // Show image collage
        }
    }

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

}

Here is the main layout, message_layout.xml:

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

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    // Image collage layout

</LinearLayout>

And this is one of the image collage layouts, two_images.xml:

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

    <ImageView
        android:id="@+id/image_one"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        />

    <ImageView
        android:id="@+id/image_two"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        />

</LinearLayout>

So the question is, how do I load/inflate the correct layout depending on the number of images into the recycler adapter, and populate the layout with the images?

Body:
You should create a custom ViewHolder for each one of your layouts.

Imagine you have this ViewHolder: TwoImagesViewHolder

public class TwoImagesViewHolder extends RecyclerView.ViewHolder {
    public TextView title;
    public ImageView imageOne;
    public ImageView imageTwo;

    public TwoImagesViewHolder(@NonNull View view) {
        super(view);
        title = (TextView)view.findViewById(R.id.title);
        imageOne = (ImageView)view.findViewById(R.id.image_one);
        imageTwo = (ImageView)view.findViewById(R.id.image_two);
    }
}

Inside the adapter you can use your holder like this:

@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Message item = mDataset.get(position);
    int numImages = item.getImages().size();
    if (numImages == 2) {
        return new TwoImagesViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, parent, false))
    }

    // Add all the conditions for your custom ViewHolders

    return DefaultViewHolder; // Define a Default holder
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Message item = mDataset.get(position);
    int numImages = item.getImages().size();
    if (numImages == 2) {
      // Show image collage
      TwoImagesViewHolder holder = (TwoImagesViewHolder)viewHolder;
      holder.title.setText(item.getTitle());
      holder.image_one.setImageResource(...);
      holder.image_two.setImageResource(...);
    }

    // Add all the conditions for your custom ViewHolders
}

You need to create all your conditions to instance the correct layout holder and remember to have the same conditions for the onCreateViewHolder and onBindViewHolder.

ContentLicense: CC BY-SA 4.0


问:
How to make edit text not editable but clickable in JAVA
Is it possible to make EditText clickable but not editable.

I don't want it to be editable (Neither should the keyboard come up nor should we be able to change the hint)

Actually I want to use Edit text simply as an image with a hint (which cannot be changed). I know the actual way was to use an ImageView and one TextView, but I want it to try with EditText because I'll then be using only one view instead of 2. Also every thing is dynamic so no XML.

For the above requirement the solution in XML is android:editable="false" but I want to use this in Java.

But,

If I use :-

```<code>et.setEnabled(false);
</code>```

or

```<code> et.setKeyListener(null);
</code>```

It makes the EditText not EDITABLE but at the same time it makes it non clickable as well.

答:
As of 2020, if you also care about accessibility, you should avoid setting et.setFocusable(false); since that will make the EditText not reachable using Keyboard navigation.

Here is my solution:

Kotlin

```<code>editText.isFocusableInTouchMode = false

editText.isLongClickable = false //this will prevent copy and paste

editText.setOnClickListener {
   // handle the click
   // this will automatically make the edittext clickable = true
}
</code>```

Body:
Is it possible to make EditText clickable but not editable.

I don't want it to be editable (Neither should the keyboard come up nor should we be able to change the hint)

Actually I want to use Edit text simply as an image with a hint (which cannot be changed). I know the actual way was to use an ImageView and one TextView, but I want it to try with EditText because I'll then be using only one view instead of 2. Also every thing is dynamic so no XML.

For the above requirement the solution in XML is android:editable="false" but I want to use this in Java.

But,

If I use :-

et.setEnabled(false);

or

 et.setKeyListener(null);

It makes the EditText not EDITABLE but at the same time it makes it non clickable as well.

Body:
As of 2020, if you also care about accessibility, you should avoid setting et.setFocusable(false); since that will make the EditText not reachable using Keyboard navigation.

Here is my solution:

Kotlin

editText.isFocusableInTouchMode = false

editText.isLongClickable = false //this will prevent copy and paste

editText.setOnClickListener {
   // handle the click
   // this will automatically make the edittext clickable = true
}


Title: applying cut() on R dataframe daywise

Body:
I have a datatable in R on which I apply a cut() and table(). I am able to get the frequency table based on the conditions. But I am getting overall frequencies. I want to get it day wise. I have a column named as timestamp which have timestamp. Also I have a section column which has value either A or B. How to cut it based on each day each section.

My current output :

Var1    Freq
0-30    1398
30-60   1051
60-80   1006
80-100  36
100>    2

Expected output:

Date        Sec  Var1    Freq
05-01-2020   A   0-30    1398
05-01-2020   A   30-60   1051
05-01-2020   A   60-80   1006
05-01-2020   A   80-100  36
05-01-2020   A   100>    2
05-01-2020   B   0-30    138
05-01-2020   B   30-60   151
05-01-2020   B   60-80   1056
05-01-2020   B   80-100  3
05-01-2020   B   100>    6
06-01-2020   A   0-30    398
06-01-2020   A   30-60   11
06-01-2020   A   60-80   16
06-01-2020   A   80-100  3666
06-01-2020   A   100>    25
06-01-2020   B   0-30    1948
06-01-2020   B   30-60   233
06-01-2020   B   60-80   33
06-01-2020   B   80-100  433
06-01-2020   B   100>    34
and so on.....

My code :

result = as.data.frame(table(cut(df$temp,breaks=c(0,30,60,80,100,1000),labels=c("0-30","30-60","60-80","80-100","100>"))))

Sample data :

timestamp        section    temp
01-05-2020 00:01:22 A   45
02-05-2020 00:01:22 A   10
03-05-2020 00:01:22 A   98
04-05-2020 00:01:22 A   23
05-05-2020 00:01:22 A   67
06-05-2020 00:01:22 A   89
07-05-2020 00:01:22 A   100
08-05-2020 00:01:22 A   110
09-05-2020 00:01:22 A   123
10-05-2020 00:01:22 A   12
01-05-2020 00:01:22 B   23
02-05-2020 00:01:22 B   44
03-05-2020 00:01:22 B   55
04-05-2020 00:01:22 B   12
05-05-2020 00:01:22 B   98
06-05-2020 00:01:22 B   45
07-05-2020 00:01:22 B   87
08-05-2020 00:01:22 B   65
09-05-2020 00:01:22 B   12
10-05-2020 00:01:22 B   8

Body:
This question has been tagged with data.table. So, for the sake of completeness, here is also a data.table solution:

library(data.table)
setDT(df)[, .(Freq = .N),
          by = .(Date = as.IDate(timestamp, "%d-%m-%Y"), section,
                 Var1 = cut(temp, c(0, 30, 60, 80, 100, Inf), c("0-30", "30-60", "60-80", "80-100", "100>")))]

          Date section   Var1 Freq
 1: 2020-05-01       A  30-60    1
 2: 2020-05-02       A   0-30    1
 3: 2020-05-03       A 80-100    1
 4: 2020-05-04       A   0-30    1
 5: 2020-05-05       A  60-80    1
 6: 2020-05-06       A 80-100    1
 7: 2020-05-07       A 80-100    1
 8: 2020-05-08       A   100>    1
 9: 2020-05-09       A   100>    1
10: 2020-05-10       A   0-30    1
11: 2020-05-01       B   0-30    1
12: 2020-05-02       B  30-60    1
13: 2020-05-03       B  30-60    1
14: 2020-05-04       B   0-30    1
15: 2020-05-05       B 80-100    1
16: 2020-05-06       B  30-60    1
17: 2020-05-07       B 80-100    1
18: 2020-05-08       B  60-80    1
19: 2020-05-09       B   0-30    1
20: 2020-05-10       B   0-30    1

or, in a more programmatic way

breaks <- c(0, 30, 60, 80, 100, Inf)
labels <- stringr::str_replace(paste(head(breaks, -1L), tail(breaks, -1L), sep = "-"), "-Inf", ">")
setDT(df)[, .(Freq = .N), by = .(Date = as.IDate(timestamp, "%d-%m-%Y"), section,
                                 Var1 = cut(temp, breaks, labels))]

Data

library(data.table)
df <- fread(
  "timestamp time       section    temp
01-05-2020 00:01:22 A   45
02-05-2020 00:01:22 A   10
03-05-2020 00:01:22 A   98
04-05-2020 00:01:22 A   23
05-05-2020 00:01:22 A   67
06-05-2020 00:01:22 A   89
07-05-2020 00:01:22 A   100
08-05-2020 00:01:22 A   110
09-05-2020 00:01:22 A   123
10-05-2020 00:01:22 A   12
01-05-2020 00:01:22 B   23
02-05-2020 00:01:22 B   44
03-05-2020 00:01:22 B   55
04-05-2020 00:01:22 B   12
05-05-2020 00:01:22 B   98
06-05-2020 00:01:22 B   45
07-05-2020 00:01:22 B   87
08-05-2020 00:01:22 B   65
09-05-2020 00:01:22 B   12
10-05-2020 00:01:22 B   8")[
  , c("timestamp", "time") := .(paste(timestamp, time), NULL)]


问:
How To Use Paypal Payout PHP API
I'm using PHP and I want to send money to users who have sold their products on my platform. For this I'm trying to use Paypal Payouts, I've found this link here with an example code for a single payout.

My problem is that, I'm not that good in PHP and I have no clue how this actually works. The latter part of the script is more or less understandable however, I'm really unsure about these lines here:

```<code>require __DIR__ . '/../bootstrap.php';
$payouts = new \PayPal\Api\Payout();
$senderBatchHeader = new \PayPal\Api\PayoutSenderBatchHeader();
</code>```

What is bootstrap.php and why is it necessary for this paypal payout system? Also I need to know how do these objects here work new \PayPal\Api\PayoutSenderBatchHeader() I really do not understand the syntax here.

Can someone explain what these three lines exactly mean and why they are needed for the paypal payout and how they work?

答:
The PayPal-PHP-SDK is deprecated and should not be used for any new integration.

On the list of current SDKs you will find the Payouts PHP SDK.

Title: How To Use Paypal Payout PHP API

Body:
I'm using PHP and I want to send money to users who have sold their products on my platform. For this I'm trying to use Paypal Payouts, I've found this link here with an example code for a single payout.

My problem is that, I'm not that good in PHP and I have no clue how this actually works. The latter part of the script is more or less understandable however, I'm really unsure about these lines here:

require __DIR__ . '/../bootstrap.php';
$payouts = new \PayPal\Api\Payout();
$senderBatchHeader = new \PayPal\Api\PayoutSenderBatchHeader();

What is bootstrap.php and why is it necessary for this paypal payout system? Also I need to know how do these objects here work new \PayPal\Api\PayoutSenderBatchHeader() I really do not understand the syntax here.

Can someone explain what these three lines exactly mean and why they are needed for the paypal payout and how they work?


问:
Error in PDF root object
This PDF root object will get Adobe Reader to fail. Other PDF readers like Foxit, Nuance, Evince, SumatraPDF will open the PDF file without problems. The problem is /Dests which reguires an indirect object (PDF reference). Deleting the /Dests << >> will get Adobe Reader to open the file, but fail on printing. All the other readers work OK without the /Dests. Any ideas how to correct the syntax in the following root object example?</p>

```<code>  17 0 obj
  <<
    /Type /Catalog
    /Pages 2 0 R
    /Outlines 15 0 R
    /PageMode /UseOutlines
    /Dests <<
             /__WKANCHOR_2 8 0 R
             /#8d#c2#ca#ebs#e4#60#00#9e#97l#b9#80#1b#cb#86sQR#83 9 0 R
           >>
  >>
  endobj
</code>```

答:
/Dests is supposed to be a dictionary (pairs of /Key value) containing names (Keys) and corresponding destinations (values). The /Dests keyword first appeared in PDF 1.1.

PDF 1.1 allowed for the keys only to be a name object. PDF 1.2 allowed for keys to also be byte strings.

So which PDF version does your file claim to be?

From the spec for PDF 1.7 ("ISO 32000-1"), describing the meaning of /Dests:

In PDF 1.1, the correspondence between name objects and destinations shall be defined by the Dests entry in the document catalogue (see 7.7.2, “Document Catalog”). The value of this entry shall be a dictionary in which each key is a destination name and the corresponding value is either an array defining the destination, using the syntax shown in Table 151, or a dictionary with a D entry whose value is such an array.

Title: Error in PDF root object

Body:
This PDF root object will get Adobe Reader to fail. Other PDF readers like Foxit, Nuance, Evince, SumatraPDF will open the PDF file without problems. The problem is /Dests which reguires an indirect object (PDF reference). Deleting the /Dests << >> will get Adobe Reader to open the file, but fail on printing. All the other readers work OK without the /Dests. Any ideas how to correct the syntax in the following root object example?

  17 0 obj
  <<
    /Type /Catalog
    /Pages 2 0 R
    /Outlines 15 0 R
    /PageMode /UseOutlines
    /Dests <<
             /__WKANCHOR_2 8 0 R
             /#8d#c2#ca#ebs#e4#60#00#9e#97l#b9#80#1b#cb#86sQR#83 9 0 R
           >>
  >>
  endobj


问:
Implementing Autoplay on glider.js
So I'm working with glider.js (https://nickpiscitelli.github.io/Glider.js/) on my website for handling slides, because I really want to keep it minimal (I know there are other sliders out there, but glider.js is the lightest). However, I really need the autoplay function, but I can't seem to be able to make it work (I don't really know my way around JS, I just copy code snippets for things I need)

I found some code for an autoplay, it looks like this:

```<code>function sliderAuto(slider, miliseconds) {
 slider.isLastSlide = function() {
   return slider.page >= slider.dots.childElementCount - 1;
 }

 var slide = function() {
   slider.slideTimeout = setTimeout(function() {
     function slideTo() {
       return slider.isLastSlide() ? 0 : slider.page + 1;
     }

     slider.scrollItem(slideTo(), true);
   }, miliseconds);
 }

 slider.ele.addEventListener('glider-animated', function(event) {
   window.clearInterval(slider.slideTimeout);
   slide();
 });

 slide();
}
</code>```

But I don't know how to activate it, to make it work. I know I should pass the parameters to "slider" and "miliseconds", but I don't know what exactly should I pass, should I set a special class to each slide, and pass that class? Let's say my html is the following:

```<code><div class="glider-contain">
  <div class="glider">
    <div>your content here</div>
    <div>your content here</div>
    <div>your content here</div>
    <div>your content here</div>
  </div>
</code>```

How do I make the autoplay work? Thanks!

答:
Based on the docs that you've linked and the code snippet i would say that
First things first, slider parameter is supposed to be your glidder object (what you created with new Glidder(..., and milliseconds is the amount of time in milliseconds that each slide will be visible.

Now, an example of what it could look like:

1

2

3

4

```

<pre class="lang-js prettyprint-override"><code>const glider = new Glider(document.getElementById('glider'));

function sliderAuto(slider, miliseconds) {
 const slidesCount = slider.track.childElementCount;
 let slideTimeout = null;
 let nextIndex = 1;

 function slide () {
   slideTimeout = setTimeout(
     function () {
       if (nextIndex >= slidesCount ) {
         nextIndex = 0;
       }
       slider.scrollItem(nextIndex++);
     },
     miliseconds
   );
 }

 slider.ele.addEventListener('glider-animated', function() {
   window.clearInterval(slideTimeout);
   slide();
 });

 slide();
}

sliderAuto(glider, 1000)
</code>```

I've edited the snippet a bit because you don't seem to use dots.
working fiddle

Title: Implementing Autoplay on glider.js

Body:
So I'm working with glider.js (https://nickpiscitelli.github.io/Glider.js/) on my website for handling slides, because I really want to keep it minimal (I know there are other sliders out there, but glider.js is the lightest). However, I really need the autoplay function, but I can't seem to be able to make it work (I don't really know my way around JS, I just copy code snippets for things I need)

I found some code for an autoplay, it looks like this:

function sliderAuto(slider, miliseconds) {
 slider.isLastSlide = function() {
   return slider.page >= slider.dots.childElementCount - 1;
 }

 var slide = function() {
   slider.slideTimeout = setTimeout(function() {
     function slideTo() {
       return slider.isLastSlide() ? 0 : slider.page + 1;
     }

     slider.scrollItem(slideTo(), true);
   }, miliseconds);
 }

 slider.ele.addEventListener('glider-animated', function(event) {
   window.clearInterval(slider.slideTimeout);
   slide();
 });

 slide();
}

But I don't know how to activate it, to make it work. I know I should pass the parameters to "slider" and "miliseconds", but I don't know what exactly should I pass, should I set a special class to each slide, and pass that class? Let's say my html is the following:

your content here

your content here

your content here

your content here

How do I make the autoplay work? Thanks!

Body:
Based on the docs that you've linked and the code snippet i would say that
First things first, slider parameter is supposed to be your glidder object (what you created with new Glidder(..., and milliseconds is the amount of time in milliseconds that each slide will be visible.

Now, an example of what it could look like:

<div class="glider-contain">
  <div id="glider" class="glider">
    <div class="placeholder">1</div>
    <div class="placeholder">2</div>
    <div class="placeholder">3</div>
    <div class="placeholder">4</div>
  </div>
</div>

const glider = new Glider(document.getElementById('glider'));

function sliderAuto(slider, miliseconds) {
 const slidesCount = slider.track.childElementCount;
 let slideTimeout = null;
 let nextIndex = 1;

 function slide () {
   slideTimeout = setTimeout(
     function () {
       if (nextIndex >= slidesCount ) {
         nextIndex = 0;
       }
       slider.scrollItem(nextIndex++);
     },
     miliseconds
   );
 }

 slider.ele.addEventListener('glider-animated', function() {
   window.clearInterval(slideTimeout);
   slide();
 });

 slide();
}

sliderAuto(glider, 1000)

I've edited the snippet a bit because you don't seem to use dots.
working fiddle


问:
Problems getting updated information with PHP exec()
I have simple code that uses exec() to set a variable with some system information (like current IP.) I execute the code and display the information. I change the IP address of the computer and rerun the code. I'm using unset() to clear the variable before executing the code, however, it still displays the old information. How do I obtain the current information using exec()? Thanks in advance and sorry for the noob-iness.</p>

```<code>  <button type="button" class="btn btn-info btn-lg" onclick="showip()">Get IP</button>

  <script>
  function showip(){
     <?php
        unset($return);
        unset($ip);
        exec('wget https://ipinfo.io/ip -qO -', $return);
        $ip = $return[0];
     ?>
     curip = <?php echo(json_encode($ip, JSON_HEX_TAG)); ?>;
     alert("The current IP is "+curip);
   }
  </script>
</code>```

答:
PHP runs on the server, this is why you're always getting the same IP address.

If you want the client's IP address you can use

```<code>$_SERVER["REMOTE_ADDR"]
</code>```

'REMOTE_ADDR'

The IP address from which the user is viewing the current page.

Another solution would be to make an AJAX request to https://ipinfo.io/ip.

```<code>function showip() {
    fetch("https://ipinfo.io/ip")
    .then(function(response) {
        return response.text()
    })
    .then(function(ip) {
        alert("The current IP is " + ip)
    })
}
</code>```

Body:
I have simple code that uses exec() to set a variable with some system information (like current IP.) I execute the code and display the information. I change the IP address of the computer and rerun the code. I'm using unset() to clear the variable before executing the code, however, it still displays the old information. How do I obtain the current information using exec()? Thanks in advance and sorry for the noob-iness.

  <button type="button" class="btn btn-info btn-lg" onclick="showip()">Get IP</button>

Body:
PHP runs on the server, this is why you're always getting the same IP address.

If you want the client's IP address you can use

$_SERVER["REMOTE_ADDR"]

'REMOTE_ADDR'

The IP address from which the user is viewing the current page.

Another solution would be to make an AJAX request to https://ipinfo.io/ip.

function showip() {
    fetch("https://ipinfo.io/ip")
    .then(function(response) {
        return response.text()
    })
    .then(function(ip) {
        alert("The current IP is " + ip)
    })
}


问:
.htaccess redirection from sub folder to current folder with with query parameters
I have index.php with query pi which looks like this : index.php?pi=1

.htaccess code is the following :

```<code>RewriteRule ^([0-9]+)/$ index.php?pi=$1 [NC,L]
</code>```

which was supposed to make it look like   /current_folder/ , /current_folder/2/, /current_folder/3/

This is causing duplicated issue in Google as : /current_folder/ 's content is equal to /current_folder/1/.

I need to redirect all /current_folder/1/ to /current_folder/, and however leave /current_folder/2/, or higher, as they are.

答: Problem solved via php solution using if else structure, i.e. when we are on page no.2 view /current folder/ for previous. all good.</p>

Body:
I have index.php with query pi which looks like this : index.php?pi=1

.htaccess code is the following :

RewriteRule ^([0-9]+)/$ index.php?pi=$1 [NC,L]

which was supposed to make it look like   /current_folder/ , /current_folder/2/, /current_folder/3/

This is causing duplicated issue in Google as : /current_folder/ 's content is equal to /current_folder/1/.

I need to redirect all /current_folder/1/ to /current_folder/, and however leave /current_folder/2/, or higher, as they are.


问:
Python Pandas Data not aligned correctly
I am building a dataframe from a directory of text files that contain memory readings. I am giving the column the name Memory.

But when the data gets imported there is a column of zeros, the column with the memory readings that I want, and the Memory column has an NaN by each entry (not a number, I presume):

output:

```<code>***Memory Data Frame:
            0 Memory
0   1843260.0    NaN
0   7706164.0    NaN
0   7904828.0    NaN
0   7706164.0    NaN
0   7706172.0    NaN
0   7648524.0    NaN
0   7648524.0    NaN
0   7706172.0    NaN
0   7706164.0    NaN
0   7904828.0    NaN
0   7706172.0    NaN
0   7648524.0    NaN
0   7706172.0    NaN
0  16075888.0    NaN
0   7904672.0    NaN
0   7904680.0    NaN
0   7904672.0    NaN
0   7904680.0    NaN
0  16075880.0    NaN
0   7904672.0    NaN
***
</code>```

I'm not sure why the data is misaligned with a row of all zeros, the memory readings are floats with a trailing .0, or why there's a row of NaN in the Memory column. Here is my most recent code.

code:

```<code># Create the memory dataframe
column_names = ["Memory"]
memory_df = pd.DataFrame(columns = column_names)
memory_df.astype('int32').dtypes
temp_df = pd.DataFrame(columns = column_names)
temp_df.astype('int32').dtypes
print(f"Reading text files into the Memory DF")
for filename in filelist:
    print(f"Adding filename: {filename}")
    filename = text_path + filename
    temp_df = pd.read_csv(filename, delim_whitespace=True, header=None)
    temp_df.astype('int32').dtypes
    memory_df = memory_df.append(temp_df)
</code>```

How can I ingest the data with JUST one Memory column with the memory readings shown as integers with no trailing .0?

答:
I don't see the structure of your .csv files, but I suppose from your output that the consist of 1 column of (integer) numbers.

I deleted all useless rows from your code, edited 1 row and appended another 1, so the working code (tested by myself) is

```<code># Create the memory dataframe

column_names = ["Memory"]
memory_df = pd.DataFrame(columns=column_names)
print(f"Reading text files into the Memory DF")
for filename in filelist:
    print(f"Adding filename: {filename}")
    filename = text_path + filename
    temp_df = pd.read_csv(filename, delim_whitespace=True, names=column_names)
    memory_df = memory_df.append(temp_df)

memory_df.Memory = memory_df.Memory.astype("int32")
</code>```

The resulting memory_df dataframe:

```<code>        Memory
0      1843260
1      7706164
2      7904828
3      7706164
4      7706172
5      7648524
6      7648524
7      7706172
8      7706164
9      7904828
10     7706172
11     7648524
12     7706172
13    16075888
14     7904672
15     7904680
16     7904672
17     7904680
18    16075880
19     7904672
</code>```

Body:
I am building a dataframe from a directory of text files that contain memory readings. I am giving the column the name Memory.

But when the data gets imported there is a column of zeros, the column with the memory readings that I want, and the Memory column has an NaN by each entry (not a number, I presume):

output:

***Memory Data Frame:
            0 Memory
0   1843260.0    NaN
0   7706164.0    NaN
0   7904828.0    NaN
0   7706164.0    NaN
0   7706172.0    NaN
0   7648524.0    NaN
0   7648524.0    NaN
0   7706172.0    NaN
0   7706164.0    NaN
0   7904828.0    NaN
0   7706172.0    NaN
0   7648524.0    NaN
0   7706172.0    NaN
0  16075888.0    NaN
0   7904672.0    NaN
0   7904680.0    NaN
0   7904672.0    NaN
0   7904680.0    NaN
0  16075880.0    NaN
0   7904672.0    NaN
***

I'm not sure why the data is misaligned with a row of all zeros, the memory readings are floats with a trailing .0, or why there's a row of NaN in the Memory column. Here is my most recent code.

code:

# Create the memory dataframe
column_names = ["Memory"]
memory_df = pd.DataFrame(columns = column_names)
memory_df.astype('int32').dtypes
temp_df = pd.DataFrame(columns = column_names)
temp_df.astype('int32').dtypes
print(f"Reading text files into the Memory DF")
for filename in filelist:
    print(f"Adding filename: {filename}")
    filename = text_path + filename
    temp_df = pd.read_csv(filename, delim_whitespace=True, header=None)
    temp_df.astype('int32').dtypes
    memory_df = memory_df.append(temp_df)

How can I ingest the data with JUST one Memory column with the memory readings shown as integers with no trailing .0?

Body:
I don't see the structure of your .csv files, but I suppose from your output that the consist of 1 column of (integer) numbers.

I deleted all useless rows from your code, edited 1 row and appended another 1, so the working code (tested by myself) is

# Create the memory dataframe

column_names = ["Memory"]
memory_df = pd.DataFrame(columns=column_names)
print(f"Reading text files into the Memory DF")
for filename in filelist:
    print(f"Adding filename: {filename}")
    filename = text_path + filename
    temp_df = pd.read_csv(filename, delim_whitespace=True, names=column_names)
    memory_df = memory_df.append(temp_df)

memory_df.Memory = memory_df.Memory.astype("int32")

The resulting memory_df dataframe:

        Memory
0      1843260
1      7706164
2      7904828
3      7706164
4      7706172
5      7648524
6      7648524
7      7706172
8      7706164
9      7904828
10     7706172
11     7648524
12     7706172
13    16075888
14     7904672
15     7904680
16     7904672
17     7904680
18    16075880
19     7904672


问:
Populate dynamically rendered form fields in react
I am having 3 materialUI TextFields which are render n number of times (n is an integer input from the user before rendering the form field, where I stored it in a variable named groupMembersCount).
I am getting it dynamically rendered by this way:

```<code>export default function DynamicGroupMember() {
    const [groupMembersCount, setGroupMembersCount] = useState(0);
    const [show, setShow] = useState(false);
    const [groupDetails, setGroupDetails] = useState([
        {fullName: "", phoneNo: "", gender: ""},
    ]);
  function handleChange(event, index) {
        console.log(event.target.value, index);
        let newArr = [...groupDetails]; // copying the old datas array
        let item = newArr[index];
        item = {...item, [event.target.name]: event.target.value};
        newArr[index] = item;

        setGroupDetails(newArr);
    }

    return (
        <div>
            Number of Group: <TextField name="groupMembersCount" onChange={(event) => {
            setGroupMembersCount(event.target.value)
        }}/>
            {Array.apply(null, {length: groupMembersCount}).map(
                (e, i) => (
                    <div key={i}>
                        <strong>Member #{i + 1}</strong>
                        <div className="getIndex" name={i + 1}>
                            <TextField
                                id={`name${i + 1}`}
                                name="fullName"
                                variant="outlined"
                                margin="none"
                                label="Name"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <TextField
                                id={`phoneNo${i + 1}`}
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <Select
                                id={`gender${i + 1}`}
                                name="gender"
                                variant="outlined"
                                margin="none"
                                label="Gender"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            >
                                <option value="MALE">Male</option>
                                <option value="FEMALE">Female</option>
                                <option value="OTHER">Other</option>
                            </Select>
                        </div>
                    </div>
                )
            )}
            <Button onClick={() => {
                setShow(true)
            }}>Show</Button>
            {
                show ?
                    groupDetails.map(member =>
                        <Card>
                        <CardContent>
                            <Typography color="textSecondary" gutterBottom>
                                {member.fullName}
                            </Typography>
                            <Typography variant="h5" component="h2">
                                {member.phoneNo}
                            </Typography>
                            <Typography color="textSecondary">
                                {member.gender}
                            </Typography>
                        </CardContent>
                    </Card>) : null
            }
        </div>
    );
}
</code>```

What if I filled the number (groupMembersCount) and then filled those form fields and after filling, I modified groupMembersCount (either increase or decrease), in case of increase I want the values that user filled should retain and if decreased, form fields values should clear out.
I tried passing values from groupDetails array to form in "value" prop but it shows an error because the index I an writing/passing the values initially doesn't exist at that index.

答:
You need set value from groupDetails that was stored before using useState. Please check this example:

```<code>import TextField from "@material-ui/core/TextField";
import React, {useState} from "react";
import Select from "@material-ui/core/Select";
import Button from "@material-ui/core/Button";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography";

export default function DynamicGroupMember3() {
    const [groupMembersCount, setGroupMembersCount] = useState(0);
    const [show, setShow] = useState(false);
    const [errorText, setErrorText] = useState([]);
    const [showState, setShowState] = useState(false);
    const [groupDetails, setGroupDetails] = useState([
        {fullName: "", phoneNo: "", gender: ""},
    ]);
    const [state, setState] = React.useState({
        idProof: "",
        noOfPeople: "",
        bookingId: "",
        detailsOfPeople: [],
    });

    function handleChange(event, index) {
        event.preventDefault();
        console.log(errorText.length, 'length');
        if (event.target.name === "phoneNo") {
            // do validation here
            let valid = false;
            if (isNaN(event.target.value)) {
                let arr = [...errorText];
                arr[index] = 'Invalid ' + event.target.name;
                setErrorText(arr);
            } else {
                let arr = [...errorText];
                arr[index] = '';
                setErrorText(arr);
            }
        }

        let newArr = [...groupDetails]; // copying the old datas array
        let item = newArr[index];
        item = {...item, [event.target.name]: event.target.value};
        newArr[index] = item;
        setGroupDetails(newArr);
    }

    return (
        <div>
            Number of Group: <TextField name="groupMembersCount" onChange={(event) => {
            if (isNaN(event.target.value)) {
                alert('Please enter number');
                return;
            }
            if (event.target.value !== '') {
                let noOfMember = parseInt(event.target.value);
                let errors = new Array(noOfMember);
                setErrorText(errors);
                if (groupMembersCount > noOfMember) {
                    let newGroup = [];
                    groupDetails.map((group, index) => {
                        if (index < noOfMember) {
                            newGroup.push(group);
                        }
                    });
                    setGroupDetails(newGroup);
                }
                setGroupMembersCount(noOfMember);
            }
        }}/>
            {Array.apply(null, {length: groupMembersCount}).map(
                (e, i) => (
                    <div key={i}>
                        <strong>Member #{i + 1}</strong>
                        <div className="getIndex" name={i + 1}>
                            <TextField
                                id={`name${i + 1}`}
                                name="fullName"
                                variant="outlined"
                                margin="none"
                                label="Name"
                                value={groupDetails[i] ? groupDetails[i].fullName : ''}
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <TextField
                                id={`phoneNo${i + 1}`}
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                value={groupDetails[i] ? groupDetails[i].phoneNo : ''}
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                                error={errorText[i] !== '' && errorText[i] !== undefined}
                                helperText={errorText[i]}
                            />
                            <Select
                                id={`gender${i + 1}`}
                                name="gender"
                                variant="outlined"
                                margin="none"
                                label="Gender"
                                value={groupDetails[i] ? groupDetails[i].gender : ''}
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            >
                                <option value="MALE">Male</option>
                                <option value="FEMALE">Female</option>
                                <option value="OTHER">Other</option>
                            </Select>
                        </div>
                    </div>
                )
            )}
            <Button onClick={() => {
                setShow(true)
            }}>Show</Button>
            {
                show ?
                    groupDetails.map((member, index) =>
                        <Card key={index}>
                            <CardContent>
                                <Typography color="textSecondary" gutterBottom>
                                    {member.fullName}
                                </Typography>
                                <Typography variant="h5" component="h2">
                                    {member.phoneNo}
                                </Typography>
                                <Typography color="textSecondary">
                                    {member.gender}
                                </Typography>
                            </CardContent>
                        </Card>) : null
            }
            <Button onClick={() => {
                console.log(groupDetails, 'groupDetails');
                setState({
                    idProof: "XYZ123",
                    noOfPeople: groupDetails.length,
                    bookingId: "boking-4434",
                    detailsOfPeople: groupDetails
                });
                console.log(groupDetails, 'groupDetails');
                setShowState(true);

            }}>Show STATE</Button>
            {
                showState ?
                    <Card>
                        <CardContent>
                            <Typography color="textSecondary" gutterBottom>
                                Id Proof: {state.idProof}
                            </Typography>
                            <Typography variant="h5" component="h2">
                                No Of People: {state.noOfPeople}
                            </Typography>
                            <Typography color="textSecondary">
                                Booking Id: {state.bookingId}
                            </Typography>
                        </CardContent>
                    </Card> : null
            }
        </div>
    );
}
</code>```

Body:
I am having 3 materialUI TextFields which are render n number of times (n is an integer input from the user before rendering the form field, where I stored it in a variable named groupMembersCount).
I am getting it dynamically rendered by this way:

export default function DynamicGroupMember() {
    const [groupMembersCount, setGroupMembersCount] = useState(0);
    const [show, setShow] = useState(false);
    const [groupDetails, setGroupDetails] = useState([
        {fullName: "", phoneNo: "", gender: ""},
    ]);
  function handleChange(event, index) {
        console.log(event.target.value, index);
        let newArr = [...groupDetails]; // copying the old datas array
        let item = newArr[index];
        item = {...item, [event.target.name]: event.target.value};
        newArr[index] = item;

        setGroupDetails(newArr);
    }

    return (

            Number of Group: <TextField name="groupMembersCount" onChange={(event) => {
            setGroupMembersCount(event.target.value)
        }}/>
            {Array.apply(null, {length: groupMembersCount}).map(
                (e, i) => (

                        Member #{i + 1}

                            <TextField
                                id={`name${i + 1}`}
                                name="fullName"
                                variant="outlined"
                                margin="none"
                                label="Name"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <TextField
                                id={`phoneNo${i + 1}`}
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <Select
                                id={`gender${i + 1}`}
                                name="gender"
                                variant="outlined"
                                margin="none"
                                label="Gender"
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            >
                                <option value="MALE">Male</option>
                                <option value="FEMALE">Female</option>
                                <option value="OTHER">Other</option>
                            </Select>

                )
            )}
            <Button onClick={() => {
                setShow(true)
            }}>Show</Button>
            {
                show ?
                    groupDetails.map(member =>
                        <Card>
                        <CardContent>
                            <Typography color="textSecondary" gutterBottom>
                                {member.fullName}
                            </Typography>
                            <Typography variant="h5" component="h2">
                                {member.phoneNo}
                            </Typography>
                            <Typography color="textSecondary">
                                {member.gender}
                            </Typography>
                        </CardContent>
                    </Card>) : null
            }

    );
}

What if I filled the number (groupMembersCount) and then filled those form fields and after filling, I modified groupMembersCount (either increase or decrease), in case of increase I want the values that user filled should retain and if decreased, form fields values should clear out.
I tried passing values from groupDetails array to form in "value" prop but it shows an error because the index I an writing/passing the values initially doesn't exist at that index.

Body:
You need set value from groupDetails that was stored before using useState. Please check this example:

import TextField from "@material-ui/core/TextField";
import React, {useState} from "react";
import Select from "@material-ui/core/Select";
import Button from "@material-ui/core/Button";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import Typography from "@material-ui/core/Typography";

export default function DynamicGroupMember3() {
    const [groupMembersCount, setGroupMembersCount] = useState(0);
    const [show, setShow] = useState(false);
    const [errorText, setErrorText] = useState([]);
    const [showState, setShowState] = useState(false);
    const [groupDetails, setGroupDetails] = useState([
        {fullName: "", phoneNo: "", gender: ""},
    ]);
    const [state, setState] = React.useState({
        idProof: "",
        noOfPeople: "",
        bookingId: "",
        detailsOfPeople: [],
    });

    function handleChange(event, index) {
        event.preventDefault();
        console.log(errorText.length, 'length');
        if (event.target.name === "phoneNo") {
            // do validation here
            let valid = false;
            if (isNaN(event.target.value)) {
                let arr = [...errorText];
                arr[index] = 'Invalid ' + event.target.name;
                setErrorText(arr);
            } else {
                let arr = [...errorText];
                arr[index] = '';
                setErrorText(arr);
            }
        }

        let newArr = [...groupDetails]; // copying the old datas array
        let item = newArr[index];
        item = {...item, [event.target.name]: event.target.value};
        newArr[index] = item;
        setGroupDetails(newArr);
    }

    return (
        <div>
            Number of Group: <TextField name="groupMembersCount" onChange={(event) => {
            if (isNaN(event.target.value)) {
                alert('Please enter number');
                return;
            }
            if (event.target.value !== '') {
                let noOfMember = parseInt(event.target.value);
                let errors = new Array(noOfMember);
                setErrorText(errors);
                if (groupMembersCount > noOfMember) {
                    let newGroup = [];
                    groupDetails.map((group, index) => {
                        if (index < noOfMember) {
                            newGroup.push(group);
                        }
                    });
                    setGroupDetails(newGroup);
                }
                setGroupMembersCount(noOfMember);
            }
        }}/>
            {Array.apply(null, {length: groupMembersCount}).map(
                (e, i) => (
                    <div key={i}>
                        <strong>Member #{i + 1}</strong>
                        <div className="getIndex" name={i + 1}>
                            <TextField
                                id={`name${i + 1}`}
                                name="fullName"
                                variant="outlined"
                                margin="none"
                                label="Name"
                                value={groupDetails[i] ? groupDetails[i].fullName : ''}
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            />
                            <TextField
                                id={`phoneNo${i + 1}`}
                                name="phoneNo"
                                variant="outlined"
                                margin="none"
                                label="Mobile Number"
                                value={groupDetails[i] ? groupDetails[i].phoneNo : ''}
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                                error={errorText[i] !== '' && errorText[i] !== undefined}
                                helperText={errorText[i]}
                            />
                            <Select
                                id={`gender${i + 1}`}
                                name="gender"
                                variant="outlined"
                                margin="none"
                                label="Gender"
                                value={groupDetails[i] ? groupDetails[i].gender : ''}
                                onChange={(event) => {
                                    handleChange(event, i)
                                }}
                            >
                                <option value="MALE">Male</option>
                                <option value="FEMALE">Female</option>
                                <option value="OTHER">Other</option>
                            </Select>
                        </div>
                    </div>
                )
            )}
            <Button onClick={() => {
                setShow(true)
            }}>Show</Button>
            {
                show ?
                    groupDetails.map((member, index) =>
                        <Card key={index}>
                            <CardContent>
                                <Typography color="textSecondary" gutterBottom>
                                    {member.fullName}
                                </Typography>
                                <Typography variant="h5" component="h2">
                                    {member.phoneNo}
                                </Typography>
                                <Typography color="textSecondary">
                                    {member.gender}
                                </Typography>
                            </CardContent>
                        </Card>) : null
            }
            <Button onClick={() => {
                console.log(groupDetails, 'groupDetails');
                setState({
                    idProof: "XYZ123",
                    noOfPeople: groupDetails.length,
                    bookingId: "boking-4434",
                    detailsOfPeople: groupDetails
                });
                console.log(groupDetails, 'groupDetails');
                setShowState(true);

            }}>Show STATE</Button>
            {
                showState ?
                    <Card>
                        <CardContent>
                            <Typography color="textSecondary" gutterBottom>
                                Id Proof: {state.idProof}
                            </Typography>
                            <Typography variant="h5" component="h2">
                                No Of People: {state.noOfPeople}
                            </Typography>
                            <Typography color="textSecondary">
                                Booking Id: {state.bookingId}
                            </Typography>
                        </CardContent>
                    </Card> : null
            }
        </div>
    );
}


问:
React Global Memoization
I have the following React test app:

class MemoTestApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
     showOverlay: false,
    }
  }

  render() {
    return (

          <MemoComponent str="Hello World" />

          <input type="button" onClick={() => this.setState({showOverlay: true})} value="Show Overlay"/>

        {this.state.showOverlay && (

Overlay

            <MemoComponent str="Hello World" />

        )}

    )
  }
}

const Component = (props) => {
  console.info('render ' + props.str);
  return
{props.str}
;
}

const MemoComponent = React.memo(Component);

ReactDOM.render(<MemoTestApp />, document.querySelector("#app"))```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  position: relative;
  min-height: 200px;
}

.overlay {
  position: absolute;
  padding: 20px;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: white;
}</code>```

```

As you can see, there is a memoized functional component which is rendered twice with the same props. The first rendering takes place immediately, the second one after the user presses the button.

However, the component really is rendered twice, as you can see in the console. React.memo prevents the second rendering of the first instance of the component, but the second instance seems to "now know" that this component has already been rendered with the given props.

Is there a way to make Memoization "global", i.e. so that rendered outputs are shared between different instances of the component?

What is the reason that React.memo is not global by default?

答:
Short answer: Components are reusable, this is by design.

They may have their own state, for example a counter. Or they have side effects, e.g. own intervals, custom logic depending on the DOM nodes.

For that reason, they have to be separate "instances" depending where they live on the DOM (parent node, index or key), and are separately rendered. The result is then memoized per component "instance".

Title: React Global Memoization

Body:
I have the following React test app:

class MemoTestApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
     showOverlay: false,
    }
  }

  render() {
    return (

          <MemoComponent str="Hello World" />

          <input type="button" onClick={() => this.setState({showOverlay: true})} value="Show Overlay"/>

        {this.state.showOverlay && (

Overlay

            <MemoComponent str="Hello World" />

        )}

    )
  }
}

const Component = (props) => {
  console.info('render ' + props.str);
  return
{props.str}
;
}

const MemoComponent = React.memo(Component);

ReactDOM.render(<MemoTestApp />, document.querySelector("#app"))

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
  position: relative;
  min-height: 200px;
}

.overlay {
  position: absolute;
  padding: 20px;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: white;
}

As you can see, there is a memoized functional component which is rendered twice with the same props. The first rendering takes place immediately, the second one after the user presses the button.

However, the component really is rendered twice, as you can see in the console. React.memo prevents the second rendering of the first instance of the component, but the second instance seems to "now know" that this component has already been rendered with the given props.

Is there a way to make Memoization "global", i.e. so that rendered outputs are shared between different instances of the component?

What is the reason that React.memo is not global by default?


问:
Can somebody help me understand byte arrays in python for the following sample code that was uses byte arrays to generate a large integer?
I am having trouble understanding what the from_bytes() method in python is doing exactly for the following instance of the code. Especially how does creating a byte array that starts with 255 and is succeeded by 25 zeroes give rise to an integer value.

I am especially interested in understanding the internal workings of the following line
int.from_bytes(byte_seed, byteorder="big", signed=False)
in the code:

```<code>def test_base_hash_from_wisconsin(self):
    q: int = pow(2, 256) - 189
    q_static = 115792089237316195423570985008687907853269984665640564039457584007913129639747

    # Verify the correct value for q is used
    self.assertEqual(q, q_static)

    # Create a byte array with 0xff & 25 zeroes
    byte_seed = bytes([
        255,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0,
    ])

    # convert the byte array to an integer deterministically
    as_int = int.from_bytes(byte_seed, byteorder="big", signed=False)

    print(as_int)

    # take the integer mod q
    base_hash = as_int % q

    print(base_hash)

    self.assertEqual(base_hash, as_int)

    self.assertEqual(
        base_hash, 409769201286042520263200333546996463643161763414612173001850880
    )
</code>```

This is the original C code for doing the same thing:

```<code>void Crypto_hash_reduce(struct hash *out, raw_hash bytes)
{
    mpz_import(out->digest, HASH_DIGEST_SIZE_BYTES / 8, 1, 8, 0, 0, bytes);
    mod_q(out->digest, out->digest);
}
</code>```

答:
Integers are saved as a series of 0 and 1 in the memory, eg:

Unsigned int

```<code>0 -> 00000000 00000000
1 -> 00000000 00000001
2 -> 00000000 00000010
3 -> 00000000 00000011
...
65536 -> 11111111 11111111
</code>```

Signed int

```<code>-32768 -> 10000000 00000000
 ...
-2     -> 11111111 11111110
-1     -> 11111111 11111111
 0     -> 00000000 00000000
 1     -> 00000000 00000001
 2     -> 00000000 00000010
 3     -> 00000000 00000011
 ...
 32767 -> 01111111 11111111
</code>```

Now i've used the "big endian" type of decoding, where the most significant byte comes first.

There is also the "little endian":

Unsigned int (little endian)

```<code>0 -> 00000000 00000000
1 -> 00000001 00000000
2 -> 00000010 00000000
3 -> 00000011 00000000
...
65536 -> 11111111 11111111
</code>```

Note how the bytes just swapped, but the bit order inside the bytes is the same.

What int.from_bytes does is simply turning a series of 0 and 1 into an integer, using this exact protocol

If you want to understand more on this subject search for keywords like binary number, endianness, or consult links like

http://statmath.wu.ac.at/courses/data-analysis/itdtHTML/node55.html

https://medium.com/@luischaparroc/integer-numbers-storage-in-computer-memory-47af4b59009

Body:
I am having trouble understanding what the from_bytes() method in python is doing exactly for the following instance of the code. Especially how does creating a byte array that starts with 255 and is succeeded by 25 zeroes give rise to an integer value.

I am especially interested in understanding the internal workings of the following line
int.from_bytes(byte_seed, byteorder="big", signed=False)
in the code:

def test_base_hash_from_wisconsin(self):
    q: int = pow(2, 256) - 189
    q_static = 115792089237316195423570985008687907853269984665640564039457584007913129639747

    # Verify the correct value for q is used
    self.assertEqual(q, q_static)

    # Create a byte array with 0xff & 25 zeroes
    byte_seed = bytes([
        255,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        0,
    ])

    # convert the byte array to an integer deterministically
    as_int = int.from_bytes(byte_seed, byteorder="big", signed=False)

    print(as_int)

    # take the integer mod q
    base_hash = as_int % q

    print(base_hash)

    self.assertEqual(base_hash, as_int)

    self.assertEqual(
        base_hash, 409769201286042520263200333546996463643161763414612173001850880
    )

This is the original C code for doing the same thing:

void Crypto_hash_reduce(struct hash *out, raw_hash bytes)
{
    mpz_import(out->digest, HASH_DIGEST_SIZE_BYTES / 8, 1, 8, 0, 0, bytes);
    mod_q(out->digest, out->digest);
}

Body:
Integers are saved as a series of 0 and 1 in the memory, eg:

Unsigned int

0 -> 00000000 00000000
1 -> 00000000 00000001
2 -> 00000000 00000010
3 -> 00000000 00000011
...
65536 -> 11111111 11111111

Signed int

-32768 -> 10000000 00000000
 ...
-2     -> 11111111 11111110
-1     -> 11111111 11111111
 0     -> 00000000 00000000
 1     -> 00000000 00000001
 2     -> 00000000 00000010
 3     -> 00000000 00000011
 ...
 32767 -> 01111111 11111111

Now i've used the "big endian" type of decoding, where the most significant byte comes first.

There is also the "little endian":

Unsigned int (little endian)

0 -> 00000000 00000000
1 -> 00000001 00000000
2 -> 00000010 00000000
3 -> 00000011 00000000
...
65536 -> 11111111 11111111

Note how the bytes just swapped, but the bit order inside the bytes is the same.

What int.from_bytes does is simply turning a series of 0 and 1 into an integer, using this exact protocol

If you want to understand more on this subject search for keywords like binary number, endianness, or consult links like

http://statmath.wu.ac.at/courses/data-analysis/itdtHTML/node55.html

https://medium.com/@luischaparroc/integer-numbers-storage-in-computer-memory-47af4b59009


问:
Dynamic page update using ftl template and Spring Boot
Me question related to using Spring Boot with FTL (Freemarker) templates.
Is there any way to update my page dynamically?
For example:
I have one general list for two accounts. When the second user change that list, I want to see those changes on my page without page reloading. Is there any way to realize that?
I know that React has this possibility, but I have a lot of code with ftl templates.
Will be glad for any answer</p>

答:
without page reloading

That's going to be Ajax operation (if you're after the basic solution).

Implement jQuery on change function that watched menu select option change

In the on change write AJAX $.post to your service/controller, get the response value or JSON object and apply it to page using javascript ot jQuery commands.

Ajax and jQuery works nicely inside ftl templates.

Please provide more context and how your data is being served to page, either myself or another member could be able to provide a code sample.


问:
How can I extend Scala collections with an argmax method?
I would like to add to all collections where it makes sense, an argMax method.
How to do it? Use implicits?</p>

答:
Nice and easy ? :</p>

```<code>val l = List(1,0,10,2)
l.zipWithIndex.maxBy(x => x._1)._2
</code>```

ContentLicense: CC BY-SA 2.5

Body:
Nice and easy ? :

val l = List(1,0,10,2)
l.zipWithIndex.maxBy(x => x._1)._2


问:
SFML - Projectile slow down with different direction
I am creating a Tower Defense game, I created a program which create a projectile starting from a turret and sends it on the enemy as soon as he is in its range of shooting. The projectile moves in the direction of the enemy but on certain directions the projectile is more or less rapid.
Here is the code :

```<code>//initialPosition is where the projectile is created.
sf::Vector2f direction = enemyPosition - initialPosition;
projectile.move(direction.x * speed, direction.y * speed);
</code>```

What am i doing wrong?

答:
I found the solution, here is the code :</p>

```<code>direction = enemyPosition - initialPosition;
ndir = direction / sqrt(pow(direction.x, 2) + pow(direction.y, 2));
velocity = ndir * speed;
pform.move(velocity);
</code>```

Body:
I am creating a Tower Defense game, I created a program which create a projectile starting from a turret and sends it on the enemy as soon as he is in its range of shooting. The projectile moves in the direction of the enemy but on certain directions the projectile is more or less rapid.
Here is the code :

//initialPosition is where the projectile is created.
sf::Vector2f direction = enemyPosition - initialPosition;
projectile.move(direction.x * speed, direction.y * speed);

What am i doing wrong?

Body:
I found the solution, here is the code :

direction = enemyPosition - initialPosition;
ndir = direction / sqrt(pow(direction.x, 2) + pow(direction.y, 2));
velocity = ndir * speed;
pform.move(velocity);


问:
Keras multiply parallel layers' outputs with constrained weigths
I have 3 parallel MLPs and want to obtain the following in Keras:

```<code>Out = W1 * Out_MLP1 + W2 * Out_MLP2 + W3 * Out_MLP3
</code>```

where Out_MLPs are output layer of each MLP and have dimension of (10,) and W1, W2 and W3 are three trainable weights (floats) where they satisfy the following condition:

```<code>W1 + W2 + W3 = 1
</code>```

What is the best way to implement this with Keras functional API? What if we had N parallel layers?

答:
what you need is to apply a softmax on a set of learnable weights, in order to grant that they sum up to 1.

We initialize our learnable weights in a custom layer. this layer receives the output of our MLPs and combines them following our logic W1 * Out_MLP1 + W2 * Out_MLP2 + W3 * Out_MLP3. the output will be a tensor of shape (10,).

```<code>class W_ADD(Layer):

    def __init__(self, n_output):
        super(W_ADD, self).__init__()
        self.W = tf.Variable(initial_value=tf.random.uniform(shape=[1,1,n_output], minval=0, maxval=1),
            trainable=True) # (1,1,n_inputs)

    def call(self, inputs):

        # inputs is a list of tensor of shape [(n_batch, n_feat), ..., (n_batch, n_feat)]
        # expand last dim of each input passed [(n_batch, n_feat, 1), ..., (n_batch, n_feat, 1)]
        inputs = [tf.expand_dims(i, -1) for i in inputs]
        inputs = Concatenate(axis=-1)(inputs) # (n_batch, n_feat, n_inputs)
        weights = tf.nn.softmax(self.W, axis=-1) # (1,1,n_inputs)
        # weights sum up to one on last dim

        return tf.reduce_sum(weights*inputs, axis=-1) # (n_batch, n_feat)
</code>```

in this dummy example, I create a network that has 3 parallel MLPs

```<code>inp1 = Input((100))
inp2 = Input((100))
inp3 = Input((100))
x1 = Dense(32, activation='relu')(inp1)
x2 = Dense(32, activation='relu')(inp2)
x3 = Dense(32, activation='relu')(inp3)
x1 = Dense(10, activation='linear')(x1)
x2 = Dense(10, activation='linear')(x2)
x3 = Dense(10, activation='linear')(x3)
mlp_outputs = [x1,x2,x3]
out = W_ADD(n_output=len(mlp_outputs))(mlp_outputs)

m = Model([inp1,inp2,inp3], out)
m.compile('adam','mse')

X1 = np.random.uniform(0,1, (1000,100))
X2 = np.random.uniform(0,1, (1000,100))
X3 = np.random.uniform(0,1, (1000,100))
y = np.random.uniform(0,1, (1000,10))

m.fit([X1,X2,X3], y, epochs=10)
</code>```

as you can see this is easily generalizable in case of N parallel layers

Body:
I have 3 parallel MLPs and want to obtain the following in Keras:

Out = W1 * Out_MLP1 + W2 * Out_MLP2 + W3 * Out_MLP3

where Out_MLPs are output layer of each MLP and have dimension of (10,) and W1, W2 and W3 are three trainable weights (floats) where they satisfy the following condition:

W1 + W2 + W3 = 1

What is the best way to implement this with Keras functional API? What if we had N parallel layers?

Body:
what you need is to apply a softmax on a set of learnable weights, in order to grant that they sum up to 1.

We initialize our learnable weights in a custom layer. this layer receives the output of our MLPs and combines them following our logic W1 * Out_MLP1 + W2 * Out_MLP2 + W3 * Out_MLP3. the output will be a tensor of shape (10,).

class W_ADD(Layer):

    def __init__(self, n_output):
        super(W_ADD, self).__init__()
        self.W = tf.Variable(initial_value=tf.random.uniform(shape=[1,1,n_output], minval=0, maxval=1),
            trainable=True) # (1,1,n_inputs)

    def call(self, inputs):

        # inputs is a list of tensor of shape [(n_batch, n_feat), ..., (n_batch, n_feat)]
        # expand last dim of each input passed [(n_batch, n_feat, 1), ..., (n_batch, n_feat, 1)]
        inputs = [tf.expand_dims(i, -1) for i in inputs]
        inputs = Concatenate(axis=-1)(inputs) # (n_batch, n_feat, n_inputs)
        weights = tf.nn.softmax(self.W, axis=-1) # (1,1,n_inputs)
        # weights sum up to one on last dim

        return tf.reduce_sum(weights*inputs, axis=-1) # (n_batch, n_feat)

in this dummy example, I create a network that has 3 parallel MLPs

inp1 = Input((100))
inp2 = Input((100))
inp3 = Input((100))
x1 = Dense(32, activation='relu')(inp1)
x2 = Dense(32, activation='relu')(inp2)
x3 = Dense(32, activation='relu')(inp3)
x1 = Dense(10, activation='linear')(x1)
x2 = Dense(10, activation='linear')(x2)
x3 = Dense(10, activation='linear')(x3)
mlp_outputs = [x1,x2,x3]
out = W_ADD(n_output=len(mlp_outputs))(mlp_outputs)

m = Model([inp1,inp2,inp3], out)
m.compile('adam','mse')

X1 = np.random.uniform(0,1, (1000,100))
X2 = np.random.uniform(0,1, (1000,100))
X3 = np.random.uniform(0,1, (1000,100))
y = np.random.uniform(0,1, (1000,10))

m.fit([X1,X2,X3], y, epochs=10)

as you can see this is easily generalizable in case of N parallel layers


问:
Access to user's mailbox using EWS, OAuth2 and user's credentials
In our application we use EWS and basic authentication.
An user can get access to own mailbox only or to all mailboxes in his organization if he has admin credentials. Now we are trying to replace basic authentication with OAuth2 authentication.
We registered the application on Azure portal, added the permission "EWS.AccessAsUser.All".

For an admin account everything works well. Our application can get access to any mailbox in admin's organization.

The problem is in that we cannot get an authorization code for a standard user account.
"TestApp needs permission to access resources in your organization that only an admin can grant" is shown.

So the question is: is there a way to get access to user's mailbox using EWS, OAuth2 and user's credentials?

答:
With oAuth you need to grant consent for your application in a Tenant eg
 https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/grant-admin-consent once you have granted tenant wide consent any user should be able to use the application unless you apply restrictions. If your application is being used by other companies then you need to have a Multi Tenant application registration and the client will need to consent to its use in their tenant before they can use it. </p>


问:
Find number of close loops in Binary Edge Image
I have a binary image with the number of close loops and free curves like shown in image..

My approach so far- (python code):

Skeletonize the image to get edge of 1 pixel

Use label/bwlabel to get individual curve/edge

Applied DFS to get the edge which is not close

Apply DFS to get close edge..but not working correctly..

Expected output -

Number of close loops =6, the sum of the pixels along the loop or all (x,y) points along the edge of the close curve as highlighted in RED

Expected Output-

答:
You already have a binary image: simply use findContours() to get the inner contours.

Bare in mind you want use cv2.RETR_CCOMP as the Countour Retrieval Mode to easily access the holes:

retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.

It should be a matter of simply getting the length of countours on the second level (holes)


问:
Mark row in dataframe that contains a any column = NAN
I have a dataframe that contains 3 columns

Some rows contain a column that has a NaN Value.

I have used checkfornan=df.isnull() to generate a dataframe (checkfornan) that I can used to locate individual values a NaN.

But what I would like to do is add another column in my original dataframe (df) say 'isNaN' and assign a value of True into that column if any other value in the same row is Nan, or False if no values in same column are NaN.

Being new to Dataframe, I am not sure how I use the output from df.isnull() dataframe to combine it with my original dataframe to achieve this?

Any ideas?

thanks

答:
Check if any column is a NaN, create a new column:

```<code>df['isNaN'] = df.isnull().any(axis=1)
</code>```

Body:
Check if any column is a NaN, create a new column:

df['isNaN'] = df.isnull().any(axis=1)


问:
How can I compare two time strings in the format HH:MM:SS?
I have two time strings in HH:MM:SS format. For example, str1 contains 10:20:45,  str2 contains 5:10:10.

How can I compare the above values?

答: You could compare the two values right after splitting them with ':'.</p>


问:
Java: two threads executing until the boolean flag is false: the second thread's first run stops the first thread
I have this threaded program that has three threads: main, lessonThread, questionThread.

It works like this:

Lesson continues continues to gets printed while the finished
the variable is true;

every 5 seconds the questionThread asks Finish
the lesson? and if the answer is y, it sets finished to false

The problem is that the Lesson continues never gets printed after the question gets asked the first time:

Also, as seen on the picture, sometimes lessonThread sneaks in with its Lesson continues before the user can enter the answer to the questionThread's question.

```<code>public class Lesson {
    private boolean finished;
    private boolean waitingForAnswer;
    private Scanner scanner = new Scanner(System.in);

    private Thread lessonThread;
    private Thread questionThread;

    public static void main(String[] args) {
        Lesson lesson = new Lesson();
        lesson.lessonThread = lesson.new LessonThread();
        lesson.questionThread = lesson.new QuestionThread();

        lesson.lessonThread.start();
        lesson.questionThread.start();
    }

    class LessonThread extends Thread  {
        @Override
        public void run()  {
            while (!finished && !waitingForAnswer)  {
                System.out.println("Lesson continues");
            }
        }
    }

    class QuestionThread extends Thread {
        private Instant sleepStart = Instant.now();
        private boolean isAsleep = true;
        @Override
        public void run() {
            while (!finished) {
                if (isAsleep && Instant.now().getEpochSecond() - sleepStart.getEpochSecond() >= 5) {
                    System.out.print("Finish a lesson? y/n");
                    waitingForAnswer = true;
                    String reply = scanner.nextLine().substring(0, 1);
                    switch (reply.toLowerCase()) {
                        case "y":
                            finished = true;
                    }
                    waitingForAnswer = false;

                    isAsleep = true;
                    sleepStart = Instant.now();
                }
            }
        }
    }
}
</code>```

I think the waitingForAnswer = true might be at fault here, but then, the lessonThread has 5 seconds until the questionThread asks the question again, during which the waitingForAnswer is false.

Any help is greatly appreciated.

EDIT: I found a buy in the loop in the lessonThread and changed it to:

```<code>    @Override
        public void run()  {
            while (!finished)  {
                if (!waitingForAnswer)  {
                    System.out.println("Lesson continues");
                }
            }
        }
</code>```

However, I get the same result.

EDIT: I can get it working when inside a debugger:

答:
I managed to make it work with making waitingForAnswer volatile:

```<code>    private volatile boolean waitingForAnswer;
</code>```

Body:
I have this threaded program that has three threads: main, lessonThread, questionThread.

It works like this:

Lesson continues continues to gets printed while the finished
the variable is true;

every 5 seconds the questionThread asks Finish
the lesson? and if the answer is y, it sets finished to false

The problem is that the Lesson continues never gets printed after the question gets asked the first time:

Also, as seen on the picture, sometimes lessonThread sneaks in with its Lesson continues before the user can enter the answer to the questionThread's question.

public class Lesson {
    private boolean finished;
    private boolean waitingForAnswer;
    private Scanner scanner = new Scanner(System.in);

    private Thread lessonThread;
    private Thread questionThread;

    public static void main(String[] args) {
        Lesson lesson = new Lesson();
        lesson.lessonThread = lesson.new LessonThread();
        lesson.questionThread = lesson.new QuestionThread();

        lesson.lessonThread.start();
        lesson.questionThread.start();
    }

    class LessonThread extends Thread  {
        @Override
        public void run()  {
            while (!finished && !waitingForAnswer)  {
                System.out.println("Lesson continues");
            }
        }
    }

    class QuestionThread extends Thread {
        private Instant sleepStart = Instant.now();
        private boolean isAsleep = true;
        @Override
        public void run() {
            while (!finished) {
                if (isAsleep && Instant.now().getEpochSecond() - sleepStart.getEpochSecond() >= 5) {
                    System.out.print("Finish a lesson? y/n");
                    waitingForAnswer = true;
                    String reply = scanner.nextLine().substring(0, 1);
                    switch (reply.toLowerCase()) {
                        case "y":
                            finished = true;
                    }
                    waitingForAnswer = false;

                    isAsleep = true;
                    sleepStart = Instant.now();
                }
            }
        }
    }
}

I think the waitingForAnswer = true might be at fault here, but then, the lessonThread has 5 seconds until the questionThread asks the question again, during which the waitingForAnswer is false.

Any help is greatly appreciated.

EDIT: I found a buy in the loop in the lessonThread and changed it to:

    @Override
        public void run()  {
            while (!finished)  {
                if (!waitingForAnswer)  {
                    System.out.println("Lesson continues");
                }
            }
        }

However, I get the same result.

EDIT: I can get it working when inside a debugger:

Body:
I managed to make it work with making waitingForAnswer volatile:

    private volatile boolean waitingForAnswer;


问:
MySQL not creating table, keeps reporting syntax error which doesn't exist
I am trying to create a table in a MySQL database. I am using the command line of my server. I input:

test1;
CREATE TABLE people (ID int, name varchar(40));
```

<p>...and it says:</p>

```ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TABLE people (ID int, name varchar(40)); at line 1
```

I am very confused. I have even tried copy-pasting working examples of code, and I get the same result every time. Thank you for your help.

答:
first of all create database with the following syntax CREATE DATABASE DATABASE_NAME select the database like
USE DATABASE_NAME
then create table and the keyword in uppercase CREATE TABLE people (Id INT, name VARCHAR(40)); or CREATE TABLE IF NOT EXISTS people (Id INT, name VARCHAR(40));

Body:
I am trying to create a table in a MySQL database. I am using the command line of my server. I input:

test1;
CREATE TABLE people (ID int, name varchar(40));

...and it says:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TABLE people (ID int, name varchar(40)); at line 1

I am very confused. I have even tried copy-pasting working examples of code, and I get the same result every time. Thank you for your help.


问:
Passing a listed range of an attribute to its own object (Python)
I'm trying to create a class of objects which print "BOO!" a certain number of times, based on the current (particular) object's scariness level. I've created the attribute scariness, but I want to create a function which takes a range from 0 to that scariness level, then takes that range as a list, then prints "BOO!" for every element in that list. I've tried it two ways, here is my code:

Version 1:

```<code>class Ghost:
    def __init__(self, name, scariness, scarylist):
        self.name = name
        self.scariness = scariness
        self.scarylist = list(range[scariness])
    def scare_human(self):
        for i in scarylist:
            print('BOO!')

steve = Ghost("Steve", 1000, scarylist)
</code>```

When I execute the cell beginning with scarylist = list[range(1000)] in my IDE (Jupyter Notebook if it matters) I get the error, "'Type' object is not subscriptable." I'm guessing there are a couple things wrong with this version.

Version 2:

```<code>class Ghost:
    scarylist = list(range[scariness])
    def scare_human(self):
        for i in scarylist:
            print('BOO!')

steve = Ghost()
steve.name = "Steve"
steve.scariness = 1000
steve.hungriness = 10
</code>```

The trouble with this version is that I have to define the attributes of the class before I want to call them as variables of a function of the class. I can't do this if I use this kind of definition of the class.

答:
I want to create a function which takes a range from 0 to that scariness level, then takes that range as a list, then prints "BOO!" for every element in that list.

It's possible I'm missing something, but I'm not sure why you need to create a range out of scariness: int in order to print BOO! scariness number of times.

Here's my version of Ghost that does what I think you were aiming for:

>>> class Ghost:
    def __init__(self, name, scariness):
        self.name = name
        self.scariness = scariness
    def scare_human(self):
        for _ in range(self.scariness):
            print('BOO!')

>>> steve = Ghost("Steve", 10)
>>> steve.scare_human()
BOO!
BOO!
BOO!
BOO!
BOO!
BOO!
BOO!
BOO!
BOO!
BOO!
```

Body:
I'm trying to create a class of objects which print "BOO!" a certain number of times, based on the current (particular) object's scariness level. I've created the attribute scariness, but I want to create a function which takes a range from 0 to that scariness level, then takes that range as a list, then prints "BOO!" for every element in that list. I've tried it two ways, here is my code:

Version 1:

class Ghost:
    def __init__(self, name, scariness, scarylist):
        self.name = name
        self.scariness = scariness
        self.scarylist = list(range[scariness])
    def scare_human(self):
        for i in scarylist:
            print('BOO!')

steve = Ghost("Steve", 1000, scarylist)

When I execute the cell beginning with scarylist = list[range(1000)] in my IDE (Jupyter Notebook if it matters) I get the error, "'Type' object is not subscriptable." I'm guessing there are a couple things wrong with this version.

Version 2:

class Ghost:
    scarylist = list(range[scariness])
    def scare_human(self):
        for i in scarylist:
            print('BOO!')

steve = Ghost()
steve.name = "Steve"
steve.scariness = 1000
steve.hungriness = 10

The trouble with this version is that I have to define the attributes of the class before I want to call them as variables of a function of the class. I can't do this if I use this kind of definition of the class.


问:
How to make a geocoding function that runs asynchronously finish before subsequent code?
I have a forward geocoding function that is called inside of a function:

```<code>class AnnotationsVM: ObservableObject {

    @ObservedObject var VModel: ViewModel

    func addNextAnnotation(address: String) {
        self.VModel.fetchCoords(address: address)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            //Without the asyncAfter, this code runs before the fetchCoords() function is run.
        }
    }
}
</code>```

And the definition of the fetchCoords function is the following:

```<code>class ViewModel: ObservableObject {

    @Published lat: Double?
    @Published lon: Double?

    func fetchCoords(address: String){
        var latitude: Double? = 0.0
        var longitude: Double? = 0.0
        self.getLocation(from: address) { coordinates in
            self.location = coordinates // Assign to a local variable for further processing
            self.lon = coordinates?.longitude
            self.lat = coordinates?.latitude
        }
    }
}
</code>```

My question is, is there a more efficient way to do the DispatchQueue rather than just tacking on an arbitrary time (I used 0.1 seconds but would prefer for that code to run as soon as fetchCoords has run).

答:
You are correct that you just waiting for some arbitrary time to hope that the data is available is a very hacky and brittle approach.

There are numerous patterns to handle async behavior, but one thing you could do here is to pass a completion handler, that would be invoked when the fetchCoords completes.

So, let's say that this completion handler accepts the coordinates (for simplicity, I'll use 2 Doubles):

```<code>func fetchCoords(address: String, completion: @escaping (Double, Double) -> Void){
   self.getLocation(from: address) { coordinates in

      self.location = coordinates

      if let lat = coordinates?latitude, let lon = coordinates?longitude {
          completion(lat, lon)
      }
}
</code>```

```<code>func addNextAnnotation(address: String) {
   self.VModel.fetchCoords(address: address) { lat, lon in
      // do something with lat and long
   }
}
</code>```

Of course, this is just a conceptual approach (for example, it doesn't handle errors), but it should get you on the right track.

Body:
I have a forward geocoding function that is called inside of a function:

class AnnotationsVM: ObservableObject {

    @ObservedObject var VModel: ViewModel

    func addNextAnnotation(address: String) {
        self.VModel.fetchCoords(address: address)
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            //Without the asyncAfter, this code runs before the fetchCoords() function is run.
        }
    }
}

And the definition of the fetchCoords function is the following:

class ViewModel: ObservableObject {

    @Published lat: Double?
    @Published lon: Double?

    func fetchCoords(address: String){
        var latitude: Double? = 0.0
        var longitude: Double? = 0.0
        self.getLocation(from: address) { coordinates in
            self.location = coordinates // Assign to a local variable for further processing
            self.lon = coordinates?.longitude
            self.lat = coordinates?.latitude
        }
    }
}

My question is, is there a more efficient way to do the DispatchQueue rather than just tacking on an arbitrary time (I used 0.1 seconds but would prefer for that code to run as soon as fetchCoords has run).

Body:
You are correct that you just waiting for some arbitrary time to hope that the data is available is a very hacky and brittle approach.

There are numerous patterns to handle async behavior, but one thing you could do here is to pass a completion handler, that would be invoked when the fetchCoords completes.

So, let's say that this completion handler accepts the coordinates (for simplicity, I'll use 2 Doubles):

func fetchCoords(address: String, completion: @escaping (Double, Double) -> Void){
   self.getLocation(from: address) { coordinates in

      self.location = coordinates

      if let lat = coordinates?latitude, let lon = coordinates?longitude {
          completion(lat, lon)
      }
}

func addNextAnnotation(address: String) {
   self.VModel.fetchCoords(address: address) { lat, lon in
      // do something with lat and long
   }
}

Of course, this is just a conceptual approach (for example, it doesn't handle errors), but it should get you on the right track.