问:
Timed input in python 3 for Mac and Windows
I need a timed input for python 3 on both Mac and Windows which, if the user runs out of time, automatically chooses one of the options. Every other answer for a question I've seen only terminates after user presses 'Enter'. I need it to terminate regardless of any 'Enter' pressed or not.

For example, in my chess program, if no input is given after 5 seconds, I need it to automatically choose "Q". Also if the input is not in ["Q", "R", "B", "N"] then I also need it to choose "Q".

The following code doesn't work. It'll ask for the input then wait forever; the timer doesn't work at all.

```<code>def countdown():
    global timer
    timer = 5
    for x in range(timer):
        timer -= 1
        time.sleep(1)

countdownThread = threading.Thread(target=countdown)
countdownThread.start()

while timer > 0:
    promotedPiece = input("Promote to Q, R, B or N? >  ").upper()
    if timer == 0:
        break

if timer == 0:
    if promotedPiece not in ["Q", "R", "B", "N"]:  # If not valid input, choose Queen
        promotedPiece = "Q"
        print("Queen auto selected")
</code>```

答:
I've spent a few hours, and this is as far as I got:

```<code>import time
from multiprocessing import Process

global timer
timer = 5

def get_answer():
    answer = input ("ANSWER THE QUESTION!!!")

def runtime():
    global timer
    while True:
        time.sleep(1)
        timer = timer-1
        print (timer)
        if timer == 0:
            thread1.terminate()
            thread1.join()
            print ("hi")
            break

# create two new threads
thread1 = Process(target=get_answer, args=())
thread2 = Process(target=runtime, args=())

# start the threads
thread1.start()
thread2.start()

# wait for the threads to complete
thread1.join()
thread2.join()
</code>```

All you need to do is work out the error I'm getting with the Process module, and you'll be good.

Body:
I need a timed input for python 3 on both Mac and Windows which, if the user runs out of time, automatically chooses one of the options. Every other answer for a question I've seen only terminates after user presses 'Enter'. I need it to terminate regardless of any 'Enter' pressed or not.

For example, in my chess program, if no input is given after 5 seconds, I need it to automatically choose "Q". Also if the input is not in ["Q", "R", "B", "N"] then I also need it to choose "Q".

The following code doesn't work. It'll ask for the input then wait forever; the timer doesn't work at all.

def countdown():
    global timer
    timer = 5
    for x in range(timer):
        timer -= 1
        time.sleep(1)

countdownThread = threading.Thread(target=countdown)
countdownThread.start()

while timer > 0:
    promotedPiece = input("Promote to Q, R, B or N? >  ").upper()
    if timer == 0:
        break

if timer == 0:
    if promotedPiece not in ["Q", "R", "B", "N"]:  # If not valid input, choose Queen
        promotedPiece = "Q"
        print("Queen auto selected")

Body:
I've spent a few hours, and this is as far as I got:

import time
from multiprocessing import Process

global timer
timer = 5

def get_answer():
    answer = input ("ANSWER THE QUESTION!!!")

def runtime():
    global timer
    while True:
        time.sleep(1)
        timer = timer-1
        print (timer)
        if timer == 0:
            thread1.terminate()
            thread1.join()
            print ("hi")
            break

# create two new threads
thread1 = Process(target=get_answer, args=())
thread2 = Process(target=runtime, args=())

# start the threads
thread1.start()
thread2.start()

# wait for the threads to complete
thread1.join()
thread2.join()

All you need to do is work out the error I'm getting with the Process module, and you'll be good.


来源: stackexchange

问:
prevent page from refreshing after clicking a button
After a button is clicked, the page refreshes, which interferes with further functions of the page.
I tried changing the type from "submit" to "button", but then the button doesn't work at all. I also tried to return false the functions.

My simple code goes like this

```<code><html>
<body>
<form method="Get" action="">
<input type="submit" name="buttonV" onclick="function1()"> <br>
<input type="submit" name="buttonS" onclick="funciton2()">
</form>
</body>
</html>

<?php

 if ($_GET) {
        if (isset($_GET['buttonV'])) {
            function1();
        } elseif (isset($_GET['buttonS'])) {
            function2();
        }
    }

    function function1()
    {
      // do stuff
    }

    function function2()
    {
       // do stuff
    }

?>
</code>```

What should I do in order to prevent the page to refresh?

答:
I saw you are using php. I don't you use javascript.
You can use 'event.preventDefault()'.</p>

ContentLicense: CC BY-SA 4.0

Body:
After a button is clicked, the page refreshes, which interferes with further functions of the page.
I tried changing the type from "submit" to "button", but then the button doesn't work at all. I also tried to return false the functions.

My simple code goes like this

<form method="Get" action="">
<input type="submit" name="buttonV" onclick="function1()">

<input type="submit" name="buttonS" onclick="funciton2()">
</form>

<?php

 if ($_GET) {
        if (isset($_GET['buttonV'])) {
            function1();
        } elseif (isset($_GET['buttonS'])) {
            function2();
        }
    }

    function function1()
    {
      // do stuff
    }

    function function2()
    {
       // do stuff
    }

?>

What should I do in order to prevent the page to refresh?


问:
DataTable JS Unable to Filter on Column With Decimals
I want to enable filtering on a DataTable column that has numbers with decimals. I am able to have the code successfully run on a table without decimals, but it cannot sort with decimal numbers. Any way to modify the below to accommodate decimals?

```<code>/* Custom filtering function which will search data in column four between two values */
        $.fn.dataTable.ext.search.push(
            function( settings, data, dataIndex ) {
                var min = parseInt( $('#min').val(), 10 );
                var max = parseInt( $('#max').val(), 10 );
                var age = parseFloat( data[1] ) || 0; // use data for the age column

                if ( ( isNaN( min ) && isNaN( max ) ) ||
                     ( isNaN( min ) && age <= max ) ||
                     ( min <= age   && isNaN( max ) ) ||
                     ( min <= age   && age <= max ) )
                {
                    return true;
                }
                return false;
            }
        );

        $(document).ready(function() {
            var table = $('#example').DataTable();

            // Event listener to the two range filtering inputs to redraw on input
            $('#min, #max').keyup( function() {
                table.draw();
            });
        });
</code>```

I am wondering if changing the parseInt from the min and max variables to parseFloat will work, but then I am not sure if I need to modify isNaN?

答:
For that column you can use Datatables filter attribute

"data-filter"

```<code><td data-filter="62,5">62.5</td>
</code>```

and then in search column replace deciman "." with ","

```<code>if(colIdx == 5){
       var searchval = this.value.replace(".",",");
}else{
      var searchval = this.value;
}
</code>```

colIdx is column id because i used custom search fileds

you can directly use var searchval = this.value.replace(".",",");

Body:
I want to enable filtering on a DataTable column that has numbers with decimals. I am able to have the code successfully run on a table without decimals, but it cannot sort with decimal numbers. Any way to modify the below to accommodate decimals?

/* Custom filtering function which will search data in column four between two values */
        $.fn.dataTable.ext.search.push(
            function( settings, data, dataIndex ) {
                var min = parseInt( $('#min').val(), 10 );
                var max = parseInt( $('#max').val(), 10 );
                var age = parseFloat( data[1] ) || 0; // use data for the age column

                if ( ( isNaN( min ) && isNaN( max ) ) ||
                     ( isNaN( min ) && age <= max ) ||
                     ( min <= age   && isNaN( max ) ) ||
                     ( min <= age   && age <= max ) )
                {
                    return true;
                }
                return false;
            }
        );

        $(document).ready(function() {
            var table = $('#example').DataTable();

            // Event listener to the two range filtering inputs to redraw on input
            $('#min, #max').keyup( function() {
                table.draw();
            });
        });

I am wondering if changing the parseInt from the min and max variables to parseFloat will work, but then I am not sure if I need to modify isNaN?

Body:
For that column you can use Datatables filter attribute

"data-filter"

<td data-filter="62,5">62.5</td>

and then in search column replace deciman "." with ","

if(colIdx == 5){
       var searchval = this.value.replace(".",",");
}else{
      var searchval = this.value;
}

colIdx is column id because i used custom search fileds

you can directly use var searchval = this.value.replace(".",",");


问:
Google Apps Script Permissions for a function with inputs
I know this topic has bee covered before sort of, but none of it really makes sense to me. Basically I wrote a function that will generate a PDF from some API data using user inputs. It looks vaguely like this and works when I run it in the script editor.

```<code>function myfunction(InputA,InputB,InputC,InputD,InputE) {

......

var sourceSpreadsheet = SpreadsheetApp.getActive();
    var parents = DriveApp.getFileById(sourceSpreadsheet.getId()).getParents();
    if (parents.hasNext()) {
      var folder = parents.next();
    }

    var response = UrlFetchApp.fetch(url, options)
    var blob = response.getAs('application/pdf').setName(InputA + InputB + InputC)
    var newFile = folder.createFile(blob);

    return newFile
}

</code>```

The problem is Google permissions. The classic: "You don't have permission to access the drive".

I have tried publishing the script as a private sheets addon and enabled it on my spreadsheet. But that didn't really do anything. And I don't really know why because I authorized the app for all the required scopes when I approved the add on. I can see it in the extensions menu but I am still getting errors when I try to call the function.

The button method of enabling permissions doesn't work for me because I need to run the code several times based on parameters defined in the Sheet. I tried simple triggers since I want the code to run weekly anyways, but found the same problem.

Can someone give me the step by step of how I'm supposed to do this.

Please don't send links to the google documentation because I have read the related pages and still don't know what I'm doing wrong.

答:
I recommend you use an installable onEdit trigger. I have this approach and see if it works for you.

Sample Data:

Assuming url is from Input D column.

Create a column of checkboxes that will trigger the installed trigger. In my case, ticking it will create the file and unticking it will remove the file created.

Ticking rows where an input (at least 1) is missing, will cancel the creation of the file and then untick the checkbox ticked.

Drive folder:

Script:

```<code>function createFileTrigger(e) {
  var spreadsheet = e.source;
  var sheet = spreadsheet.getActiveSheet();
  var range = e.range;
  var value = e.value;
  var row = range.getRow();
  var col = range.getColumn();

  // proceed if edited cell is Sheet1!H2:H
  if(sheet.getSheetName() == 'Sheet1' && col == 8 && row > 1) {
    // if checkbox is ticked
    if(value == 'TRUE') {
      // inputs = [Input A, Input B, Input C, Input D, Input E]
      var inputs = range.offset(0, -6, 1, 5).getValues().flat();

      var parents = DriveApp.getFileById(spreadsheet.getId()).getParents();
      var folder = parents.next();

      // set some conditions here to pre-check the inputs
      // e.g. if at least 1 input is blank, cancel file creation (return)
      if(inputs.filter(String).length < 5) {
        // untick the checkbox ticked
        range.setValue('FALSE');
        // skip creation of file
        return;
      }

      // assuming url is from Input D (removed options as not needed for presentation)
      var response = UrlFetchApp.fetch(inputs[3]);
      var newFileName = `${inputs[0]} ${inputs[1]} ${inputs[2]}`;

      // if file is existing (which should not happen but just in case)
      if(folder.getFilesByName(newFileName).hasNext()) {
        // do something else that is needed to be done to avoid duplication of file
        // e.g. overwrite or skip creating file
        console.log(newFileName + ' is already existing in the parent folder');
      }
      // if not existing
      else {
        // create the file
        var blob = response.getAs('application/pdf').setName(newFileName)
        // for presenation purposes, will write the id of the created file
        range.offset(0, -1).setValue(folder.createFile(blob).getId());
      }
    }
    // if checkbox is unticked
    else {
      // do something else that is needed to be done
      // e.g. delete the file using the id returned (using Drive Advanced Services)
      var fileIdRange = range.offset(0, -1);
      Drive.Files.remove(fileIdRange.getValue());
      // remove file id content on the cell
      fileIdRange.clearContent();
    }
  }
}
</code>```

Ticking checkbox (folder):

Ticking checkbox (sheet):

Note:

This can still be improved, but should already be enough for your case.

Body:
I know this topic has bee covered before sort of, but none of it really makes sense to me. Basically I wrote a function that will generate a PDF from some API data using user inputs. It looks vaguely like this and works when I run it in the script editor.

function myfunction(InputA,InputB,InputC,InputD,InputE) {

......

var sourceSpreadsheet = SpreadsheetApp.getActive();
    var parents = DriveApp.getFileById(sourceSpreadsheet.getId()).getParents();
    if (parents.hasNext()) {
      var folder = parents.next();
    }

    var response = UrlFetchApp.fetch(url, options)
    var blob = response.getAs('application/pdf').setName(InputA + InputB + InputC)
    var newFile = folder.createFile(blob);

    return newFile
}

The problem is Google permissions. The classic: "You don't have permission to access the drive".

I have tried publishing the script as a private sheets addon and enabled it on my spreadsheet. But that didn't really do anything. And I don't really know why because I authorized the app for all the required scopes when I approved the add on. I can see it in the extensions menu but I am still getting errors when I try to call the function.

The button method of enabling permissions doesn't work for me because I need to run the code several times based on parameters defined in the Sheet. I tried simple triggers since I want the code to run weekly anyways, but found the same problem.

Can someone give me the step by step of how I'm supposed to do this.

Please don't send links to the google documentation because I have read the related pages and still don't know what I'm doing wrong.

Body:
I recommend you use an installable onEdit trigger. I have this approach and see if it works for you.

Sample Data:

Assuming url is from Input D column.

Create a column of checkboxes that will trigger the installed trigger. In my case, ticking it will create the file and unticking it will remove the file created.

Ticking rows where an input (at least 1) is missing, will cancel the creation of the file and then untick the checkbox ticked.

Drive folder:

Script:

function createFileTrigger(e) {
  var spreadsheet = e.source;
  var sheet = spreadsheet.getActiveSheet();
  var range = e.range;
  var value = e.value;
  var row = range.getRow();
  var col = range.getColumn();

  // proceed if edited cell is Sheet1!H2:H
  if(sheet.getSheetName() == 'Sheet1' && col == 8 && row > 1) {
    // if checkbox is ticked
    if(value == 'TRUE') {
      // inputs = [Input A, Input B, Input C, Input D, Input E]
      var inputs = range.offset(0, -6, 1, 5).getValues().flat();

      var parents = DriveApp.getFileById(spreadsheet.getId()).getParents();
      var folder = parents.next();

      // set some conditions here to pre-check the inputs
      // e.g. if at least 1 input is blank, cancel file creation (return)
      if(inputs.filter(String).length < 5) {
        // untick the checkbox ticked
        range.setValue('FALSE');
        // skip creation of file
        return;
      }

      // assuming url is from Input D (removed options as not needed for presentation)
      var response = UrlFetchApp.fetch(inputs[3]);
      var newFileName = `${inputs[0]} ${inputs[1]} ${inputs[2]}`;

      // if file is existing (which should not happen but just in case)
      if(folder.getFilesByName(newFileName).hasNext()) {
        // do something else that is needed to be done to avoid duplication of file
        // e.g. overwrite or skip creating file
        console.log(newFileName + ' is already existing in the parent folder');
      }
      // if not existing
      else {
        // create the file
        var blob = response.getAs('application/pdf').setName(newFileName)
        // for presenation purposes, will write the id of the created file
        range.offset(0, -1).setValue(folder.createFile(blob).getId());
      }
    }
    // if checkbox is unticked
    else {
      // do something else that is needed to be done
      // e.g. delete the file using the id returned (using Drive Advanced Services)
      var fileIdRange = range.offset(0, -1);
      Drive.Files.remove(fileIdRange.getValue());
      // remove file id content on the cell
      fileIdRange.clearContent();
    }
  }
}

Ticking checkbox (folder):

Ticking checkbox (sheet):

Note:

This can still be improved, but should already be enough for your case.


问:
asmx asp.net webservice return multiple classes wsdl
We are developing a webservice for a client.  We are not supose to throw SoapExceptions, so instead, we catch every exception server side, and return a custom Exception class.

```<code>Public Class Order
...
End Class

Public Class MyException
...
End Class
</code>```

And then in my webservice a function (webmethod):

```<code>Public Function GetOrder(ByVal id As Integer) As Object

    Try
        ...
        Return New Order()
    Catch ex As Exception
        Return New MyException(ex.Message)
    End Try

End Function
</code>```

The problem now is, that since my webmethod is returning the type [Object]. The wdsl that is generated does not contain the order, or the exception.

I can change the [Object] to [Order] Or [MyException], but only one of them is generated in the wsdl.

So does anybody have an idea of how i should handle this? I want both the MyException type and the Order type in my wsdl, but i just cant get it working.

Thank you all.

答:
If you really want to return multiple objects, then maybe you should create a "wrapper" object, e.g something like this:

```<code>'please note: I don't normally use VB.NET, so there might be some errors
Public Class OrderResponse

Public Property Order() As Order
    Get
        Return m_Order
    End Get
    Set
        m_Order = Value
    End Set
End Property
Private m_Order As Order

Public Property Exception() As MyException
    Get
        Return m_Exception
    End Get
    Set
        m_Exception = Value
    End Set
End Property
Private m_Exception As MyException
End Class
</code>```

Then change your method to return an instance of that class, with either the property Order or Exception set to the respective value:

```<code>Public Function GetOrder(ByVal id As Integer) As OrderResponse
    ...
End Function
</code>```

ContentLicense: CC BY-SA 3.0

Body:
We are developing a webservice for a client.  We are not supose to throw SoapExceptions, so instead, we catch every exception server side, and return a custom Exception class.

Public Class Order
...
End Class

Public Class MyException
...
End Class

And then in my webservice a function (webmethod):

Public Function GetOrder(ByVal id As Integer) As Object

    Try
        ...
        Return New Order()
    Catch ex As Exception
        Return New MyException(ex.Message)
    End Try

End Function

The problem now is, that since my webmethod is returning the type [Object]. The wdsl that is generated does not contain the order, or the exception.

I can change the [Object] to [Order] Or [MyException], but only one of them is generated in the wsdl.

So does anybody have an idea of how i should handle this? I want both the MyException type and the Order type in my wsdl, but i just cant get it working.

Thank you all.

Body:
If you really want to return multiple objects, then maybe you should create a "wrapper" object, e.g something like this:

'please note: I don't normally use VB.NET, so there might be some errors
Public Class OrderResponse

Public Property Order() As Order
    Get
        Return m_Order
    End Get
    Set
        m_Order = Value
    End Set
End Property
Private m_Order As Order

Public Property Exception() As MyException
    Get
        Return m_Exception
    End Get
    Set
        m_Exception = Value
    End Set
End Property
Private m_Exception As MyException
End Class

Then change your method to return an instance of that class, with either the property Order or Exception set to the respective value:

Public Function GetOrder(ByVal id As Integer) As OrderResponse
    ...
End Function


问:
how to assign value in asp.net List variable?
I have list variable which is filled by data fetch from db in code behind.
After fetching data in list , can i replace a list variable value?
here is my list

```<code>public  class SummaryInformation
{

    public long Id { get { return parent.Id; } }

    public string TypeCode { get { return parent.TypeCode; } }
}
</code>```

Code for fetching data and replacing list value

```<code>string sTypeCode = "C"
SummaryInformation account = Account.GetSummary(long.Parse(lb.CommandArgument), currentUser, lb.Attribute("Id"));
List<SummaryInformation> accounts = new List<SummaryInformation>();
</code>```

Now once the list loaded here from db data then can i replace TypeCode db value with my value in list?
like below

```<code>accounts.ElementAt(1) = sTypeCode ;
</code>```

i am getting error when i tried to assign list value like this.

答:
You can do the following to override your DB TypeCode value to your sTypeCode:

```<code>string sTypeCode = "C"
SummaryInformation account = Account.GetSummary(long.Parse(lb.CommandArgument), currentUser, lb.Attribute("Id"));
List<SummaryInformation> accounts = new List<SummaryInformation>();
account.TypeCode=sTypeCode;
//Add to your list
accounts.Add(account);
</code>```

You also need to use Automatic Properties to your getter and setter:

```<code>public string TypeCode {get;set;}
</code>```

Body:
I have list variable which is filled by data fetch from db in code behind.
After fetching data in list , can i replace a list variable value?
here is my list

public  class SummaryInformation
{

    public long Id { get { return parent.Id; } }

    public string TypeCode { get { return parent.TypeCode; } }
}

Code for fetching data and replacing list value

string sTypeCode = "C"
SummaryInformation account = Account.GetSummary(long.Parse(lb.CommandArgument), currentUser, lb.Attribute("Id"));
List<SummaryInformation> accounts = new List<SummaryInformation>();

Now once the list loaded here from db data then can i replace TypeCode db value with my value in list?
like below

accounts.ElementAt(1) = sTypeCode ;

i am getting error when i tried to assign list value like this.

Body:
You can do the following to override your DB TypeCode value to your sTypeCode:

string sTypeCode = "C"
SummaryInformation account = Account.GetSummary(long.Parse(lb.CommandArgument), currentUser, lb.Attribute("Id"));
List<SummaryInformation> accounts = new List<SummaryInformation>();
account.TypeCode=sTypeCode;
//Add to your list
accounts.Add(account);

You also need to use Automatic Properties to your getter and setter:

public string TypeCode {get;set;}


问:
Display selected row data in another component using Material UI/React JS
I am running into a bit of a problem grabbing data from a Data Grid (or XGrid) to display in another component on the page.

From the code below you can see that I am grabbing data from a local database that I am displaying in a Data Grid. What I want to do now is add the ability to take the selected rows and display the data (product ID, description, price, etc.) and display it in another component. Right now, I will settle for just a single selection.

I have tried many suggestions found here to add a onSelectionModelChange, but the only thing I am able to grab is the row id value. Not that it would make that much difference, but I am using MySQL for the backend.

Any suggestions?

Here's my React file:

```<code>import * as React from 'react';
import Axios from 'axios';
import { Grid } from '@material-ui/core';

import { createTheme } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/styles';
import { GridToolbarDensitySelector, GridToolbarFilterButton, XGrid } from '@material-ui/x-grid';

const currencyFormatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
});

const usdPrice = {
    type: 'number',
    width: 180,
    valueFormatter: ({ value }) => currencyFormatter.format(Number(value)),
    cellClassName: 'font-tabular-nums',
};

const defaultTheme = createTheme();
const useStyles = makeStyles(
    (theme) => ({
        root: {
            padding: theme.spacing(0.5, 0.5, 0),
            justifyContent: 'space-between',
            display: 'flex',
            alignItems: 'flex-start',
            flexWrap: 'wrap',
            background: '#f3f5f6'
        },
        textField: {
            [theme.breakpoints.down('xs')]: {
                width: '100%',
            },
            margin: theme.spacing(1, 0.5, 1.5),
            '& .MuiSvgIcon-root': {
                marginRight: theme.spacing(0.5),
            },
            '& .MuiInput-underline:before': {
                borderBottom: `1px solid ${theme.palette.divider}`,
            },
        },
    }),
    { defaultTheme },
);

function FilteringToolbar() {
    const classes = useStyles();

    return (
        <div className={classes.root}>
            <div>
                <GridToolbarFilterButton />
                <GridToolbarDensitySelector />
            </div>
        </div>
    );
}

const ProductTable = () => {

    const [rowData, setRowData] = React.useState([]);
    const [rows, setRows] = React.useState(rowData);

    React.useEffect(() => {
        const axios = require('axios').default;
        Axios.get("http://localhost:3001/api/get").then((response) => {
            setRows(response.data);
        }).catch(e => {
            window.alert(e);
        });
    }, [rowData]);

    const columns = [
        { field: 'prodID', headerName: 'Product ID', width: 130, disableReorder: true } ,
        { field: 'desc', headerName: 'Description', width: 200, editable: true, disableReorder: true },
        { field: 'price', headerName: 'Price', editable: true, disableReorder: true, ...usdPrice },
        { field: 'inStock', headerName: 'In Stock', width: 110, editable: true, disableReorder: true, headerAlign: 'center', align: 'center', type: 'boolean'},
        { field: 'new', headerName: 'New', width: 110, editable: true, disableReorder: true, headerAlign: 'center', align: 'center', type: 'boolean' },
    ]

    return (
        <Grid container item xs={12}>
            <Grid container item xs={12}>
                <Grid container item xs={3} />
                <Grid container item xs={6} justifyContent="center" alignItems="center">
                <div style={{ height: 500, width: '100%', display: 'block', marginLeft: 'auto', marginRight: 'auto' }}>
                    <XGrid checkboxSelection {...rows}
                        components={{ Toolbar: FilteringToolbar }}
                        rows={rows}
                        columns={columns}
                        id="id"
                    />
            </div>
            </Grid>
            <Grid container item xs={3} />
            </Grid>
        </Grid>
    );
}

export default ProductTable;
</code>```

答:
I would suggest that instead of trying to get the row data that you need to pass to any child/related components from the table, you get the data directly from your own component's state. Since you already have the ids returned from onSelectionModelChange, you can simply use them to filter the rows state to get the selected items.  For example:

```<code>...

const [selected, setSelected] = React.useState([]);
const [rows, setRows] = React.useState([]);

const handleSelectionChange = React.useCallback(
  (selected = []) => {
    setSelected(rows.filter(({ prodID }) => selected.includes(prodID)));
  },
  [rows]
);

...
</code>```
```<code><XGrid
  // Calls our handler function that filters the selected items from state
  onSelectionModelChange={handleSelectionChange}
  checkboxSelection
  {...rows}
  components={{ Toolbar: FilteringToolbar }}
  rows={rows}
  columns={columns}
  // Re-wires the grid to use your `prodID` instead of it's default `id`
  getRowId={({ prodID }) => prodID}
/>
</code>```

Working Code Sandbox: https://codesandbox.io/s/datagrid-selected-items-rm3f1?file=/src/App.tsx

Body:
I am running into a bit of a problem grabbing data from a Data Grid (or XGrid) to display in another component on the page.

From the code below you can see that I am grabbing data from a local database that I am displaying in a Data Grid. What I want to do now is add the ability to take the selected rows and display the data (product ID, description, price, etc.) and display it in another component. Right now, I will settle for just a single selection.

I have tried many suggestions found here to add a onSelectionModelChange, but the only thing I am able to grab is the row id value. Not that it would make that much difference, but I am using MySQL for the backend.

Any suggestions?

Here's my React file:

import * as React from 'react';
import Axios from 'axios';
import { Grid } from '@material-ui/core';

import { createTheme } from '@material-ui/core/styles';
import { makeStyles } from '@material-ui/styles';
import { GridToolbarDensitySelector, GridToolbarFilterButton, XGrid } from '@material-ui/x-grid';

const currencyFormatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
});

const usdPrice = {
    type: 'number',
    width: 180,
    valueFormatter: ({ value }) => currencyFormatter.format(Number(value)),
    cellClassName: 'font-tabular-nums',
};

const defaultTheme = createTheme();
const useStyles = makeStyles(
    (theme) => ({
        root: {
            padding: theme.spacing(0.5, 0.5, 0),
            justifyContent: 'space-between',
            display: 'flex',
            alignItems: 'flex-start',
            flexWrap: 'wrap',
            background: '#f3f5f6'
        },
        textField: {
            [theme.breakpoints.down('xs')]: {
                width: '100%',
            },
            margin: theme.spacing(1, 0.5, 1.5),
            '& .MuiSvgIcon-root': {
                marginRight: theme.spacing(0.5),
            },
            '& .MuiInput-underline:before': {
                borderBottom: `1px solid ${theme.palette.divider}`,
            },
        },
    }),
    { defaultTheme },
);

function FilteringToolbar() {
    const classes = useStyles();

    return (

                <GridToolbarFilterButton />
                <GridToolbarDensitySelector />

    );
}

const ProductTable = () => {

    const [rowData, setRowData] = React.useState([]);
    const [rows, setRows] = React.useState(rowData);

    React.useEffect(() => {
        const axios = require('axios').default;
        Axios.get("http://localhost:3001/api/get").then((response) => {
            setRows(response.data);
        }).catch(e => {
            window.alert(e);
        });
    }, [rowData]);

    const columns = [
        { field: 'prodID', headerName: 'Product ID', width: 130, disableReorder: true } ,
        { field: 'desc', headerName: 'Description', width: 200, editable: true, disableReorder: true },
        { field: 'price', headerName: 'Price', editable: true, disableReorder: true, ...usdPrice },
        { field: 'inStock', headerName: 'In Stock', width: 110, editable: true, disableReorder: true, headerAlign: 'center', align: 'center', type: 'boolean'},
        { field: 'new', headerName: 'New', width: 110, editable: true, disableReorder: true, headerAlign: 'center', align: 'center', type: 'boolean' },
    ]

    return (
        <Grid container item xs={12}>
            <Grid container item xs={12}>
                <Grid container item xs={3} />
                <Grid container item xs={6} justifyContent="center" alignItems="center">

                    <XGrid checkboxSelection {...rows}
                        components={{ Toolbar: FilteringToolbar }}
                        rows={rows}
                        columns={columns}
                        id="id"
                    />

            </Grid>
            <Grid container item xs={3} />
            </Grid>
        </Grid>
    );
}

export default ProductTable;

Body:
I would suggest that instead of trying to get the row data that you need to pass to any child/related components from the table, you get the data directly from your own component's state. Since you already have the ids returned from onSelectionModelChange, you can simply use them to filter the rows state to get the selected items.  For example:

...

const [selected, setSelected] = React.useState([]);
const [rows, setRows] = React.useState([]);

const handleSelectionChange = React.useCallback(
  (selected = []) => {
    setSelected(rows.filter(({ prodID }) => selected.includes(prodID)));
  },
  [rows]
);

...

<XGrid
  // Calls our handler function that filters the selected items from state
  onSelectionModelChange={handleSelectionChange}
  checkboxSelection
  {...rows}
  components={{ Toolbar: FilteringToolbar }}
  rows={rows}
  columns={columns}
  // Re-wires the grid to use your `prodID` instead of it's default `id`
  getRowId={({ prodID }) => prodID}
/>

Working Code Sandbox: https://codesandbox.io/s/datagrid-selected-items-rm3f1?file=/src/App.tsx


问:
Element "align" is obsolete or non-standard: what should I use instead?
I have this HTML code:

```<code><td align="center">
</code>```

and I'm getting this error in Visual Studio 2008 from ReSharper:

"Element 'align' is obsolete or nonstandard"

What is the replacement of this code to make it standard?

答:
use css styling:

```<code>text-align:center
</code>```

but styling tables doesn't really work well on ie6, if you need it

Body:
I have this HTML code:

and I'm getting this error in Visual Studio 2008 from ReSharper:

"Element 'align' is obsolete or nonstandard"

What is the replacement of this code to make it standard?

Body:
use css styling:

text-align:center

but styling tables doesn't really work well on ie6, if you need it


问:
How to revert a wrong Git pull (remote to local)
I pull a wrong remote branch to local i.e Merge branch 'remote' of ://github.../remote into Local

A right click in TortoiseGit -> Revert changes by this commit is requesting to revert to either "parent 1" or "parent 2". I simply want to cancel the pull remote into local, what should chose ?

答:
Find the original commit your branch was on before you pulled.

ORIG_HEAD points to the original head of a branch before it was changed in a drastic way. "Drastic" means something more than a simple commit, like git reset or git pull. Verify ORIG_HEAD points at your pre-pull commit with git log ORIG_HEAD.

If it isn't, you can use git log --graph --decorate to find the commit before the pull. Or you can use git reflog to look at where HEAD was every time it changed.

Reset the branch.

Assuming it's ORIG_HEAD: git reset --hard ORIG_HEAD

This will move the branch back to the specified commit as if the pull never happened.


问:
React Native Android: How to install Closed Alpha testing build instead of Production?
I have a production build of my React Native app on the Google Play Store, and have created a new version that I'm releasing to a Closed Alpha track for testing. When I go to that Closed Alpha track, it has a link that users should follow in order to install the build.

In a previous app, I didn't have a Production build and instead had only the Closed Alpha track, and following this link successfully installed the test build. However, with the current app, when I follow this link, it installs the Production build instead of the Closed Alpha one. Does anyone know how I can get the link to install the Closed Alpha test build instead of the Production one?

答: For installing the closed testing track you must join as a beta tester. You should add your email id to the tester list in the closed alpha testing track. In play store, you should look for 'Join Beta Program' and join it. Uninstall the app if already installed, or just refresh the page, it should show you the alpha track. Make sure you are logged in to play store with the same email id you have added in tester list.</p>


问:
How to localize .net shared projects
In Visual Studio you can create Shared Projects.

Have Microsoft envisioned any standard approach to localization in a shared project?

I'm pretty sure I can find a way to handle localization, but before I invent my own method, it would be nice to know if there is an "official" way.

EDIT

If you localize a library, the translations should be contained within the library.

If you localize texts using resource strings in a .resx (or .resw) file, then the resource file has to be included in the library, and there has to be code to load the resources from the rignt resource file.

Two things are not possible.

Do the localization only in the component which uses the library.

If you replace a string literal with a resource name, you are changing the source code, which is against the whole idea of using a library.

Use resource names in a library, without providing a .resx file.

That code just wouldn't work.

There is a similar question in the Microsoft forums. Based on the discussion on that page, it looks to me like Microsoft do not provide sufficient support for localization of shared projects.

I have found one interesting example, which is the project CodeMaid project on GitHub.

This is a Visual Studio Extension and not a Xamarin project (shared projects are not limited to Xamarin).
This project contains a resource file (Resource.resx) and a code file (Resources.resx.cs) to access the resources.
Based on this, I assume it is possible to include a .resx file in a shaered project.

However, it does not appear possible to run the custom tool (PublicResXFileCodeGenerator) to generate the code file, and it does not run automatically when you edit the .resx file.

My guess, is that the developers of CodeMaid have not made any changes to the resource file, since moving it into the shared project.

答:
The answer to my original question appears to be "No". With regard to localization, shared projects don't really work.

However, localization can work, but there are two problems.

1. The custom tool PublicResXFileCodeGenerator doesn't run.

In my own tool (which is a visual studio extension), I will try to generate the code behind (Resources.designer.cs) myself. The code required to generate it is quite simple.

This is my basic function ...

```<code>public void GenerateCodeCS ( string resxFullPath, string namespaceName, ITypeResolutionService typeResolver )
{
  string BaseName = Path.GetFileNameWithoutExtension ( resxFullPath ) ;
  string BaseDir  = Path.GetDirectoryName ( resxFullPath ) ;
  string FileName = BaseName + ".designer.cs" ;
  string FullPath = Path.Combine ( BaseDir, FileName ) ;

  using ( var sw = new StreamWriter ( FullPath, false, Encoding.UTF8 ) )
  {
    sw.WriteLine ( $"namespace {namespaceName}.Properties" ) ;
    sw.WriteLine ( "{" );
    sw.WriteLine ( "  using System;" );
    sw.WriteLine ( "  using System.Resources;" );
    sw.WriteLine ( "  using System.Globalization;" );
    sw.WriteLine ( "  public class Resources" );
    sw.WriteLine ( "  {" );
    sw.WriteLine ( "    private static ResourceManager resourceMan;" );
    sw.WriteLine ( "    private static CultureInfo     resourceCulture;" );
    sw.WriteLine ();
    sw.WriteLine ( "    public static global::System.Resources.ResourceManager ResourceManager" );
    sw.WriteLine ( "    {" );
    sw.WriteLine ( "      get" );
    sw.WriteLine ( "      {" );
    sw.WriteLine ( "        if ( resourceMan == null )" );
    sw.WriteLine ( "        {" );
    sw.WriteLine ($"          resourceMan = new ResourceManager(\"{namespaceName}.Properties.Resources\", typeof(Resources).Assembly);" );
    sw.WriteLine ( "        }" );
    sw.WriteLine ( "        return resourceMan ;" );
    sw.WriteLine ( "      }" );
    sw.WriteLine ( "    }" );
    sw.WriteLine ();
    sw.WriteLine ( "    public static CultureInfo Culture { get => resourceCulture; set => resourceCulture = value; }" );
    sw.WriteLine ();

    using ( var resxReader = new ResXResourceReader ( resxFullPath, typeResolver ) )
    {
      resxReader.BasePath         = BaseDir ;
      resxReader.UseResXDataNodes = true ;

      foreach ( DictionaryEntry res in resxReader as IResourceReader )
      {
        var key      = res.Key.ToString() ;
        var resxNode = res.Value as ResXDataNode ;
        var value    = resxNode.GetValue ( typeResolver ) ;
        if ( value is string )
        {
          sw.WriteLine ( $"    public static string {key} => ResourceManager.GetString(\"{key}\", resourceCulture);" ) ;
        }
      }
    }
    sw.WriteLine ( "  }" );
    sw.WriteLine ( "}" );
  }
}
</code>```

This generates a file something like this

```<code>namespace SharedProject.Properties
{
  using System;
  using System.Resources;
  using System.Globalization;
  public class Resources
  {
    private static ResourceManager resourceMan;
    private static CultureInfo     resourceCulture;

    public static global::System.Resources.ResourceManager ResourceManager
    {
      get
      {
        if ( resourceMan == null )
        {
          resourceMan = new ResourceManager("SharedProject.Properties.Resources", typeof(Resources).Assembly);
        }
        return resourceMan ;
      }
    }

    public static CultureInfo Culture { get => resourceCulture; set => resourceCulture = value; }

    public static string Bye_Bye => ResourceManager.GetString("Bye_Bye", resourceCulture);
    public static string Ciao_Ciao => ResourceManager.GetString("Ciao_Ciao", resourceCulture);
    public static string Hello_World => ResourceManager.GetString("Hello_World", resourceCulture);
  }
}
</code>```

It should be possible to include that in a console app and to run it in a pre-build step. The typeResolver parameter is probably not necessary.

2. The namespace for the resources is wrong.

When the resources are compiled into the target application, they are given the namespace of the application, and not the namespace of the shared project.

Since the code in the shared project cannot possibly know the namespace of the target application, this makes it impossible to access the resources.

Fortunately, there is a workaround for this problem. What you have to do, is to edit the project file and add the <LogicalName> property to the resource file.

Actually, in a shared project, it is not the project file (.csproj), but the file project items file (.projitems).

In my example project, the resource file is referenced like this

```<code><EmbeddedResource Include="$(MSBuildThisFileDirectory)Properties\Resources.resx">
  <Generator>PublicResXFileCodeGenerator</Generator>
  <LogicalName>SharedProject.Properties.Resources.resources</LogicalName>
</EmbeddedResource>
</code>```

In this case, SharedProject is the namespace of the shared project, which is referenced by the code behind (see above).

Of course the <Generator> property is pointless, because the custom tool does not run.

I am not aware of any way to add the  property via the GUI or even from a visual studio extension.

Using ILSpy, I can see that the resources are now embedded into my application with the namespace of the shared project

and loading the resources works.

Title: How to localize .net shared projects

Body:
The answer to my original question appears to be "No". With regard to localization, shared projects don't really work.

However, localization can work, but there are two problems.

1. The custom tool PublicResXFileCodeGenerator doesn't run.

In my own tool (which is a visual studio extension), I will try to generate the code behind (Resources.designer.cs) myself. The code required to generate it is quite simple.

This is my basic function ...

public void GenerateCodeCS ( string resxFullPath, string namespaceName, ITypeResolutionService typeResolver )
{
  string BaseName = Path.GetFileNameWithoutExtension ( resxFullPath ) ;
  string BaseDir  = Path.GetDirectoryName ( resxFullPath ) ;
  string FileName = BaseName + ".designer.cs" ;
  string FullPath = Path.Combine ( BaseDir, FileName ) ;

  using ( var sw = new StreamWriter ( FullPath, false, Encoding.UTF8 ) )
  {
    sw.WriteLine ( $"namespace {namespaceName}.Properties" ) ;
    sw.WriteLine ( "{" );
    sw.WriteLine ( "  using System;" );
    sw.WriteLine ( "  using System.Resources;" );
    sw.WriteLine ( "  using System.Globalization;" );
    sw.WriteLine ( "  public class Resources" );
    sw.WriteLine ( "  {" );
    sw.WriteLine ( "    private static ResourceManager resourceMan;" );
    sw.WriteLine ( "    private static CultureInfo     resourceCulture;" );
    sw.WriteLine ();
    sw.WriteLine ( "    public static global::System.Resources.ResourceManager ResourceManager" );
    sw.WriteLine ( "    {" );
    sw.WriteLine ( "      get" );
    sw.WriteLine ( "      {" );
    sw.WriteLine ( "        if ( resourceMan == null )" );
    sw.WriteLine ( "        {" );
    sw.WriteLine ($"          resourceMan = new ResourceManager(\"{namespaceName}.Properties.Resources\", typeof(Resources).Assembly);" );
    sw.WriteLine ( "        }" );
    sw.WriteLine ( "        return resourceMan ;" );
    sw.WriteLine ( "      }" );
    sw.WriteLine ( "    }" );
    sw.WriteLine ();
    sw.WriteLine ( "    public static CultureInfo Culture { get => resourceCulture; set => resourceCulture = value; }" );
    sw.WriteLine ();

    using ( var resxReader = new ResXResourceReader ( resxFullPath, typeResolver ) )
    {
      resxReader.BasePath         = BaseDir ;
      resxReader.UseResXDataNodes = true ;

      foreach ( DictionaryEntry res in resxReader as IResourceReader )
      {
        var key      = res.Key.ToString() ;
        var resxNode = res.Value as ResXDataNode ;
        var value    = resxNode.GetValue ( typeResolver ) ;
        if ( value is string )
        {
          sw.WriteLine ( $"    public static string {key} => ResourceManager.GetString(\"{key}\", resourceCulture);" ) ;
        }
      }
    }
    sw.WriteLine ( "  }" );
    sw.WriteLine ( "}" );
  }
}

This generates a file something like this

namespace SharedProject.Properties
{
  using System;
  using System.Resources;
  using System.Globalization;
  public class Resources
  {
    private static ResourceManager resourceMan;
    private static CultureInfo     resourceCulture;

    public static global::System.Resources.ResourceManager ResourceManager
    {
      get
      {
        if ( resourceMan == null )
        {
          resourceMan = new ResourceManager("SharedProject.Properties.Resources", typeof(Resources).Assembly);
        }
        return resourceMan ;
      }
    }

    public static CultureInfo Culture { get => resourceCulture; set => resourceCulture = value; }

    public static string Bye_Bye => ResourceManager.GetString("Bye_Bye", resourceCulture);
    public static string Ciao_Ciao => ResourceManager.GetString("Ciao_Ciao", resourceCulture);
    public static string Hello_World => ResourceManager.GetString("Hello_World", resourceCulture);
  }
}

It should be possible to include that in a console app and to run it in a pre-build step. The typeResolver parameter is probably not necessary.

2. The namespace for the resources is wrong.

When the resources are compiled into the target application, they are given the namespace of the application, and not the namespace of the shared project.

Since the code in the shared project cannot possibly know the namespace of the target application, this makes it impossible to access the resources.

Fortunately, there is a workaround for this problem. What you have to do, is to edit the project file and add the <LogicalName> property to the resource file.

Actually, in a shared project, it is not the project file (.csproj), but the file project items file (.projitems).

In my example project, the resource file is referenced like this

<EmbeddedResource Include="$(MSBuildThisFileDirectory)Properties\Resources.resx">
  <Generator>PublicResXFileCodeGenerator</Generator>
  <LogicalName>SharedProject.Properties.Resources.resources</LogicalName>
</EmbeddedResource>

In this case, SharedProject is the namespace of the shared project, which is referenced by the code behind (see above).

Of course the <Generator> property is pointless, because the custom tool does not run.

I am not aware of any way to add the  property via the GUI or even from a visual studio extension.

Using ILSpy, I can see that the resources are now embedded into my application with the namespace of the shared project

and loading the resources works.


问:
Yarn throws an error while trying to build electron app
When I try to create an electron app via yarn create electron-app "my-app", it throws an error saying

```<code>'C:\Users\Lincoln' is not recognized as an internal or external command,
operable program or batch file.
error Command failed.
Exit code: 1
Command: C:\Users\Lincoln Muller\AppData\Local\Yarn\bin\create-electron-app
Arguments: my-app
Directory: C:\Users\Lincoln Muller
Output:
</code>```

What should I do? I'm new to Yarn, and NPM worked fine. This also only happens on Windows, when I use my iMac on Monterey or my Linux laptop the command runs fine.

答:
The issue is that you have a space in your directory name and you haven't correctly escaped it.

```<code>C:\Users\Lincoln Muller
</code>```

This looks like you are trying to pass the parameter Muller to program C:\Users\Lincoln

I suggest just using a folder that doesn't contain spaces or escape the [space character].

https://www.howtogeek.com/694949/how-to-escape-spaces-in-file-paths-on-the-windows-command-line/

Three Ways to Escape Spaces on Windows There are three different ways
you can escape file paths on Windows:

By enclosing the path (or parts of it) in double quotation marks ( ”
).

By adding a caret character ( ^ ) before each space. (This only
works in Command Prompt/CMD, and it doesn’t seem to work with every
command.)

By adding a grave accent character ( ` ) before each space.
(This only works in PowerShell, but it always works.)

Body:
When I try to create an electron app via yarn create electron-app "my-app", it throws an error saying

'C:\Users\Lincoln' is not recognized as an internal or external command,
operable program or batch file.
error Command failed.
Exit code: 1
Command: C:\Users\Lincoln Muller\AppData\Local\Yarn\bin\create-electron-app
Arguments: my-app
Directory: C:\Users\Lincoln Muller
Output:

What should I do? I'm new to Yarn, and NPM worked fine. This also only happens on Windows, when I use my iMac on Monterey or my Linux laptop the command runs fine.

Body:
The issue is that you have a space in your directory name and you haven't correctly escaped it.

C:\Users\Lincoln Muller

This looks like you are trying to pass the parameter Muller to program C:\Users\Lincoln

I suggest just using a folder that doesn't contain spaces or escape the [space character].

https://www.howtogeek.com/694949/how-to-escape-spaces-in-file-paths-on-the-windows-command-line/

Three Ways to Escape Spaces on Windows There are three different ways
you can escape file paths on Windows:

By enclosing the path (or parts of it) in double quotation marks ( ”
).

By adding a caret character ( ^ ) before each space. (This only
works in Command Prompt/CMD, and it doesn’t seem to work with every
command.)

By adding a grave accent character ( ` ) before each space.
(This only works in PowerShell, but it always works.)


问:
Trying to use TwitterLib 25 with GAS
So using the following simple code to just test tweet to Twitter. I have signed up for the account and have all the pertinent info. The only thing I may be doing wrong is putting the wrong key/secret in the wrong area. Here is my Twitter dev setup:

This is my simple code:

```<code>function sendTweet(status) {
  status = "Is this a cool tweet?";

  var twitterKeys = {
    TWITTER_CONSUMER_KEY: '**************************',
    TWITTER_CONSUMER_SECRET: '**************************',
    TWITTER_ACCESS_TOKEN: '**************************-**************************',
    TWITTER_ACCESS_SECRET: '**************************',
  };

  var props = PropertiesService.getScriptProperties();

  props.setProperties(twitterKeys);

  var service = new Twitterlib.OAuth(props);

  if (service.hasAccess()) {
    var response = service.sendTweet(status);

    if (response) {
      Logger.log('Tweet ID ' + response.id_str);
    } else {
      // Tweet could not be sent
      // Go to View -> Logs to see the error message
    }
  }
}
</code>```

My consumer key/secret -> API Key and Secret below and my access token/secret -> Access Token and Secret below. I am seeing the following error which doesn't give me a lot to go on as far as errors and been fighting to figure this out for days.

```<code>Send tweet failure. Error was:
{"name":"Exception"}

options were:
{"method":"POST","payload":"status=Is%20this%20a%20cool%20tweet%3F","headers":{"Authorization":"OAuth oauth_consumer_key=\"**************************\", oauth_nonce=\"**************************\", oauth_signature=\"**************************%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1644456180\", oauth_token=\"**************************-**************************\", oauth_version=\"1.0\""},"escaping":false}
</code>```

Any help or resources would be a huge help in figuring this out!! Thank you in advance.

phi

答: This turned out being I needed to turn on essential API access in the Twitter API Developer site. Once I turned that on, and retried, it was a success. Hope that helps anyone else.</p>

Title: Trying to use TwitterLib 25 with GAS

Body:
So using the following simple code to just test tweet to Twitter. I have signed up for the account and have all the pertinent info. The only thing I may be doing wrong is putting the wrong key/secret in the wrong area. Here is my Twitter dev setup:

This is my simple code:

function sendTweet(status) {
  status = "Is this a cool tweet?";

  var twitterKeys = {
    TWITTER_CONSUMER_KEY: '**************************',
    TWITTER_CONSUMER_SECRET: '**************************',
    TWITTER_ACCESS_TOKEN: '**************************-**************************',
    TWITTER_ACCESS_SECRET: '**************************',
  };

  var props = PropertiesService.getScriptProperties();

  props.setProperties(twitterKeys);

  var service = new Twitterlib.OAuth(props);

  if (service.hasAccess()) {
    var response = service.sendTweet(status);

    if (response) {
      Logger.log('Tweet ID ' + response.id_str);
    } else {
      // Tweet could not be sent
      // Go to View -> Logs to see the error message
    }
  }
}

My consumer key/secret -> API Key and Secret below and my access token/secret -> Access Token and Secret below. I am seeing the following error which doesn't give me a lot to go on as far as errors and been fighting to figure this out for days.

Send tweet failure. Error was:
{"name":"Exception"}

options were:
{"method":"POST","payload":"status=Is%20this%20a%20cool%20tweet%3F","headers":{"Authorization":"OAuth oauth_consumer_key=\"**************************\", oauth_nonce=\"**************************\", oauth_signature=\"**************************%3D\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1644456180\", oauth_token=\"**************************-**************************\", oauth_version=\"1.0\""},"escaping":false}

Any help or resources would be a huge help in figuring this out!! Thank you in advance.

phi


问:
Testing an SFTP client with Spock Framework
We actually use JUnit and the great FakeSftpServerRule junit rule to test a custom SFTP client we made. That was working great.

Lastly, we want to get rid of junit in favor of the spock framework because we try to migrate to groovy.

Do you guys know any equivalent of FakeSftpServerRule or any way to "switch" a junit rule into a spock rule equivalent ?

Thank you a lot.

答:
The same author also published Fake SFTP Server Lambda, which is independent of the test framework in contrast to the JUnit 4 rule you use.

If you want to stick with the old tool, Spock 1.3 can also use JUnit 4 rules, and in Spock 2.x it might also work with the JUnit 4 compatibility layer.

Update: Here is an example program using the SSHJ library for downloading a file from an SFTP server, so we have a subject under test:

package de.scrum_master.stackoverflow.q71081881;

import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import net.schmizz.sshj.xfer.InMemoryDestFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class SFTPFileDownloader {
  private String host;
  private int port;
  private String user;
  private String password;

  public SFTPFileDownloader(String host, int port, String user, String password) {
    this.host = host;
    this.port = port;
    this.user = user;
    this.password = password;
  }

  protected static class ByteArrayInMemoryDestFile extends InMemoryDestFile {
    private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    @Override
    public ByteArrayOutputStream getOutputStream() {
      return outputStream;
    }
  }

  public String getFileContent(String path) throws IOException {
    try (
      SSHClient sshClient = setupSshj();
      SFTPClient sftpClient = sshClient.newSFTPClient()
    )
    {
      ByteArrayInMemoryDestFile inMemoryDestFile = new ByteArrayInMemoryDestFile();
      sftpClient.get(path, inMemoryDestFile);
      return inMemoryDestFile.getOutputStream().toString("UTF-8");
    }
  }

  private SSHClient setupSshj() throws IOException {
    SSHClient client = new SSHClient();
    client.addHostKeyVerifier(new PromiscuousVerifier());
    client.connect(host, port);
    client.authPassword(user, password);
    return client;
  }
}
```
<p>The following Spock specification uses the Fake SFTP Server Lambda in two ways:</p>
<ol>
<li><p>In feature method <code>"use original server class"</code>, we use <code>withSftpServer</code> the way it was intended by its author, i.e. configuring it and performing interactions in a single lambda or Groovy closure. The only way to make it a bit more spockish is to assign results to previously defined variables and use them in Spock conditions outside of the closure later. Like Leonard said, the resulting Spock specification code is suboptimal, because of the consumer's greed to immediately execute all interactions and close the server again.</p>
</li>
<li><p>In feature method <code>"use custom server class"</code>, we use a custom <code>CloseableFakeSftpServer</code> which shamelessly utilises its parent's private constructors, methods and fields. In a Groovy class, we can do that. But of course, it would be much better for the upstream library to be extended and opened up a little in order to support a more spock-like way to first create and configure the server and later perform interactions and verify results, without being confined to a lambda or closure. I even made the helper class <code>@AutoCloseable</code> and use the Spock <code>@AutoCleanup</code> extension in order to avoid manual closing in a <code>cleanup:</code> block. The helper class also uses Groovy's <code>@Delegate FakeSftpServer</code> in order to expose the delegate's methods in its own interface. This is a workaround for not being able to simply extend the original server class, because not even Groovy can call a private super constructor.</p>
</li>
</ol>
<p>So this is the helper class for test variant #2:</p>
<pre class="lang-java prettyprint-override"><code>package de.scrum_master.stackoverflow.q71081881

import com.github.stefanbirkner.fakesftpserver.lambda.FakeSftpServer

class CloseableFakeSftpServer implements AutoCloseable {
  @Delegate
  private FakeSftpServer fakeSftpServer
  private Closeable closeServer

  CloseableFakeSftpServer() {
    fakeSftpServer = new FakeSftpServer(FakeSftpServer.createFileSystem())
    closeServer = fakeSftpServer.start(0)
  }

  @Override
  void close() throws Exception {
    fakeSftpServer.fileSystem.close()
    closeServer.close()
  }
}
</code>```

And here we finally have the specification with the two alternative feature methods (I like the second one better):

package de.scrum_master.stackoverflow.q71081881

import spock.lang.AutoCleanup
import spock.lang.Specification

import static com.github.stefanbirkner.fakesftpserver.lambda.FakeSftpServer.withSftpServer
import static java.nio.charset.StandardCharsets.UTF_8

class SFTPServerTest extends Specification {
  @AutoCleanup
  def server = new CloseableFakeSftpServer()
  def user = "someone"
  def password = "secret"

  def "use original server class"() {
    given:
    def fileContent = null

    when:
    withSftpServer { server ->
      server.addUser(user, password)
      server.putFile("/directory/file.txt", "content of file", UTF_8)
      // Interact with the subject under test
      def client = new SFTPFileDownloader("localhost", server.port, user, password)
      fileContent = client.getFileContent("/directory/file.txt")
    }

    then:
    fileContent == "content of file"
  }

  def "use custom server class"() {
    given: "a preconfigured fake SFTP server"
    server.addUser(user, password)
    server.putFile("/directory/file.txt", "content of file", UTF_8)

    and: "an SFTP client under test"
    def client = new SFTPFileDownloader("localhost", server.port, user, password)

    expect:
    client.getFileContent("/directory/file.txt") == "content of file"
  }

}
```

Try it in the Groovy web console.

Body:
The same author also published Fake SFTP Server Lambda, which is independent of the test framework in contrast to the JUnit 4 rule you use.

If you want to stick with the old tool, Spock 1.3 can also use JUnit 4 rules, and in Spock 2.x it might also work with the JUnit 4 compatibility layer.

Update: Here is an example program using the SSHJ library for downloading a file from an SFTP server, so we have a subject under test:

package de.scrum_master.stackoverflow.q71081881;

import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import net.schmizz.sshj.xfer.InMemoryDestFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class SFTPFileDownloader {
  private String host;
  private int port;
  private String user;
  private String password;

  public SFTPFileDownloader(String host, int port, String user, String password) {
    this.host = host;
    this.port = port;
    this.user = user;
    this.password = password;
  }

  protected static class ByteArrayInMemoryDestFile extends InMemoryDestFile {
    private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    @Override
    public ByteArrayOutputStream getOutputStream() {
      return outputStream;
    }
  }

  public String getFileContent(String path) throws IOException {
    try (
      SSHClient sshClient = setupSshj();
      SFTPClient sftpClient = sshClient.newSFTPClient()
    )
    {
      ByteArrayInMemoryDestFile inMemoryDestFile = new ByteArrayInMemoryDestFile();
      sftpClient.get(path, inMemoryDestFile);
      return inMemoryDestFile.getOutputStream().toString("UTF-8");
    }
  }

  private SSHClient setupSshj() throws IOException {
    SSHClient client = new SSHClient();
    client.addHostKeyVerifier(new PromiscuousVerifier());
    client.connect(host, port);
    client.authPassword(user, password);
    return client;
  }
}

The following Spock specification uses the Fake SFTP Server Lambda in two ways:

In feature method "use original server class", we use withSftpServer the way it was intended by its author, i.e. configuring it and performing interactions in a single lambda or Groovy closure. The only way to make it a bit more spockish is to assign results to previously defined variables and use them in Spock conditions outside of the closure later. Like Leonard said, the resulting Spock specification code is suboptimal, because of the consumer's greed to immediately execute all interactions and close the server again.

In feature method "use custom server class", we use a custom CloseableFakeSftpServer which shamelessly utilises its parent's private constructors, methods and fields. In a Groovy class, we can do that. But of course, it would be much better for the upstream library to be extended and opened up a little in order to support a more spock-like way to first create and configure the server and later perform interactions and verify results, without being confined to a lambda or closure. I even made the helper class @AutoCloseable and use the Spock @AutoCleanup extension in order to avoid manual closing in a cleanup: block. The helper class also uses Groovy's @Delegate FakeSftpServer in order to expose the delegate's methods in its own interface. This is a workaround for not being able to simply extend the original server class, because not even Groovy can call a private super constructor.

So this is the helper class for test variant #2:

package de.scrum_master.stackoverflow.q71081881

import com.github.stefanbirkner.fakesftpserver.lambda.FakeSftpServer

class CloseableFakeSftpServer implements AutoCloseable {
  @Delegate
  private FakeSftpServer fakeSftpServer
  private Closeable closeServer

  CloseableFakeSftpServer() {
    fakeSftpServer = new FakeSftpServer(FakeSftpServer.createFileSystem())
    closeServer = fakeSftpServer.start(0)
  }

  @Override
  void close() throws Exception {
    fakeSftpServer.fileSystem.close()
    closeServer.close()
  }
}

And here we finally have the specification with the two alternative feature methods (I like the second one better):

package de.scrum_master.stackoverflow.q71081881

import spock.lang.AutoCleanup
import spock.lang.Specification

import static com.github.stefanbirkner.fakesftpserver.lambda.FakeSftpServer.withSftpServer
import static java.nio.charset.StandardCharsets.UTF_8

class SFTPServerTest extends Specification {
  @AutoCleanup
  def server = new CloseableFakeSftpServer()
  def user = "someone"
  def password = "secret"

  def "use original server class"() {
    given:
    def fileContent = null

    when:
    withSftpServer { server ->
      server.addUser(user, password)
      server.putFile("/directory/file.txt", "content of file", UTF_8)
      // Interact with the subject under test
      def client = new SFTPFileDownloader("localhost", server.port, user, password)
      fileContent = client.getFileContent("/directory/file.txt")
    }

    then:
    fileContent == "content of file"
  }

  def "use custom server class"() {
    given: "a preconfigured fake SFTP server"
    server.addUser(user, password)
    server.putFile("/directory/file.txt", "content of file", UTF_8)

    and: "an SFTP client under test"
    def client = new SFTPFileDownloader("localhost", server.port, user, password)

    expect:
    client.getFileContent("/directory/file.txt") == "content of file"
  }

}

Try it in the Groovy web console.


问:
How to make a spaghetti plot in ggplot R for categorical variables, and colour each line by ID?
I'm trying to make a spaghetti plot for some time series data and am having some trouble - my attempts so far do not show a separate line for each individual.

Individuals were sampled twice (in July and October) and at each time point I tested whether or not they were infected with nematodes (Yes/No).

I want to make a graph with "Nematode infection status" on the Y axis and "Month" (or "Time" if I have to make it numeric?) on the X axis.

My data looks like this:

```<code>ID Month Time nematode_infected
1  July   1   Yes
1  Oct    2   Yes
2  July   1   Yes
2  Oct    2   No
3  July   1   No
3  Oct    2   Yes
</code>```

ID, Month, and nematode_infected are all factors

And my current code to graph it looks like this:

```<code>ggplot(recaptures_combined_long, aes(x=Time, y=nematode_infected, group=ID))+
  facet_wrap(~RELATIVEAGE)+
  labs(x="Month", y="Nematode infected?") + geom_line()
</code>```

This is what I get  (note that I have ~70 different IDs so there should be 70 lines on this graph, but there are only 4 per graph)

If I use "colour = ID" instead of "group = ID", I get this mess.

What I want is something like this, but with each line (each ID) a different colour:

Any idea how I could go about producing this graph? Thank you!

Edit -  the solution was:

```<code>ggplot(recaptures_combined_long, aes(nematode_infected, Month, color = as.factor(ID), group = ID) )+
  facet_wrap(~RELATIVEAGE)+ labs(x="Nematode infected?", y="Month")+
  geom_line(position=position_dodge(width=0.2))+theme_classic()  +
  coord_flip() + theme(legend.position="none")
</code>```

答:
Is this what you are looking for?

df <- read.table(text =
"ID Month Time nematode_infected
1  July   1   Yes
1  Oct    2   Yes
2  July   1   Yes
2  Oct    2   No
3  July   1   No
3  Oct    2   Yes",
h = T)

library(ggplot2)

ggplot(df) +
  geom_line(aes(Month, nematode_infected, color = as.factor(ID), group = ID))
```

Created on 2022-02-11 by the reprex package (v2.0.0)

Body:
I'm trying to make a spaghetti plot for some time series data and am having some trouble - my attempts so far do not show a separate line for each individual.

Individuals were sampled twice (in July and October) and at each time point I tested whether or not they were infected with nematodes (Yes/No).

I want to make a graph with "Nematode infection status" on the Y axis and "Month" (or "Time" if I have to make it numeric?) on the X axis.

My data looks like this:

ID Month Time nematode_infected
1  July   1   Yes
1  Oct    2   Yes
2  July   1   Yes
2  Oct    2   No
3  July   1   No
3  Oct    2   Yes

ID, Month, and nematode_infected are all factors

And my current code to graph it looks like this:

ggplot(recaptures_combined_long, aes(x=Time, y=nematode_infected, group=ID))+
  facet_wrap(~RELATIVEAGE)+
  labs(x="Month", y="Nematode infected?") + geom_line()

This is what I get  (note that I have ~70 different IDs so there should be 70 lines on this graph, but there are only 4 per graph)

If I use "colour = ID" instead of "group = ID", I get this mess.

What I want is something like this, but with each line (each ID) a different colour:

Any idea how I could go about producing this graph? Thank you!

Edit -  the solution was:

ggplot(recaptures_combined_long, aes(nematode_infected, Month, color = as.factor(ID), group = ID) )+
  facet_wrap(~RELATIVEAGE)+ labs(x="Nematode infected?", y="Month")+
  geom_line(position=position_dodge(width=0.2))+theme_classic()  +
  coord_flip() + theme(legend.position="none")

Body:
Is this what you are looking for?

df <- read.table(text =
"ID Month Time nematode_infected
1  July   1   Yes
1  Oct    2   Yes
2  July   1   Yes
2  Oct    2   No
3  July   1   No
3  Oct    2   Yes",
h = T)

library(ggplot2)

ggplot(df) +
  geom_line(aes(Month, nematode_infected, color = as.factor(ID), group = ID))

Created on 2022-02-11 by the reprex package (v2.0.0)


问:
How to Accept style suggestions of a google doc with Google Doc API?
As title, in this post I already know how to retrieve all-suggestion-accepted content of a document. Now I also want to retrieve the "style suggestion" of the content of the document. I've referred to the second half part of this guideline, but still have no clue about it. Below is the snippet I have as yet.</p>
```<code>
function get_all_suggestion_accepted()
{

  var doc_id = 'My doc ID';
  SUGGEST_MODE = 'PREVIEW_SUGGESTIONS_ACCEPTED'
  suggestions = Docs.Documents.get(doc_id, {
    'suggestionsViewMode': SUGGEST_MODE,
    "textStyleSuggestionState": { "underlineSuggested": true, }
  });

  var new_content = '';

  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        new_content += element.textRun.content;
      });
  });

   console.log(new_content);
}

</code>```

答:
Currently, accepting/rejecting suggestions via Google Docs API is not possible.

To retrieve the style suggestion, you need to access the textRun of each paragraph element and check if suggestedTextStyleChanges exists.

Example:

Code:

```<code>function myFunction() {
  var suggestions = Docs.Documents.get("doc id");
  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        if(element.textRun.suggestedTextStyleChanges){
          Logger.log(element.textRun.content);
          Logger.log(element.textRun.suggestedTextStyleChanges);
        }
      });
  });
}
</code>```

Output:

Edit

In your code, you added "textStyleSuggestionState": { "underlineSuggested": true, }, but Docs.get method only accepts suggestionsViewMode as Query Parameter and the values you can input are:

DEFAULT_FOR_CURRENT_ACCESS - The SuggestionsViewMode applied to the
returned document depends on the user's current access level. If the
user only has view access, PREVIEW_WITHOUT_SUGGESTIONS is applied.
Otherwise, SUGGESTIONS_INLINE is applied. This is the default
suggestions view mode.

SUGGESTIONS_INLINE     The returned document has suggestions inline.
Suggested changes will be differentiated from base content within the
document.

Requests to retrieve a document using this mode will return a 403
error if the user does not have permission to view suggested changes.

PREVIEW_SUGGESTIONS_ACCEPTED   The returned document is a preview with
all suggested changes accepted.

Requests to retrieve a document using this mode will return a 403
error if the user does not have permission to view suggested changes.

PREVIEW_WITHOUT_SUGGESTIONS   The returned document is a preview with
all suggested changes rejected if there are any suggestions in the
document.

The correct way to find all the underlineSuggested: true is by traversing it in the Response body and use SUGGESTIONS_INLINE as suggestionsViewMode.

Example:

Document:

This code will print the string that has underline suggestion:

```<code>function get_all_suggestion_accepted() {
  var suggestions = Docs.Documents.get("11Tx4uvv5yN_TplT4TIUyEWTZ6bUMTGaensYT20EZ4r0");
  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        if(element.textRun.suggestedTextStyleChanges){
          var obj = JSON.parse(JSON.stringify(element.textRun.suggestedTextStyleChanges));
          if(obj[Object.keys(obj)[0]].textStyleSuggestionState.underlineSuggested){
            Logger.log(element.textRun.content);
          }
        }
      });
  });
}
</code>```

Output:

Note: If you want to view all the suggestions, you have to use  SUGGESTIONS_INLINE in the textStyleSuggestionState query parameter or remove it as SUGGESTIONS_INLINE is the default view if you have access to the document. Also, when you use PREVIEW_SUGGESTIONS_ACCEPTED you won't see any suggestions in the object as it returns a preview of the document with all the suggestions accepted.

Further Reading

SuggestedTextStyle

Javascript Object

HTTP Request methods

Body:
As title, in this post I already know how to retrieve all-suggestion-accepted content of a document. Now I also want to retrieve the "style suggestion" of the content of the document. I've referred to the second half part of this guideline, but still have no clue about it. Below is the snippet I have as yet.

function get_all_suggestion_accepted()
{

  var doc_id = 'My doc ID';
  SUGGEST_MODE = 'PREVIEW_SUGGESTIONS_ACCEPTED'
  suggestions = Docs.Documents.get(doc_id, {
    'suggestionsViewMode': SUGGEST_MODE,
    "textStyleSuggestionState": { "underlineSuggested": true, }
  });

  var new_content = '';

  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        new_content += element.textRun.content;
      });
  });

   console.log(new_content);
}

Body:
Currently, accepting/rejecting suggestions via Google Docs API is not possible.

To retrieve the style suggestion, you need to access the textRun of each paragraph element and check if suggestedTextStyleChanges exists.

Example:

Code:

function myFunction() {
  var suggestions = Docs.Documents.get("doc id");
  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        if(element.textRun.suggestedTextStyleChanges){
          Logger.log(element.textRun.content);
          Logger.log(element.textRun.suggestedTextStyleChanges);
        }
      });
  });
}

Output:

Edit

In your code, you added "textStyleSuggestionState": { "underlineSuggested": true, }, but Docs.get method only accepts suggestionsViewMode as Query Parameter and the values you can input are:

DEFAULT_FOR_CURRENT_ACCESS - The SuggestionsViewMode applied to the
returned document depends on the user's current access level. If the
user only has view access, PREVIEW_WITHOUT_SUGGESTIONS is applied.
Otherwise, SUGGESTIONS_INLINE is applied. This is the default
suggestions view mode.

SUGGESTIONS_INLINE     The returned document has suggestions inline.
Suggested changes will be differentiated from base content within the
document.

Requests to retrieve a document using this mode will return a 403
error if the user does not have permission to view suggested changes.

PREVIEW_SUGGESTIONS_ACCEPTED   The returned document is a preview with
all suggested changes accepted.

Requests to retrieve a document using this mode will return a 403
error if the user does not have permission to view suggested changes.

PREVIEW_WITHOUT_SUGGESTIONS   The returned document is a preview with
all suggested changes rejected if there are any suggestions in the
document.

The correct way to find all the underlineSuggested: true is by traversing it in the Response body and use SUGGESTIONS_INLINE as suggestionsViewMode.

Example:

Document:

This code will print the string that has underline suggestion:

function get_all_suggestion_accepted() {
  var suggestions = Docs.Documents.get("11Tx4uvv5yN_TplT4TIUyEWTZ6bUMTGaensYT20EZ4r0");
  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        if(element.textRun.suggestedTextStyleChanges){
          var obj = JSON.parse(JSON.stringify(element.textRun.suggestedTextStyleChanges));
          if(obj[Object.keys(obj)[0]].textStyleSuggestionState.underlineSuggested){
            Logger.log(element.textRun.content);
          }
        }
      });
  });
}

Output:

Note: If you want to view all the suggestions, you have to use  SUGGESTIONS_INLINE in the textStyleSuggestionState query parameter or remove it as SUGGESTIONS_INLINE is the default view if you have access to the document. Also, when you use PREVIEW_SUGGESTIONS_ACCEPTED you won't see any suggestions in the object as it returns a preview of the document with all the suggestions accepted.

Further Reading

SuggestedTextStyle

Javascript Object

HTTP Request methods


问:
How to agg a pyspark dataframe and show the intersection of the lists in a column?
I have a dataframe like this one:

+-------+-----------+
| grupos|    valores|
+-------+-----------+
|grupo_1|  [1, 2, 3]|
|grupo_1|  [1, 2, 5]|
|grupo_1|  [1, 2, 6]|
|grupo_2|  [1, 2, 7]|
|grupo_2| [12, 2, 7]|
|grupo_2| [32, 2, 7]|
+-------+-----------+
```
<p>I need something to groupby and show only the intersection of the lists, like:</p>
<pre class="lang-none prettyprint-override"><code>+-------+-----------+
| grupos|    valores|
+-------+-----------+
|grupo_1|     [1, 2]|
|grupo_2|     [2, 7]|
+-------+-----------+
</code>```

Anyone can help me?

答:
Group by grupos column and collect list of valores. Then using aggregate with array_intersect functions, you find the intersection of all sub arrays:

```<code>from pyspark.sql import functions as F

df = spark.createDataFrame([
    ("grupo_1", [1, 2, 3]), ("grupo_1", [1, 2, 5]),
    ("grupo_1", [1, 2, 6]), ("grupo_2", [1, 2, 7]),
    ("grupo_2", [12, 2, 7]), ("grupo_2", [32, 2, 7])
], ["grupos", "valores"])

df1 = df.groupBy("grupos").agg(
    F.collect_set("valores").alias("valores")
).withColumn(
    "valores",
    F.expr("aggregate(valores, valores[0], (acc, x) -> array_intersect(acc, x))")
)

df1.show()
#+-------+-------+
#|grupos |valores|
#+-------+-------+
#|grupo_1|[1, 2] |
#|grupo_2|[2, 7] |
#+-------+-------+
</code>```

Body:
I have a dataframe like this one:

+-------+-----------+
| grupos|    valores|
+-------+-----------+
|grupo_1|  [1, 2, 3]|
|grupo_1|  [1, 2, 5]|
|grupo_1|  [1, 2, 6]|
|grupo_2|  [1, 2, 7]|
|grupo_2| [12, 2, 7]|
|grupo_2| [32, 2, 7]|
+-------+-----------+

I need something to groupby and show only the intersection of the lists, like:

+-------+-----------+
| grupos|    valores|
+-------+-----------+
|grupo_1|     [1, 2]|
|grupo_2|     [2, 7]|
+-------+-----------+

Anyone can help me?

Body:
Group by grupos column and collect list of valores. Then using aggregate with array_intersect functions, you find the intersection of all sub arrays:

from pyspark.sql import functions as F

df = spark.createDataFrame([
    ("grupo_1", [1, 2, 3]), ("grupo_1", [1, 2, 5]),
    ("grupo_1", [1, 2, 6]), ("grupo_2", [1, 2, 7]),
    ("grupo_2", [12, 2, 7]), ("grupo_2", [32, 2, 7])
], ["grupos", "valores"])

df1 = df.groupBy("grupos").agg(
    F.collect_set("valores").alias("valores")
).withColumn(
    "valores",
    F.expr("aggregate(valores, valores[0], (acc, x) -> array_intersect(acc, x))")
)

df1.show()
#+-------+-------+
#|grupos |valores|
#+-------+-------+
#|grupo_1|[1, 2] |
#|grupo_2|[2, 7] |
#+-------+-------+


答:
You should use text-align in CSS rather than using the obsolete html styling attributes.

```<code>td{
text-align:center;
}
</code>```

Title: Element "align" is obsolete or non-standard: what should I use instead?

Body:
You should use text-align in CSS rather than using the obsolete html styling attributes.

td{
text-align:center;
}


问:
F# record: ref vs mutable field
While refactoring my F# code, I found a record with a field of type bool ref:

type MyType =
  {
    Enabled : bool ref
    // other, irrelevant fields here
  }
```
<p>I decided to try changing it to a <code>mutable</code> field instead</p>
<pre class="lang-ml prettyprint-override"><code>// Refactored version
type MyType =
  {
    mutable Enabled : bool
    // other fields unchanged
  }
</code>```

Also, I applied all the changes required to make the code compile (i.e. changing := to <-, removing incr and decr functions, etc).

I noticed that after the changes some of the unit tests started to fail.
As the code is pretty large, I can't really see what exactly changed.

Is there a significant difference in implementation of the two that could change the behavior of my program?

答:
Yes, there is a difference. Refs are first-class values, while mutable variables are a language construct.

Or, from a different perspective, you might say that ref cells are passed by reference, while mutable variables are passed by value.

Consider this:

```<code>type T = { mutable x : int }
type U = { y : int ref }

let t = { x = 5 }
let u = { y = ref 5 }

let mutable xx = t.x
xx <- 10
printfn "%d" t.x  // Prints 5

let mutable yy = u.y
yy := 10
printfn "%d" !u.y // Prints 10
</code>```

This happens because xx is a completely new mutable variable, unrelated to t.x, so that mutating xx has no effect on x.

But yy is a reference to the exact same ref cell as u.y, so that pushing a new value into that cell while referring to it via yy has the same effect as if referring to it via u.y.

If you "copy" a ref, the copy ends up pointing to the same ref, but if you copy a mutable variable, only its value gets copied.

Title: F# record: ref vs mutable field

Body:
While refactoring my F# code, I found a record with a field of type bool ref:

type MyType =
  {
    Enabled : bool ref
    // other, irrelevant fields here
  }

I decided to try changing it to a mutable field instead

// Refactored version
type MyType =
  {
    mutable Enabled : bool
    // other fields unchanged
  }

Also, I applied all the changes required to make the code compile (i.e. changing := to <-, removing incr and decr functions, etc).

I noticed that after the changes some of the unit tests started to fail.
As the code is pretty large, I can't really see what exactly changed.

Is there a significant difference in implementation of the two that could change the behavior of my program?

Body:
Yes, there is a difference. Refs are first-class values, while mutable variables are a language construct.

Or, from a different perspective, you might say that ref cells are passed by reference, while mutable variables are passed by value.

Consider this:

type T = { mutable x : int }
type U = { y : int ref }

let t = { x = 5 }
let u = { y = ref 5 }

let mutable xx = t.x
xx <- 10
printfn "%d" t.x  // Prints 5

let mutable yy = u.y
yy := 10
printfn "%d" !u.y // Prints 10

This happens because xx is a completely new mutable variable, unrelated to t.x, so that mutating xx has no effect on x.

But yy is a reference to the exact same ref cell as u.y, so that pushing a new value into that cell while referring to it via yy has the same effect as if referring to it via u.y.

If you "copy" a ref, the copy ends up pointing to the same ref, but if you copy a mutable variable, only its value gets copied.


问:
Python telling me thread assigned outside function isn't assigned
I made this program to have a timed input:

```<code>import time
from threading import Thread

def get_answer():
    answer = input ("ANSWER THE QUESTION!!!")

def runtime():
    time.sleep(1)
    timer = timer-1
    print (timer)
    if timer == 0:
        thread1.cancel()
        print ("hi")

timer = 5

# create two new threads
thread1 = Thread(target=get_answer)
thread2 = Thread(target=runtime)

# start the threads
thread1.start()
thread2.start()

# wait for the threads to complete
thread1.join()
thread2.join()
</code>```

When I run it though, I get this error:

```<code>Exception in thread Thread-2 (runtime):
Traceback (most recent call last):
  File "C:\Users\user1\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Users\user1\AppData\Local\Programs\Python\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "c:\Users\user1\Desktop\import time.py", line 9, in runtime
    timer = timer-1
UnboundLocalError: local variable 'timer' referenced before assignment
</code>```

How can I fix this? I set the variable timer before the thread runs, so why isn't it assigned already?

答:
Here's how you can handle input with a timer:

```<code>from signal import signal, alarm, SIGALRM

TIMEOUT = 5

def get_answer(timeout):
    def handler(*args):
        raise Exception('Timeout')
    signal(SIGALRM, handler)
    alarm(timeout)
    try:
        return input ("ANSWER THE QUESTION!!! ")
    except Exception:
        pass
    finally:
        alarm(0)

print(get_answer(TIMEOUT))
</code>```

So, no threads here. If no input within TIMEOUT seconds the get_answer() function will return None. Otherwise it will return the user input.

Body:
I made this program to have a timed input:

import time
from threading import Thread

def get_answer():
    answer = input ("ANSWER THE QUESTION!!!")

def runtime():
    time.sleep(1)
    timer = timer-1
    print (timer)
    if timer == 0:
        thread1.cancel()
        print ("hi")

timer = 5

# create two new threads
thread1 = Thread(target=get_answer)
thread2 = Thread(target=runtime)

# start the threads
thread1.start()
thread2.start()

# wait for the threads to complete
thread1.join()
thread2.join()

When I run it though, I get this error:

Exception in thread Thread-2 (runtime):
Traceback (most recent call last):
  File "C:\Users\user1\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Users\user1\AppData\Local\Programs\Python\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "c:\Users\user1\Desktop\import time.py", line 9, in runtime
    timer = timer-1
UnboundLocalError: local variable 'timer' referenced before assignment

How can I fix this? I set the variable timer before the thread runs, so why isn't it assigned already?

Body:
Here's how you can handle input with a timer:

from signal import signal, alarm, SIGALRM

TIMEOUT = 5

def get_answer(timeout):
    def handler(*args):
        raise Exception('Timeout')
    signal(SIGALRM, handler)
    alarm(timeout)
    try:
        return input ("ANSWER THE QUESTION!!! ")
    except Exception:
        pass
    finally:
        alarm(0)

print(get_answer(TIMEOUT))

So, no threads here. If no input within TIMEOUT seconds the get_answer() function will return None. Otherwise it will return the user input.


问:
R : How to iterate sum across multiple columns?
I am trying to iterate/loop a sum across multiple non-consecutive columns. My objective is to compute the subscale score of multiple questionnaires measured repeatedly across time.

Dataset for one questionnaire of x items and n time-points:

```<code>df <- tibble(
  ID = 1:5,
  itemA_1 = sample(100, 5, TRUE),
  itemB_1 = sample(100, 5, TRUE),
  itemC_1 = sample(100, 5, TRUE),
  itemD_1 = sample(100, 5, TRUE),
  itemx_1 = sample(100, 5, TRUE),
  itemA_3 = sample(100, 5, TRUE),
  itemB_3 = sample(100, 5, TRUE),
  itemC_3 = sample(100, 5, TRUE),
  itemD_3 = sample(100, 5, TRUE),
  itemx_3 = sample(100, 5, TRUE),
  itemA_n = sample(100, 5, TRUE),
  itemB_n = sample(100, 5, TRUE),
  itemC_n = sample(100, 5, TRUE),
  itemD_n = sample(100, 5, TRUE),
  itemx_n = sample(100, 5, TRUE),
)
</code>```

The sum for one specific time point works just fine:

```<code>df %>% mutate(total_1 = sum(c(itemA_1, itemC_1, itemD_1))
</code>```

This loop does not work:

```<code>for (i in c(1, 3, n)) {
    df %>% mutate(total_i = sum(c(itemA_i, itemC_i, itemD_i))
    }
</code>```

What am I doing wrong?

答:
We may reshape to 'long' format with pivot_longer and do a group by sum

```<code>library(dplyr)
library(tidyr)
df1 <- df %>%
   pivot_longer(cols =-ID, names_to = c("item", ".value"), names_sep = "_") %>%
  filter(item %in% c("itemA", "itemC", "itemD")) %>%
  group_by(ID) %>%
  summarise(across(where(is.numeric), sum, na.rm = TRUE,
       .names = "total_{.col}")) %>%
  left_join(df, .)
</code>```

-output

```<code>> df1
# A tibble: 5 × 19
     ID itemA_1 itemB_1 itemC_1 itemD_1 itemx_1 itemA_3 itemB_3 itemC_3 itemD_3 itemx_3 itemA_n itemB_n itemC_n itemD_n itemx_n total_1
  <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>
1     1      69      27      56      44      54      53      66      28      67      19      65      38      12      45      33     250
2     2      31      65       7      34      84      19      64      70      27      23      98      65      94      71     100     221
3     3      58      34      68      18      69     100      24      47      54      60      47      48      81      61      22     247
4     4      95      16      85      34       9      28      73      57      79      60      57      31      16      24      84     239
5     5      19      66      43      25      35      31      39      17      15      84      10      23     100       6      74     188
# … with 2 more variables: total_3 <int>, total_n <int>
</code>```

If we want to use the for loop, then paste the column names with i, evaluate (!!) while assigning (:=)

```<code>library(stringr)
for (i in c(1, 3, 'n')) {
     df <- df %>%
   mutate(!! str_c("total_", i) :=
      rowSums(across(all_of(str_c(c("itemA_", "itemC_", "itemD_"), i)))))
     }
</code>```

But, note that this will not be dynamic as we have to manually include the 1, 2, ..., n in the loop

-checking the output from for loop and reshaping

```<code>> all.equal(df1$total_1, df$total_1)
[1] TRUE
> all.equal(df1$total_3, df$total_3)
[1] TRUE
> all.equal(df1$total_n, df$total_n)
[1] TRUE
</code>```

Body:
I am trying to iterate/loop a sum across multiple non-consecutive columns. My objective is to compute the subscale score of multiple questionnaires measured repeatedly across time.

Dataset for one questionnaire of x items and n time-points:

df <- tibble(
  ID = 1:5,
  itemA_1 = sample(100, 5, TRUE),
  itemB_1 = sample(100, 5, TRUE),
  itemC_1 = sample(100, 5, TRUE),
  itemD_1 = sample(100, 5, TRUE),
  itemx_1 = sample(100, 5, TRUE),
  itemA_3 = sample(100, 5, TRUE),
  itemB_3 = sample(100, 5, TRUE),
  itemC_3 = sample(100, 5, TRUE),
  itemD_3 = sample(100, 5, TRUE),
  itemx_3 = sample(100, 5, TRUE),
  itemA_n = sample(100, 5, TRUE),
  itemB_n = sample(100, 5, TRUE),
  itemC_n = sample(100, 5, TRUE),
  itemD_n = sample(100, 5, TRUE),
  itemx_n = sample(100, 5, TRUE),
)

The sum for one specific time point works just fine:

df %>% mutate(total_1 = sum(c(itemA_1, itemC_1, itemD_1))

This loop does not work:

for (i in c(1, 3, n)) {
    df %>% mutate(total_i = sum(c(itemA_i, itemC_i, itemD_i))
    }

What am I doing wrong?

Body:
We may reshape to 'long' format with pivot_longer and do a group by sum

library(dplyr)
library(tidyr)
df1 <- df %>%
   pivot_longer(cols =-ID, names_to = c("item", ".value"), names_sep = "_") %>%
  filter(item %in% c("itemA", "itemC", "itemD")) %>%
  group_by(ID) %>%
  summarise(across(where(is.numeric), sum, na.rm = TRUE,
       .names = "total_{.col}")) %>%
  left_join(df, .)

-output

> df1
# A tibble: 5 × 19
     ID itemA_1 itemB_1 itemC_1 itemD_1 itemx_1 itemA_3 itemB_3 itemC_3 itemD_3 itemx_3 itemA_n itemB_n itemC_n itemD_n itemx_n total_1
  <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>   <int>
1     1      69      27      56      44      54      53      66      28      67      19      65      38      12      45      33     250
2     2      31      65       7      34      84      19      64      70      27      23      98      65      94      71     100     221
3     3      58      34      68      18      69     100      24      47      54      60      47      48      81      61      22     247
4     4      95      16      85      34       9      28      73      57      79      60      57      31      16      24      84     239
5     5      19      66      43      25      35      31      39      17      15      84      10      23     100       6      74     188
# … with 2 more variables: total_3 <int>, total_n <int>

If we want to use the for loop, then paste the column names with i, evaluate (!!) while assigning (:=)

library(stringr)
for (i in c(1, 3, 'n')) {
     df <- df %>%
   mutate(!! str_c("total_", i) :=
      rowSums(across(all_of(str_c(c("itemA_", "itemC_", "itemD_"), i)))))
     }

But, note that this will not be dynamic as we have to manually include the 1, 2, ..., n in the loop

-checking the output from for loop and reshaping

> all.equal(df1$total_1, df$total_1)
[1] TRUE
> all.equal(df1$total_3, df$total_3)
[1] TRUE
> all.equal(df1$total_n, df$total_n)
[1] TRUE


问:
Transparent Texture With OpenGL-ES 2.0
I am trying to add a transparent texture on top a cube. Only the front face is not transparent. Other sides are transparent. What could be the problem?. Any help is appreciated.

EDIT : I found that the face which is drawn first is opaque.

3 face of the cube is drawn.

Opaque face.((This face's index is given first in GLdrawElements))

Transparent face.

答:
You most probably ran into a sorting problem. To display transparent geometries correctly the faces of the object have to be sorted from back to front.

Unfortunately there is no built-in support for that in opengl-es (or in any gfx-library in existance). The only possibility is to sort your polygons, recreate your object each frame and draw it with correctly ordered faces.

A workaround would be using additive transparency instead of normal transparency. Additive transparency is an order independent calculation. You have to remember to turn off z-buffer writes while drawing because otherwise some geometry may be ocluded.

Additive transparency is achieved by setting both blendfunc values to GL_ONE.

Title: Transparent Texture With OpenGL-ES 2.0