问:
maven-compiler-plugin: add extra dependency for incremental build
I want to construct a java class file with a class with a long, multi-line string constant. (The usual way of putting the string into a separate file and load it from the same JAR as the class is not an option. There won't be a JAR, only that class file.) Originally, I was using the multiline-string annotation-processor, it allows to place the string content in a doc comment:

/**
 * This will be the actual
 * content of the string
**/
@Multiline static final String foo = "this literal is ignored";
```

Here I mistakenly thought: "oh, comments are inconvenient, why not change multiline-string to load the content from an external file?" It turns out that this works, but maven (which I'm using for building), does of course not understand that the class file needs to be recompiled if the file read by the annotation processor is changed.

Approaches:

set useIncrementalCompilation to false: Does not at all do what I would expect, instead disables dependency checking for incremental builds

add .py to fileExtensions (didn't expect that to work)

add the maven-clean-plugin as part of the initialization phase: This works, but it is a bit overkill…

What I'd really like to do is to add the path of the embedded file to maven's list of "if this file changes, recompile that file". Is that possible, or is there another, elegant way of solving this?

答:
Maybe this is not a full answer, but just my thoughts on the above:

Annotation processors in java usually are not intended for changing the existing classes.

Yes, there is Lombok, that kind of breaks this assumption, but the price is using some internal compiler internal APIs and "Manually" compiling the modified AST:

This is also written in this tutorial for example.

Usually annotation processors can create some descriptors, like JSON or files, or, alternatively new Java sources, but they never (again with the exception of lombok) modify the existing sources.

If I've got you correctly, you wrote your own annotation processor for multi-line handling like the one that you've provided in the first link, but this kind of incompatible with the idea of annotation processors, so I doubt maven can help you out here.

Body:
I want to construct a java class file with a class with a long, multi-line string constant. (The usual way of putting the string into a separate file and load it from the same JAR as the class is not an option. There won't be a JAR, only that class file.) Originally, I was using the multiline-string annotation-processor, it allows to place the string content in a doc comment:

/**
 * This will be the actual
 * content of the string
**/
@Multiline static final String foo = "this literal is ignored";

Here I mistakenly thought: "oh, comments are inconvenient, why not change multiline-string to load the content from an external file?" It turns out that this works, but maven (which I'm using for building), does of course not understand that the class file needs to be recompiled if the file read by the annotation processor is changed.

Approaches:

set useIncrementalCompilation to false: Does not at all do what I would expect, instead disables dependency checking for incremental builds

add .py to fileExtensions (didn't expect that to work)

add the maven-clean-plugin as part of the initialization phase: This works, but it is a bit overkill…

What I'd really like to do is to add the path of the embedded file to maven's list of "if this file changes, recompile that file". Is that possible, or is there another, elegant way of solving this?


来源: stackexchange

问:
Promisify without object instance
We can promisify mysql pool getConnection function if we have already created the pool, like this:

```<code>const mysql = require('mysql');
const util = require('util');

const mysqlPool = mysql.createPool(CONFIG);

const getConnectionPm = util.promisify(mysqlPool.getConnection).bind(mysqlPool);
</code>```

And the usage can be something like:

```<code>(async() => {
    const connection = await mysqlPool.getConnectionPm();

});
</code>```

How can I promisify the mysqlPool.getConnection.query function to use connection variable? To make something like this:

```<code>(async() => {
    const connection = await mysqlPool.getConnectionPm();

    const result = await connection.queryPm(SQL_QUERY, SQL_ARGS);
});
</code>```

The problem is that I don't know how to pass the connection variable to the promisify function. I guess one different way is to create a connection object with getConnectionPm function, then bind the query to that object like what we did to promisify the getConnection itself. But how we can achieve something like the code above?

For example, the code below gives an undefined error:

```<code>const getConnectionPm = util.promisify(mysql.createPool.getConnection);
</code>```

答:
You can change your getConnectionPm, and add a queryPM promisified query method to each connection.

const getConnectionPm = async () => {
    const conn = await util.promisify(mysqlPool.getConnection).call(mysqlPool);
    conn.queryPm = util.promisify(conn.query).bind(conn);
    return conn;
}
```

<p>Then you can query as in your example.</p>

<pre class="lang-js prettyprint-override"><code>(async() => {
    const connection = await mysqlPool.getConnectionPm();
    const result = await connection.queryPm(SQL_QUERY, SQL_ARGS);
});
</code>```

ContentLicense: CC BY-SA 4.0

Title: Promisify without object instance

Body:
We can promisify mysql pool getConnection function if we have already created the pool, like this:

const mysql = require('mysql');
const util = require('util');

const mysqlPool = mysql.createPool(CONFIG);

const getConnectionPm = util.promisify(mysqlPool.getConnection).bind(mysqlPool);

And the usage can be something like:

(async() => {
    const connection = await mysqlPool.getConnectionPm();

});

How can I promisify the mysqlPool.getConnection.query function to use connection variable? To make something like this:

(async() => {
    const connection = await mysqlPool.getConnectionPm();

    const result = await connection.queryPm(SQL_QUERY, SQL_ARGS);
});

The problem is that I don't know how to pass the connection variable to the promisify function. I guess one different way is to create a connection object with getConnectionPm function, then bind the query to that object like what we did to promisify the getConnection itself. But how we can achieve something like the code above?

For example, the code below gives an undefined error:

const getConnectionPm = util.promisify(mysql.createPool.getConnection);

Body:
You can change your getConnectionPm, and add a queryPM promisified query method to each connection.

const getConnectionPm = async () => {
    const conn = await util.promisify(mysqlPool.getConnection).call(mysqlPool);
    conn.queryPm = util.promisify(conn.query).bind(conn);
    return conn;
}

Then you can query as in your example.

(async() => {
    const connection = await mysqlPool.getConnectionPm();
    const result = await connection.queryPm(SQL_QUERY, SQL_ARGS);
});


问:
How can I add an empty row in a for loop based on a previous for loop?
I'm trying to make a comparison report that displays sales for two time periods, in this scenario i've selected 1-31 October and 1-30th November. I am loading the data from the same Json file but as two seperate queries, the first uses the October period and the second uses the November period.

This is the code I have currently:

```<code>// October 1-31
<div class="col-6" *ngFor="let periods of reportData">
    <div *ngFor="let reportVal of periods.groupedTransactions">
        <div class="row" *ngIf="reportData.length > 0">
            <div class="col-12">
                <h6>Customer: {{reportVal.name}}</h6>
            </div>
            <div class="col">
                <h6>Total Sales: {{reportVal.totalSales | number}}</h6>
            </div>
        </div>
    </div>
</div>
// November 1-30
<div class="col-6" *ngFor="let comPeriods of comReportData">
    <div *ngFor="let reportVal of comPeriods.groupedTransactions">
        <div class="row" *ngIf="comReportData.length > 0">
            <div class="col-12">
                <h6>Customer: {{reportVal.name}}</h6>
            </div>
            <div class="col">
                <h6>Total Sales: {{reportVal.totalSales | number}}</h6>
            </div>
        </div>
    </div>
</div>
</code>```

And this is the result:

Is there a way to add a function that will add an empty row in the November if there is no sales from that customer? I want to have all the Customers vertically aligned.

Because the periods for loop is based on the selected dates, putting the columns in the same loop will only get data from one date.

If anyone can help me out or tell me where to look to solve this it would be greatly appreciated!

答:
Hope this helps... If this is not the expected result you want to display, Please share the json  format.

customer.component.html

```<code><div class="container">
<h2>Customer Sales</h2>
<p>The below table is listing monthly sales of the customer in the year 2019 </p>
<div *ngFor="let report of reportData">
    <h5>Month: {{report.month}}</h5>
    <table class="table">
        <thead>
            <tr>
                <th>Customer</th>
                <th>Total Sales</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let sales of report.groupedTransactions">
                <td>{{sales.name}}</td>
                <td>{{sales.totalSales}}</td>
            </tr>
        </tbody>
    </table>
</div>
</code>```

customer.component.ts

```<code>ngOnInit() {

this.reportData = [
  {
    month: 'October',
    groupedTransactions: [
      {
        name: 'John',
        totalSales: 100
      },
      {
        name: 'Rita',
        totalSales: 80
      },
      {
        name: 'Edward',
        totalSales: 70
      },
    ]
  },
  {
    month: 'November',
    groupedTransactions: [
      {
        name: 'John',
        totalSales: 90
      },
      {
        name: 'Rita',
        totalSales: null
      },
      {
        name: 'Edward',
        totalSales: 120
      },
    ]
  }
]
</code>```

}

}
    }

Body:
I'm trying to make a comparison report that displays sales for two time periods, in this scenario i've selected 1-31 October and 1-30th November. I am loading the data from the same Json file but as two seperate queries, the first uses the October period and the second uses the November period.

This is the code I have currently:

// October 1-31

 0">

Customer: {{reportVal.name}}

Total Sales: {{reportVal.totalSales | number}}

// November 1-30

 0">

Customer: {{reportVal.name}}

Total Sales: {{reportVal.totalSales | number}}

And this is the result:

Is there a way to add a function that will add an empty row in the November if there is no sales from that customer? I want to have all the Customers vertically aligned.

Because the periods for loop is based on the selected dates, putting the columns in the same loop will only get data from one date.

If anyone can help me out or tell me where to look to solve this it would be greatly appreciated!

Body:
Hope this helps... If this is not the expected result you want to display, Please share the json  format.

customer.component.html

<div class="container">
<h2>Customer Sales</h2>
<p>The below table is listing monthly sales of the customer in the year 2019 </p>
<div *ngFor="let report of reportData">
    <h5>Month: {{report.month}}</h5>
    <table class="table">
        <thead>
            <tr>
                <th>Customer</th>
                <th>Total Sales</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let sales of report.groupedTransactions">
                <td>{{sales.name}}</td>
                <td>{{sales.totalSales}}</td>
            </tr>
        </tbody>
    </table>
</div>

customer.component.ts

ngOnInit() {

this.reportData = [
  {
    month: 'October',
    groupedTransactions: [
      {
        name: 'John',
        totalSales: 100
      },
      {
        name: 'Rita',
        totalSales: 80
      },
      {
        name: 'Edward',
        totalSales: 70
      },
    ]
  },
  {
    month: 'November',
    groupedTransactions: [
      {
        name: 'John',
        totalSales: 90
      },
      {
        name: 'Rita',
        totalSales: null
      },
      {
        name: 'Edward',
        totalSales: 120
      },
    ]
  }
]

}

}
    }


问:
How verify mysql database connection from another file php
I've created a form where the user can add his database name, username, password, host. then that form creates a config file and adds the user database details. the form is in root and the config file is in root/includes. I want to know how can I verify database connection from form file. if the connection is successful he can proceed to the next step and if it's not I want to show the error.

Form

```<code>if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['db-details']) {

    $dbName = $_POST['dbName'];
    $dbUsername = $_POST['dbUsername'];
    $dbPassword = $_POST['dbPassword'];
    $dbHost = $_POST['dbHost'];

    $phConfigFile = 'includes/ph_config.php';

    file_put_contents($phConfigFile, $phConfigData);

}
</code>```

Config

```<code><?php

    define("DB_HOST", "[dbHost]");

    define("DB_USER", "[dbUsername]");

    define("DB_PASS", "[dbPassword]");

    define("DB_NAME", "[dbName]");

    $connection = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
</code>```

答:
This is the same as RiggsFolly answer, but improved.

```<code>if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['db-details'])) {
    try {
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $connection = new mysqli(
            $_POST['dbHost'],
            $_POST['dbUsername'],
            $_POST['dbPassword'],
            $_POST['dbName']
        );

        $DBconfig = [
            'dbHost' => $_POST['dbHost'],
            'dbUsername' => $_POST['dbUsername'],
            'dbPassword' => $_POST['dbPassword'],
            'dbName' => $_POST['dbName']
        ];

        // generate the config file
        $contents = '<?php' . PHP_EOL;
        $contents .= '$DBconfig = ' . var_export($DBconfig, true) . ';' . PHP_EOL;
        $contents .= 'mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);' . PHP_EOL;
        $contents .= '$connection = new mysqli(
            $DBconfig["dbHost"],
            $DBconfig["dbUsername"],
            $DBconfig["dbPassword"],
            $DBconfig["dbName"]
        );';
        echo $contents;
    } catch (\Exception $e) {
        // echo error message here and show the same form.
    }
}
</code>```

Basically, you should avoid the error suppression operator at all cost. Thankfully PHP has exceptions, which can be caught and handled.

If there's no exception you can put the connection details in an array and then export that array into a string. Generate the connection file and save it.

Another thing I would improve is to encapsulate this in a function to prevent the config details spilling out.

```<code>// generate the config file
$contents = '<?php' . PHP_EOL;
$contents .= 'function db_connect():\mysqli { '. PHP_EOL;
$contents .= '$DBconfig = ' . var_export($DBconfig, true) . ';' . PHP_EOL;
$contents .= 'mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);' . PHP_EOL;
$contents .= 'return new mysqli(
    $DBconfig["dbHost"],
    $DBconfig["dbUsername"],
    $DBconfig["dbPassword"],
    $DBconfig["dbName"]
);';
$contents .= PHP_EOL;
$contents .= '}'.PHP_EOL;
$contents .= '$connection = db_connect();'.PHP_EOL;
echo $contents;
</code>```

Body:
I've created a form where the user can add his database name, username, password, host. then that form creates a config file and adds the user database details. the form is in root and the config file is in root/includes. I want to know how can I verify database connection from form file. if the connection is successful he can proceed to the next step and if it's not I want to show the error.

Form

if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['db-details']) {

    $dbName = $_POST['dbName'];
    $dbUsername = $_POST['dbUsername'];
    $dbPassword = $_POST['dbPassword'];
    $dbHost = $_POST['dbHost'];

    $phConfigFile = 'includes/ph_config.php';

    file_put_contents($phConfigFile, $phConfigData);

}

Config

<?php

    define("DB_HOST", "[dbHost]");

    define("DB_USER", "[dbUsername]");

    define("DB_PASS", "[dbPassword]");

    define("DB_NAME", "[dbName]");

    $connection = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);

Body:
This is the same as RiggsFolly answer, but improved.

if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['db-details'])) {
    try {
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        $connection = new mysqli(
            $_POST['dbHost'],
            $_POST['dbUsername'],
            $_POST['dbPassword'],
            $_POST['dbName']
        );

        $DBconfig = [
            'dbHost' => $_POST['dbHost'],
            'dbUsername' => $_POST['dbUsername'],
            'dbPassword' => $_POST['dbPassword'],
            'dbName' => $_POST['dbName']
        ];

        // generate the config file
        $contents = '<?php' . PHP_EOL;
        $contents .= '$DBconfig = ' . var_export($DBconfig, true) . ';' . PHP_EOL;
        $contents .= 'mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);' . PHP_EOL;
        $contents .= '$connection = new mysqli(
            $DBconfig["dbHost"],
            $DBconfig["dbUsername"],
            $DBconfig["dbPassword"],
            $DBconfig["dbName"]
        );';
        echo $contents;
    } catch (\Exception $e) {
        // echo error message here and show the same form.
    }
}

Basically, you should avoid the error suppression operator at all cost. Thankfully PHP has exceptions, which can be caught and handled.

If there's no exception you can put the connection details in an array and then export that array into a string. Generate the connection file and save it.

Another thing I would improve is to encapsulate this in a function to prevent the config details spilling out.

// generate the config file
$contents = '<?php' . PHP_EOL;
$contents .= 'function db_connect():\mysqli { '. PHP_EOL;
$contents .= '$DBconfig = ' . var_export($DBconfig, true) . ';' . PHP_EOL;
$contents .= 'mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);' . PHP_EOL;
$contents .= 'return new mysqli(
    $DBconfig["dbHost"],
    $DBconfig["dbUsername"],
    $DBconfig["dbPassword"],
    $DBconfig["dbName"]
);';
$contents .= PHP_EOL;
$contents .= '}'.PHP_EOL;
$contents .= '$connection = db_connect();'.PHP_EOL;
echo $contents;


问:
Standalone Spring JtaTransactionManager not working with WAS
I am trying to use Spring JtaTransactionManager (WebSphereUowTransactionManager) in a standalone program with WAS9.0. The JndiTemplate is retrieved with a Jndi lookup and set to the spring JtaTransactionManager. The dataSource and JMS resources which are XA complaint are also retrieved from a Jndi lookup to the server. The problem I face here is that the operation performed in the transaction block is getting committed immediately . Looks like the resources are not managed by the transaction manager. The client program has all the WAS runtimes libraries in the classpath

Appreciate if anyone could help here and guide how we could make WebSphereUowTransactionManager work from outside a container.

```<code>applicationContext_Jta.xml:
<bean id="jndiTemplateLookUp" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.provider.url">iiop://ip:port</prop>
            <prop key="java.naming.factory.initial">com.ibm.websphere.naming.WsnInitialContextFactory</prop>
        </props>
    </property>
</bean>

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplateLookUp"/>
    <property name="jndiName" value="jdbc/WSDataSource"/>
</bean>

Main Code:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
ApplicationContext jtaApplicationCtx = new ClassPathXmlApplicationContext("applicationContext_Jta.xml");
JndiTemplate jndiTemplate = (JndiTemplate) jtaApplicationCtx.getBean("jndiTemplateLookUp");
DataSource datasource = (DataSource) jtaApplicationCtx.getBean("dataSource");

JtaTransactionManager transactionManager = new WebSphereUowTransactionManager();
transactionManager.setJndiTemplate(jndiTemplate);
transactionManager.afterPropertiesSet();

((CallbackPreferringPlatformTransactionManager) transactionManager).execute(transactionDefinition,
                new TransactionCallback<Integer>() {
 @Override
 public Integer doInTransaction(TransactionStatus transactionStatus) {

 //DB SQL Execute

 //JMS Send

 return 0;
 }
 });
</code>```

答:
I have also had problems with this TransactionManager with Liberty Websphere. I ended up forcing the DataSourceTransactionManager manually, like this:

```<code>@Bean
public PlatformTransactionManager platformTransactionManager(final DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}
</code>```

To me it seems like this functionality is either incompatible with newer versions of websphere, or that it's just plain broken.

Body:
I am trying to use Spring JtaTransactionManager (WebSphereUowTransactionManager) in a standalone program with WAS9.0. The JndiTemplate is retrieved with a Jndi lookup and set to the spring JtaTransactionManager. The dataSource and JMS resources which are XA complaint are also retrieved from a Jndi lookup to the server. The problem I face here is that the operation performed in the transaction block is getting committed immediately . Looks like the resources are not managed by the transaction manager. The client program has all the WAS runtimes libraries in the classpath

Appreciate if anyone could help here and guide how we could make WebSphereUowTransactionManager work from outside a container.

applicationContext_Jta.xml:
<bean id="jndiTemplateLookUp" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.provider.url">iiop://ip:port</prop>
            <prop key="java.naming.factory.initial">com.ibm.websphere.naming.WsnInitialContextFactory</prop>
        </props>
    </property>
</bean>

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplateLookUp"/>
    <property name="jndiName" value="jdbc/WSDataSource"/>
</bean>

Main Code:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
ApplicationContext jtaApplicationCtx = new ClassPathXmlApplicationContext("applicationContext_Jta.xml");
JndiTemplate jndiTemplate = (JndiTemplate) jtaApplicationCtx.getBean("jndiTemplateLookUp");
DataSource datasource = (DataSource) jtaApplicationCtx.getBean("dataSource");

JtaTransactionManager transactionManager = new WebSphereUowTransactionManager();
transactionManager.setJndiTemplate(jndiTemplate);
transactionManager.afterPropertiesSet();

((CallbackPreferringPlatformTransactionManager) transactionManager).execute(transactionDefinition,
                new TransactionCallback<Integer>() {
 @Override
 public Integer doInTransaction(TransactionStatus transactionStatus) {

 //DB SQL Execute

 //JMS Send

 return 0;
 }
 });

Body:
I have also had problems with this TransactionManager with Liberty Websphere. I ended up forcing the DataSourceTransactionManager manually, like this:

@Bean
public PlatformTransactionManager platformTransactionManager(final DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

To me it seems like this functionality is either incompatible with newer versions of websphere, or that it's just plain broken.


问:
How to handle pop up window dialog to download file automatically with firefox profile in python selenium on Linux (Ubuntu) system
I am trying to download the file automatically from system file download dialog by setting preference in firefox  profile in my python selenium code , but my code is not working.

Browser : Firefox 72.0
Selenium Version : 3.14
OS : linux Ubuntu
Filetype to download: *.enc (encrypted file type)
Path of firefox in linux : /usr/bin/firefox

Code :

```<code>profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.manager.showWhenStarting", False)
profile.set_preference("browser.download.dir", "/home/user/Downloads/tests")
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/x-uuencoded,application/octet-stream")
self.driver = webdriver.Firefox(firefox_profile=profile)
</code>```

答:
Hi @Sum i have resolving, my problem was a different Content-Type.

Use this example to resolve your problem , and to understand your Content-Type: https://stackoverflow.com/a/36356422/12911814

In my case the Content-Type was "application/force-download" not "application/pdf"

```<code>    profile.set_preference("pdfjs.disabled", True)
    profile.set_preference("browser.download.folderList",2)
    profile.set_preference("browser.download.manager.useWindow", False)
    profile.set_preference("browser.download.dir", "<path>")
    profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf, application/force-download")
</code>```

These settings worked for me. Hope it might help you.

Body:
I am trying to download the file automatically from system file download dialog by setting preference in firefox  profile in my python selenium code , but my code is not working.

Browser : Firefox 72.0
Selenium Version : 3.14
OS : linux Ubuntu
Filetype to download: *.enc (encrypted file type)
Path of firefox in linux : /usr/bin/firefox

Code :

profile = webdriver.FirefoxProfile()
profile.set_preference("browser.download.folderList", 2)
profile.set_preference("browser.download.manager.showWhenStarting", False)
profile.set_preference("browser.download.dir", "/home/user/Downloads/tests")
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/x-uuencoded,application/octet-stream")
self.driver = webdriver.Firefox(firefox_profile=profile)

Body:
Hi @Sum i have resolving, my problem was a different Content-Type.

Use this example to resolve your problem , and to understand your Content-Type: https://stackoverflow.com/a/36356422/12911814

In my case the Content-Type was "application/force-download" not "application/pdf"

    profile.set_preference("pdfjs.disabled", True)
    profile.set_preference("browser.download.folderList",2)
    profile.set_preference("browser.download.manager.useWindow", False)
    profile.set_preference("browser.download.dir", "<path>")
    profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf, application/force-download")

These settings worked for me. Hope it might help you.


问:
Bash: how to do string replacements in function?
I wrote a bash script with a curl statement and many sed statements after that. I would like to move all the sed replacements in a fucntion so that the curl statement looks better. How can I pass a parameter? Should I store the result of curl in a variable? And how does return in function work?</p>

```<code>function do_replacements () {

}

curl -s http.... | do_replacements > target.txt
</code>```

答:
You could ignore stderr to prevent printing of the transfer summary and read from stdin in the function:

```<code>do_replacements() {
  sed 's/foo/bar/g;s/abc/def/g'
}

curl http://… 2>/dev/null | do_replacements > target.txt
</code>```

There is no "return" value as such, the function prints the modified result to stdout and this output is then redirected to target.txt.

Body:
I wrote a bash script with a curl statement and many sed statements after that. I would like to move all the sed replacements in a fucntion so that the curl statement looks better. How can I pass a parameter? Should I store the result of curl in a variable? And how does return in function work?

function do_replacements () {

}

curl -s http.... | do_replacements > target.txt

Body:
You could ignore stderr to prevent printing of the transfer summary and read from stdin in the function:

do_replacements() {
  sed 's/foo/bar/g;s/abc/def/g'
}

curl http://… 2>/dev/null | do_replacements > target.txt

There is no "return" value as such, the function prints the modified result to stdout and this output is then redirected to target.txt.


问:
Restricting string length in XML Schema
I am new to XML and JAXB, I am trying to add the AdditionalDataDeposit field with restrictions to my XML schema so I can generate the POJO with Maven. When I try to build it in maven the error:

```<code>blahBlahBlahmsgfactory: Unable to parse input schema(s). Error messages should have been provided.
org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name
'LimitedString50' to a(n) 'type definition' component.
</code>```

my code:

Under AdditionalData complex type:

```<code><xs:element name="DEPOSIT" type="trmns:AdditionalDataDEPOSIT" minOccurs="0">
  <xs:annotation>
    <xs:documentation>Additional Deposit Data</xs:documentation>
  </xs:annotation>
</xs:element>
</code>```

then:

```<code>  <xs:complexType name="AdditionalDataDEPOSIT">
    <xs:annotation>
      <xs:documentation>Additional Deposit Data</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="depositorID" type="LimitedString50"/>
      <xs:element name="depositorNationality" type="LimitedString50"/>
      <xs:element name="fundSource" type="LimitedString50"/>
      <xs:element name="fullName" type="LimitedString100"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="LimitedString50">
    <xs:restriction base="xs:string">
      <xs:maxLength value="50" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="LimitedString100">
    <xs:restriction base="xs:string">
      <xs:maxLength value="100" />
    </xs:restriction>
  </xs:simpleType>
</code>```

I dont understand much of XML Schema's, but advice will be appreciated.

答:
```<code><xs:complexType name="AdditionalDataDEPOSIT">
    <xs:annotation>
      <xs:documentation>Additional Deposit Data</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="depositorID" type="trmns:LimitedStringFifty"/>
      <xs:element name="depositorNationality" type="trmns:LimitedStringFifty"/>
      <xs:element name="fundSource" type="trmns:LimitedStringFifty"/>
      <xs:element name="fullName" type="trmns:LimitedStringHundred"/>
    </xs:sequence>
  </xs:complexType>
    <xs:simpleType name="LimitedStringFifty">
      <xs:restriction base="xs:string">
        <xs:maxLength value="50" />
      </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="LimitedStringHundred">
      <xs:restriction base="xs:string">
        <xs:maxLength value="100" />
      </xs:restriction>
    </xs:simpleType>
</code>```

Adding trmns: to the prefix of my type seemed to work, I'm not entirely sure why, maybe somebody here could explain. Posting to assist others.

Title: Restricting string length in XML Schema

Body:
I am new to XML and JAXB, I am trying to add the AdditionalDataDeposit field with restrictions to my XML schema so I can generate the POJO with Maven. When I try to build it in maven the error:

blahBlahBlahmsgfactory: Unable to parse input schema(s). Error messages should have been provided.
org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name
'LimitedString50' to a(n) 'type definition' component.

my code:

Under AdditionalData complex type:

<xs:element name="DEPOSIT" type="trmns:AdditionalDataDEPOSIT" minOccurs="0">
  <xs:annotation>
    <xs:documentation>Additional Deposit Data</xs:documentation>
  </xs:annotation>
</xs:element>

then:

  <xs:complexType name="AdditionalDataDEPOSIT">
    <xs:annotation>
      <xs:documentation>Additional Deposit Data</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="depositorID" type="LimitedString50"/>
      <xs:element name="depositorNationality" type="LimitedString50"/>
      <xs:element name="fundSource" type="LimitedString50"/>
      <xs:element name="fullName" type="LimitedString100"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="LimitedString50">
    <xs:restriction base="xs:string">
      <xs:maxLength value="50" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="LimitedString100">
    <xs:restriction base="xs:string">
      <xs:maxLength value="100" />
    </xs:restriction>
  </xs:simpleType>

I dont understand much of XML Schema's, but advice will be appreciated.

Body:
<xs:complexType name="AdditionalDataDEPOSIT">
    <xs:annotation>
      <xs:documentation>Additional Deposit Data</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="depositorID" type="trmns:LimitedStringFifty"/>
      <xs:element name="depositorNationality" type="trmns:LimitedStringFifty"/>
      <xs:element name="fundSource" type="trmns:LimitedStringFifty"/>
      <xs:element name="fullName" type="trmns:LimitedStringHundred"/>
    </xs:sequence>
  </xs:complexType>
    <xs:simpleType name="LimitedStringFifty">
      <xs:restriction base="xs:string">
        <xs:maxLength value="50" />
      </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="LimitedStringHundred">
      <xs:restriction base="xs:string">
        <xs:maxLength value="100" />
      </xs:restriction>
    </xs:simpleType>

Adding trmns: to the prefix of my type seemed to work, I'm not entirely sure why, maybe somebody here could explain. Posting to assist others.


问:
Display stored Array Objects to List in Javascript to HTML
I'm Trying to make a list display in HTML of the stored details i put in my object using Javascript.
which should look like this

```<code>name: Tester1 , age: 1
name: Tester2 , age: 2
name: Tester3 , age: 3
</code>```

I used for in loop to display all the inputted objects, but it this happened

```<code>Actual:
name: Tester1 , age: 1name: Tester1 , age: 1name: Tester2 , age: 2name: Tester1 , age: 1name: Tester2 , age: 2name: Tester3 , age: 3
</code>```

Here is the code for the Jascript

```<code>var person = [];
function profile(e) {
    //to stop form from resubmitting
    e.preventDefault();

    var pProfile = {
        name: document.getElementById('name').value,
        age: document.getElementById('age').value
    }
    person.push(pProfile);
    //used to convert result to string
    var myJSON = JSON.stringify(person);

    document.forms[0].reset();

    //display in Final Obejct div
    document.getElementById("fObject").innerHTML = myJSON;

    //display converted objects to
    for (let x in person){
         document.getElementById("rFormat").append("name: " + person[x].name + " , " + "age : " + person[x].age + "<br>");
         console.log(person[x]);
    }
}

</code>```

And this is for the HTML

```<code>    <div id="part1">
        <h3>Part 1</h2>
        <form id="profile" onsubmit="profile(event)" action="#">
            Name: <input type="text" id ="name">
            Age: <input type="text" id ="age">
            <input type="Submit" value="Add">
        </form>

        <h4>Final Object</h4>
        <div id="fObject"></div>

        <h4>Readable Format</h4>
        <div id="rFormat"></div>
    </div>
</code>```

Pretty sure that I did something wrong with the for in loop, but i don't know exactly where.
Please help. I'm new in javascript. Thanks so much.

答:
You need to change the for-loop to use for-of instead of for-in. You need the values and not the keys

```<code>for(let x of person)
</code>```

and then instead of person[x], you already have the object you need so use as below

```<code>.append("name: " + x.name + " , " + "age : " + x.age
</code>```

Body:
I'm Trying to make a list display in HTML of the stored details i put in my object using Javascript.
which should look like this

name: Tester1 , age: 1
name: Tester2 , age: 2
name: Tester3 , age: 3

I used for in loop to display all the inputted objects, but it this happened

Actual:
name: Tester1 , age: 1name: Tester1 , age: 1name: Tester2 , age: 2name: Tester1 , age: 1name: Tester2 , age: 2name: Tester3 , age: 3

Here is the code for the Jascript

var person = [];
function profile(e) {
    //to stop form from resubmitting
    e.preventDefault();

    var pProfile = {
        name: document.getElementById('name').value,
        age: document.getElementById('age').value
    }
    person.push(pProfile);
    //used to convert result to string
    var myJSON = JSON.stringify(person);

    document.forms[0].reset();

    //display in Final Obejct div
    document.getElementById("fObject").innerHTML = myJSON;

    //display converted objects to
    for (let x in person){
         document.getElementById("rFormat").append("name: " + person[x].name + " , " + "age : " + person[x].age + "
");
         console.log(person[x]);
    }
}

And this is for the HTML

Part 1

        <form id="profile" onsubmit="profile(event)" action="#">
            Name: <input type="text" id ="name">
            Age: <input type="text" id ="age">
            <input type="Submit" value="Add">
        </form>

Final Object

Readable Format

Pretty sure that I did something wrong with the for in loop, but i don't know exactly where.
Please help. I'm new in javascript. Thanks so much.

Body:
You need to change the for-loop to use for-of instead of for-in. You need the values and not the keys

for(let x of person)

and then instead of person[x], you already have the object you need so use as below

.append("name: " + x.name + " , " + "age : " + x.age


问:
I get a "Specified method is not supported" error when i try to use ExcelDataReader to upload file to database
I've written a method, BulkCopy, to upload my Excel file to SQL Server database table. I am trying to unit test this and it fails each time with "System.NotSupportedException : Specified method is not supported".

If someone could have a look it would be much appreciated.

Kind regards,

Emmett

```<code>    public static void BulkCopy(string inputFilePath, string tableName)
    {

        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {

                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                    var column = cols.GetValue(0).ToString();

                    if (column.Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 1");
                    }

                    if (column.Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 2");
                    }

                    if (column.Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 3");
                    }

                //continued for column mappings...

                }

                bulkCopy.WriteToServer(reader);
            }
            Console.WriteLine("Copy data to database done (DataReader).");
        }
    }
</code>```

答:
I tested your code ,the issue is showed in the following code ,you reader is incorrect.

```<code>bulkCopy.WriteToServer(reader);
</code>```

Pass the datatable into bulk , try the below code

```<code>public static void BulkCopy(string inputFilePath, string tableName)
    {
        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = System.IO.File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        IExcelDataReader reader;

        if (inputFilePath.EndsWith(".xls"))
            reader = ExcelReaderFactory.CreateBinaryReader(stream);
        else if (inputFilePath.EndsWith(".xlsx"))
            reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        else
            throw new Exception("The file to be processed is not an Excel file");
        var conf = new ExcelDataSetConfiguration
        {
            ConfigureDataTable = _ => new ExcelDataTableConfiguration
            {
                UseHeaderRow = true
            }
        };
        var dataSet = reader.AsDataSet(conf);

        // Now you can get data from each sheet by its index or its "name"
        var dataTable = dataSet.Tables[0];

        using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {
                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                    var column =col.ToString();

                    if (column.Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column1");
                    }

                    if (column.Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column2");
                    }

                    if (column.Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column3");
                    }

                    //continued for column mappings...

                }
                bulkCopy.WriteToServer(dataTable);
            }
            Console.WriteLine("Copy data to database done (DataReader).");
    }
</code>```

Pass the dataReader into bulk, change your foreach part as shown

```<code>               for (var i = 0; i<cols.Count();i++)
                {
                    if (cols[i].ToString().Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column1");
                    }

                    if (cols[i].ToString().Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column2");
                    }

                    if (cols[i].ToString().Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column3");
                    }

                    //continued for column mappings...

                }
</code>```

Body:
I've written a method, BulkCopy, to upload my Excel file to SQL Server database table. I am trying to unit test this and it fails each time with "System.NotSupportedException : Specified method is not supported".

If someone could have a look it would be much appreciated.

Kind regards,

Emmett

    public static void BulkCopy(string inputFilePath, string tableName)
    {

        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {

                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                    var column = cols.GetValue(0).ToString();

                    if (column.Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 1");
                    }

                    if (column.Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 2");
                    }

                    if (column.Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column 3");
                    }

                //continued for column mappings...

                }

                bulkCopy.WriteToServer(reader);
            }
            Console.WriteLine("Copy data to database done (DataReader).");
        }
    }

Body:
I tested your code ,the issue is showed in the following code ,you reader is incorrect.

bulkCopy.WriteToServer(reader);

Pass the datatable into bulk , try the below code

public static void BulkCopy(string inputFilePath, string tableName)
    {
        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
        var stream = System.IO.File.Open(inputFilePath, FileMode.Open, FileAccess.Read);
        IExcelDataReader reader;

        if (inputFilePath.EndsWith(".xls"))
            reader = ExcelReaderFactory.CreateBinaryReader(stream);
        else if (inputFilePath.EndsWith(".xlsx"))
            reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        else
            throw new Exception("The file to be processed is not an Excel file");
        var conf = new ExcelDataSetConfiguration
        {
            ConfigureDataTable = _ => new ExcelDataTableConfiguration
            {
                UseHeaderRow = true
            }
        };
        var dataSet = reader.AsDataSet(conf);

        // Now you can get data from each sheet by its index or its "name"
        var dataTable = dataSet.Tables[0];

        using (var bulkCopy = new SqlBulkCopy(ConnectionString))
            {
                bulkCopy.EnableStreaming = true;
                bulkCopy.DestinationTableName = tableName;
                reader.Read();
                var cols = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetValue(i)).ToArray();
                foreach (var col in cols)
                {
                    var column =col.ToString();

                    if (column.Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column1");
                    }

                    if (column.Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column2");
                    }

                    if (column.Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(column, "Column3");
                    }

                    //continued for column mappings...

                }
                bulkCopy.WriteToServer(dataTable);
            }
            Console.WriteLine("Copy data to database done (DataReader).");
    }

Pass the dataReader into bulk, change your foreach part as shown

               for (var i = 0; i<cols.Count();i++)
                {
                    if (cols[i].ToString().Trim() == "Column 1")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column1");
                    }

                    if (cols[i].ToString().Trim() == "Column 2")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column2");
                    }

                    if (cols[i].ToString().Trim() == "Column 3")
                    {
                        bulkCopy.ColumnMappings.Add(i, "Column3");
                    }

                    //continued for column mappings...

                }


问:
How to get rid of duplicate entries in a comma separated string
I have a comma separated string, how do i remove duplicate entries in the string in a pythonic way.

For example the string "a,a,b" should be changed to "a,b".

答:
Hey just use this Java 8 Syntax:

```<code> String words = "hello,hii,hii,bye,hii,word,World";
        words = Arrays.stream(words.split(",")).distinct().collect(Collectors.joining(","));
</code>```

Output:

```<code>words: hello,hii,bye,word,World
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Hey just use this Java 8 Syntax:

 String words = "hello,hii,hii,bye,hii,word,World";
        words = Arrays.stream(words.split(",")).distinct().collect(Collectors.joining(","));

Output:

words: hello,hii,bye,word,World


问:
how to display a data table with blank rows using jsf 2.0
I'm trying to show a empty datatable with 10 rows on the page load, when i try using the below code, it does not show any rows.

```<code><h:dataTable id="d" value="" bgcolor="#9AC8E6" border="10" cellpadding="5" cellspacing="3" rows="10" width="100%" dir="LTR" frame="hsides" rules="all" >
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Student Number" />
                        </f:facet>
                        <h:inputText value="#{10}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Student Name" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Standard" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Marks" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Percentage" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                </h:dataTable>
</code>```

Need help to display a datatable with blank columns and rows

UPDATE

According to the given solution I tried this way but could not resolve the problem

```<code>   <h:dataTable id="d" value="#{inquiryBean.blankList}" var="emptyBean" bgcolor="#9AC8E6" border="10" cellpadding="5" cellspacing="3" rows="10" width="100%" dir="LTR" frame="hsides" rules="all" >
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Item Number" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.itemNumber}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Material" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.material}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Description" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.description}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Unit" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.unit}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Quantity" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.quantity}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Delivery Date" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.deliveryDate}" > </h:inputText>
                    </h:column>
                </h:dataTable>
</code>```

## Bean Class ##

```<code>//getters and setters
List blankList = new ArrayList();

public List getBlankList() {
    InquiryBean bean = new InquiryBean();
    bean.setItemNumber("");
    bean.setMaterial("");
    bean.setDescription("");
    bean.setQuantity("");
    bean.setUnit("");
    bean.setDeliveryDate(null);
    return blankList;
}
</code>```

Am i missing something????

答:
You need to specify the value for the value attribute (sorry, no pun intended). It's how you specify rows of the dataTable. The way you have it now it's specifying there should no (null) rows in the output table (if it only works).

That's why my suggestion is to declare some bean which would have a 10-elements collection available as some property (if that's your preference). And have an EL expression pointing to this bean's property in the value attribute.

You can take a look at some examples on Internet (take a look at DataTableBean there).

Basically your should:

define a bean (in faces-config.xml if it's a plain JSF)

define a bean implementation class with a 10-element collection

point to this collection using EL expression in the  value attribute of the h:dataTable component.

UPDATE:

Following your update. Now you have a defined what seems a proper bean and its implementing class. However your 'blankList' is an empty collection (as exactly the name indicates). If you want to have 10 rows in the data table you basically need to call add() method on your collection 10 times (or something similar).

Body:
I'm trying to show a empty datatable with 10 rows on the page load, when i try using the below code, it does not show any rows.

<h:dataTable id="d" value="" bgcolor="#9AC8E6" border="10" cellpadding="5" cellspacing="3" rows="10" width="100%" dir="LTR" frame="hsides" rules="all" >
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Student Number" />
                        </f:facet>
                        <h:inputText value="#{10}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Student Name" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Standard" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Marks" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Percentage" />
                        </f:facet>
                        <h:inputText value="" > </h:inputText>
                    </h:column>
                    <h:column>
                </h:dataTable>

Need help to display a datatable with blank columns and rows

UPDATE

According to the given solution I tried this way but could not resolve the problem

   <h:dataTable id="d" value="#{inquiryBean.blankList}" var="emptyBean" bgcolor="#9AC8E6" border="10" cellpadding="5" cellspacing="3" rows="10" width="100%" dir="LTR" frame="hsides" rules="all" >
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Item Number" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.itemNumber}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Material" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.material}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Description" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.description}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Unit" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.unit}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Quantity" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.quantity}" > </h:inputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText style=""value="Delivery Date" />
                        </f:facet>
                        <h:inputText value="#{emptyBean.deliveryDate}" > </h:inputText>
                    </h:column>
                </h:dataTable>

## Bean Class ##

//getters and setters
List blankList = new ArrayList();

public List getBlankList() {
    InquiryBean bean = new InquiryBean();
    bean.setItemNumber("");
    bean.setMaterial("");
    bean.setDescription("");
    bean.setQuantity("");
    bean.setUnit("");
    bean.setDeliveryDate(null);
    return blankList;
}

Am i missing something????


问:
How to get value for a certain key in multidimentionnal php array?
A certain php array give me this :

```<code>myarray{
    0=>array { "key_01"=>"value_01", "key_02"=>"value_02"..."key_0n"=>"value_0n"}
    1=>array { "key_11"=>"value_11", "key_12"=>"value_12"..."key_1n"=>"value_1n"}
    .
    .
    .
    n=>array { "key_n1"=>"value_n1", "key_n2"=>"value_n2"..."key_nn"=>"value_nn"}
}
</code>```

And i would like to get this one array:

```<code>$newarray = {value_01,value_11,value_n1......value_nn}
</code>```

答:
You can get the first value of each sub-array with current or reset:

```<code>$newarray = array_map('current', $array);
</code>```

If you need a certain offset (in this case the first) then get the values from each array re-indexed with integers and then extract column 0:

```<code>$newarray = array_column(array_map('array_values', $array), 0);
</code>```

Body:
A certain php array give me this :

myarray{
    0=>array { "key_01"=>"value_01", "key_02"=>"value_02"..."key_0n"=>"value_0n"}
    1=>array { "key_11"=>"value_11", "key_12"=>"value_12"..."key_1n"=>"value_1n"}
    .
    .
    .
    n=>array { "key_n1"=>"value_n1", "key_n2"=>"value_n2"..."key_nn"=>"value_nn"}
}

And i would like to get this one array:

$newarray = {value_01,value_11,value_n1......value_nn}

Body:
You can get the first value of each sub-array with current or reset:

$newarray = array_map('current', $array);

If you need a certain offset (in this case the first) then get the values from each array re-indexed with integers and then extract column 0:

$newarray = array_column(array_map('array_values', $array), 0);


问:
Infinite looping taking place and not able to update the form control value via global service and finally getting maximum stack size error
```<code><input class="form-control dateicon" maxlength="10" minlength="10" [maxDate]="api.maxDate" name="xyz" (ngModelChange)="def($event,2)"[bsConfig]="{ isAnimated: true ,dateInputFormat: 'DD/MM/YYYY'}" formControlName="abc" bsDatepicker placeholder="DD / MM / YYYY"/>
</code>```

The above code is my ngx bootstrap date picker code and i am triggering a method via ngModelchange.

The below code represents component.ts code:

```<code>def(event,type){
if(type == 2){
 this.globals.stacks.controls['abc'].setValue(event);
}
}
</code>```

Below is my global.ts code:

```<code>   stacks: FormGroup = this.formbuilder.group({
    abc: ['',ValideService.ghi],
    xyz: [''],
  });
</code>```

Below is my validate Service code:

```<code>static ghi(control) {

        let temp = control.value;
        var minDate: any = new Date('09/01/2018');
        var maxDate: any = new Date();
        if (temp == 'undefined' || temp == null || temp == '') {
            return { 'minDatemaxDatereq': true };
        } else if (minDate > temp || maxDate < temp) {//&&

            return { 'minDatemaxDate': true };
        }
        else {
            return null;
        }
    }
</code>```

Whenever i select a particular date from the date picker the def()
method from the component.ts file gets triggered and it iterates for n number of times till i get maximum stack size error.

答:
The value of  this.globals.stacks.controls['abc'] is already set by user from browser and you have subscribed for the (ngModelChange)="def($event,2)" and inside this def method you are again setting up the value manually , which will again call the ngModelChange event  and this goes on until the stack is overflow.

What causes a stack overflow?

A stack overflow occurs when there is a recursive function (a function that calls itself) >without an exit point. The browser (hosting environment) has a maximum stack call that it >can accomodate before throwing a stack error. You can get more details from this link

Instead you can use valueChanges  and do the necessary work but  remove the (ngModelChange) event or else it will again fall under the event loop.

Body:
<input class="form-control dateicon" maxlength="10" minlength="10" [maxDate]="api.maxDate" name="xyz" (ngModelChange)="def($event,2)"[bsConfig]="{ isAnimated: true ,dateInputFormat: 'DD/MM/YYYY'}" formControlName="abc" bsDatepicker placeholder="DD / MM / YYYY"/>

The above code is my ngx bootstrap date picker code and i am triggering a method via ngModelchange.

The below code represents component.ts code:

def(event,type){
if(type == 2){
 this.globals.stacks.controls['abc'].setValue(event);
}
}

Below is my global.ts code:

   stacks: FormGroup = this.formbuilder.group({
    abc: ['',ValideService.ghi],
    xyz: [''],
  });

Below is my validate Service code:

static ghi(control) {

        let temp = control.value;
        var minDate: any = new Date('09/01/2018');
        var maxDate: any = new Date();
        if (temp == 'undefined' || temp == null || temp == '') {
            return { 'minDatemaxDatereq': true };
        } else if (minDate > temp || maxDate < temp) {//&&

            return { 'minDatemaxDate': true };
        }
        else {
            return null;
        }
    }

Whenever i select a particular date from the date picker the def()
method from the component.ts file gets triggered and it iterates for n number of times till i get maximum stack size error.


问:
Distinct repeated timeouts for UIView.animate
The UIKit's UIView.animate() method appears to be useful when implementing many animations. However, I recently ran into a problem while implementing a series of repeated animations with different timeouts.

Suppose, we have a list of images let images: [UIImage] and an image view @IBOutlet weak var presentingImageView: UIImageView!. We want to make it change its image every 3.0 seconds, for that case we would write the following code:

```<code>Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { _ in
    self.index += 1
}

UIView.animate(withDuration: 3.0,
               delay: 0.1,
               options: .repeat,
               animations: {
                   self.presentingImageView.image = images[index]
               })
</code>```

And it would work, but what if we also have an array of durations let durations: [TimeInterval] and we want to change images every duration[index] seconds?

答:
Then nest them and remove repeat

```<code>Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { _ in
    self.index += 1
    guard self.duration.count > index, self.images.count > index else { return }
    UIView.animate(withDuration:self.duration[index],
           delay: 0.1,
           options: .repeat,
    animations: {
            self.presentingImageView.image = self.images[index]
    })
}
</code>```

Body:
The UIKit's UIView.animate() method appears to be useful when implementing many animations. However, I recently ran into a problem while implementing a series of repeated animations with different timeouts.

Suppose, we have a list of images let images: [UIImage] and an image view @IBOutlet weak var presentingImageView: UIImageView!. We want to make it change its image every 3.0 seconds, for that case we would write the following code:

Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { _ in
    self.index += 1
}

UIView.animate(withDuration: 3.0,
               delay: 0.1,
               options: .repeat,
               animations: {
                   self.presentingImageView.image = images[index]
               })

And it would work, but what if we also have an array of durations let durations: [TimeInterval] and we want to change images every duration[index] seconds?

Body:
Then nest them and remove repeat

Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { _ in
    self.index += 1
    guard self.duration.count > index, self.images.count > index else { return }
    UIView.animate(withDuration:self.duration[index],
           delay: 0.1,
           options: .repeat,
    animations: {
            self.presentingImageView.image = self.images[index]
    })
}


问:
Dictionary Initialization with uniqingKeysWith, anonymous closure
I'm trying to understand the uniqingKeysWith initializer for dictionaries but encountering some problems when attempting to use an anonymous closure to specify which value in the tuple to use as unique keys.

```<code>let pairsWithDuplicateKeys = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
let dictionary = Dictionary(pairsWithDuplicateKeys, uniquingKeysWith: {$0.0})
</code>```

This is giving me the error "Contextual closure type '(Int, Int) throws -> Int' expects 2 arguments, but 1 was used in closure body", and I've experimented with adding arguments but I can't figure out what the other argument is that it is refering to.

The non anonymized version below works fine but i'd like to understand the anonymized version.

```<code>let dictionary = Dictionary(pairsWithDuplicateKeys, uniquingKeysWith: {(key, value) in key})
</code>```

答:
The closure in init(_:uniquingKeysWith:) identifies the value of the duplicate keys.

```<code>let pairsWithDuplicateKeys = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
let dict = Dictionary(pairsWithDuplicateKeys) { (first, _) -> Int in
    return first
}
</code>```

Output:

```<code>print(dict) //["a": 1, "b": 2]
</code>```

Another Example:

If you want to add the values of the duplicate keys, the closure goes like,

```<code>let dict = Dictionary(pairsWithDuplicateKeys) { (first, last) -> Int in
    return first + last
}
print(dict) //["a": 4, "b": 6]
</code>```

Read more about it here.

Body:
I'm trying to understand the uniqingKeysWith initializer for dictionaries but encountering some problems when attempting to use an anonymous closure to specify which value in the tuple to use as unique keys.

let pairsWithDuplicateKeys = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
let dictionary = Dictionary(pairsWithDuplicateKeys, uniquingKeysWith: {$0.0})

This is giving me the error "Contextual closure type '(Int, Int) throws -> Int' expects 2 arguments, but 1 was used in closure body", and I've experimented with adding arguments but I can't figure out what the other argument is that it is refering to.

The non anonymized version below works fine but i'd like to understand the anonymized version.

let dictionary = Dictionary(pairsWithDuplicateKeys, uniquingKeysWith: {(key, value) in key})

Body:
The closure in init(_:uniquingKeysWith:) identifies the value of the duplicate keys.

let pairsWithDuplicateKeys = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
let dict = Dictionary(pairsWithDuplicateKeys) { (first, _) -> Int in
    return first
}

Output:

print(dict) //["a": 1, "b": 2]

Another Example:

If you want to add the values of the duplicate keys, the closure goes like,

let dict = Dictionary(pairsWithDuplicateKeys) { (first, last) -> Int in
    return first + last
}
print(dict) //["a": 4, "b": 6]

Read more about it here.


问:
Get inner JSON content as string without deserializing
I've got a file with JSON content like this:

```<code>{
  "Data": {
    "A": {
      "A1": "S",
      "A2": 0.0
    }
  },
  "NoData": "text"
}
</code>```

What I want to achieve is to get the inner json of "Data" as a string. I do not want it to be deserialized as an object. I already tried to deserialize it with Json.NET JsonConvert.DeserializeObject<TestClass> where Test class is defined as

```<code>class Testclass
{
  public string Data {get; set;}
  public string NoData {get; set;}
}
</code>```

But this results in Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: {. Path 'Data', line 2, position 11.

The data in "Data" is cryptographically signed by a remote server and the signature needs to be checked. But I do not necessarily have the same classes the data was serialized with at the clients side. That's why I want to do as few conversions as possible. So deserializing and serializing again may change the original string in "data". All spaces and linebreaks have to stay intact.

答:
```<code>    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApp5
    {
        class Testclass
        {
            public string Data { get; set; }
            public string NoData { get; set; }
        }
        class JsonConverterObjectToString : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return (objectType == typeof(string));
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JToken token = JToken.Load(reader);
                if (token.Type == JTokenType.Object)
                {
                    return token.ToString();
                }
                return null;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                //serializer.Serialize(writer, value);

                //serialize as actual JSON and not string data
                var token = JToken.Parse(value.ToString());
                writer.WriteToken(token.CreateReader());

            }
        }
        class Program
        {

            static void Main(string[] args)
            {
                var json = "{\r\n  \"Data\": {\r\n    \"A\": {\r\n      \"A1\": \"S\",\r\n      \"A2\": 0.0\r\n    }\r\n  },\r\n  \"NoData\": \"text\"\r\n}";
                var jObj = JsonConvert.DeserializeObject<Testclass>(json, new JsonConverterObjectToString());
                var jObjStrin = JsonConvert.SerializeObject(jObj, new JsonConverterObjectToString());
 Console.WriteLine(jObjString);
            }
        }
    }
</code>```

we can able to JToken to string with the same format Please check the image. the Data has serialized again the same format using the same Convertor

Body:
I've got a file with JSON content like this:

{
  "Data": {
    "A": {
      "A1": "S",
      "A2": 0.0
    }
  },
  "NoData": "text"
}

What I want to achieve is to get the inner json of "Data" as a string. I do not want it to be deserialized as an object. I already tried to deserialize it with Json.NET JsonConvert.DeserializeObject<TestClass> where Test class is defined as

class Testclass
{
  public string Data {get; set;}
  public string NoData {get; set;}
}

But this results in Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: {. Path 'Data', line 2, position 11.

The data in "Data" is cryptographically signed by a remote server and the signature needs to be checked. But I do not necessarily have the same classes the data was serialized with at the clients side. That's why I want to do as few conversions as possible. So deserializing and serializing again may change the original string in "data". All spaces and linebreaks have to stay intact.

Body:
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApp5
    {
        class Testclass
        {
            public string Data { get; set; }
            public string NoData { get; set; }
        }
        class JsonConverterObjectToString : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return (objectType == typeof(string));
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JToken token = JToken.Load(reader);
                if (token.Type == JTokenType.Object)
                {
                    return token.ToString();
                }
                return null;
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                //serializer.Serialize(writer, value);

                //serialize as actual JSON and not string data
                var token = JToken.Parse(value.ToString());
                writer.WriteToken(token.CreateReader());

            }
        }
        class Program
        {

            static void Main(string[] args)
            {
                var json = "{\r\n  \"Data\": {\r\n    \"A\": {\r\n      \"A1\": \"S\",\r\n      \"A2\": 0.0\r\n    }\r\n  },\r\n  \"NoData\": \"text\"\r\n}";
                var jObj = JsonConvert.DeserializeObject<Testclass>(json, new JsonConverterObjectToString());
                var jObjStrin = JsonConvert.SerializeObject(jObj, new JsonConverterObjectToString());
 Console.WriteLine(jObjString);
            }
        }
    }

we can able to JToken to string with the same format Please check the image. the Data has serialized again the same format using the same Convertor


问:
Travis deploy script multiline command
I have following deploy script in Travis file and facing problem with multiline command. I've tried lots of combination and couldn't find a proper solution. If I extract it to the file and call it from script attribute, it works properly but our aim is to put all the commands in the script attribute as multiline command.

```<code>deploy:
  - provider: script
    skip_cleanup: true
    script: mvn deploy -B -DskipTests -Dbuild.number="$TRAVIS_BUILD_NUMBER"
    on:
      tags: false
      branch: dev

  - provider: script
    skip_cleanup: true
    script:
      pip install something &&
      another-command &&
      yet-another-command &&
      docker push "image-name"
    on:
      tags: false
      all_branches: true

</code>```

Here is the error logs:

```<code>sh: 1: Syntax error: "&&" unexpected
</code>```

If someone knows how to define multiline commands, I will be appreciated. Thanks in advance.

答:
TLDR

The example you gave in description looks legit from a YAML perspective. Please make sure you don't have empty lines or comments which prevents the content in script section from becoming one string

Longer version

The script provider in deploy requires the script content being single string. Only one line is allowed so you can't use YAML array.

This is different from the top level script section. Top level script section allows you to use YAML array which means you can supply multiple single line strings leading with -

Having that said, any YAML single line (without line ending) can be used properly in deploy's script section. Here are some examples

```<code>script: pip install something &&
      another-command &&
      yet-another-command &&
      docker push "image-name"
</code>```

```<code># >- to removing the ending new line
script: >-
      pip install something &&
      another-command &&
      yet-another-command &&
      docker push "image-name"
</code>```

The example below will not work for deploy's script section, but will work for top level script section

```<code># Only works in top level script not deploy script
script:
    - pip install something && another-command
    - yet-another-command
    - docker push "image-name"
</code>```

Title: Travis deploy script multiline command

Body:
I have following deploy script in Travis file and facing problem with multiline command. I've tried lots of combination and couldn't find a proper solution. If I extract it to the file and call it from script attribute, it works properly but our aim is to put all the commands in the script attribute as multiline command.

deploy:
  - provider: script
    skip_cleanup: true
    script: mvn deploy -B -DskipTests -Dbuild.number="$TRAVIS_BUILD_NUMBER"
    on:
      tags: false
      branch: dev

  - provider: script
    skip_cleanup: true
    script:
      pip install something &&
      another-command &&
      yet-another-command &&
      docker push "image-name"
    on:
      tags: false
      all_branches: true

Here is the error logs:

sh: 1: Syntax error: "&&" unexpected

If someone knows how to define multiline commands, I will be appreciated. Thanks in advance.

Body:
TLDR

The example you gave in description looks legit from a YAML perspective. Please make sure you don't have empty lines or comments which prevents the content in script section from becoming one string

Longer version

The script provider in deploy requires the script content being single string. Only one line is allowed so you can't use YAML array.

This is different from the top level script section. Top level script section allows you to use YAML array which means you can supply multiple single line strings leading with -

Having that said, any YAML single line (without line ending) can be used properly in deploy's script section. Here are some examples

script: pip install something &&
      another-command &&
      yet-another-command &&
      docker push "image-name"

# >- to removing the ending new line
script: >-
      pip install something &&
      another-command &&
      yet-another-command &&
      docker push "image-name"

The example below will not work for deploy's script section, but will work for top level script section

# Only works in top level script not deploy script
script:
    - pip install something && another-command
    - yet-another-command
    - docker push "image-name"


问:
How to hash particular column in csv file | linux |
I have a scenario

where i want to hash some columns of csv file

how to do that with below data

```<code>ID|NAME|CITY|AGE
1|AB1|BBC|12
2|AB2|FGD|17
3|AB3|ASD|18
4|AB4|SDF|19
5|AB5|ASC|22
</code>```

The Column name NAME | AGE should get hashed with random values

like below output

```<code>ID|NAME|CITY|AGE
1|68b329da9111314099c7d8ad5cb9c940|BBC|77bAD9da9893er34099c7d8ad5cb9c940
2|69b32fga9893e34099c7d8ad5cb9c940|FGD|68bAD9da989yue34099c7d8ad5cb9c940
3|46b329da9893e3403453d8ad5cb9c940|ASD|60bfgD9da9893e34099c7d8ad5cb9c940
4|50Cd29da9893e34099c7d8ad5cb9c940|SDF|67bAD9da98973e34099c7d8ad5cb9c940
5|67bAD9da9893e34099c7d8ad5cb9c940|ASC|67bAD9da11893e34099c7d8ad5cb9c940
</code>```

When i tested this code below code gives me same value for the column 'NAME'  it should give  randomized values

```<code>awk '{
    tmp="echo " $2 " | openssl md5 | cut -f2 -d\" \""
tmp | getline cksum
close(tmp)
$2=cksum
print
}' < sample.csv
</code>```

output :

```<code> 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
</code>```

答:
Example using GNU datamash to do the hashing and some awk to rearrange the columns it outputs:

```<code>$ datamash -t'|' --header-in -f md5 2,4 < input.txt | awk 'BEGIN { FS=OFS="|"; print "ID|NAME|CITY|AGE" } { print $1, $5, $3, $6 }'
ID|NAME|CITY|AGE
1|1109867462b2f0f0470df8386036243c|BBC|c20ad4d76fe97759aa27a0c99bff6710
2|14da3a611e2f8953d76b6fb7866b01d1|FGD|70efdf2ec9b086079795c442636b55fb
3|710a24b9eac0692b1adaabd07726211a|ASD|6f4922f45568161a8cdf4ad2299f6d23
4|c4d15b255ef3c6a89d1fe2e6a26b8eda|SDF|1f0e3dad99908345f7439f8ffabdffc4
5|96b24a28173a75cc3c682e25d3a6bd49|ASC|b6d767d2f8ed5d21a44b0e5886680cb9
</code>```

Note that the MD5 hashes are different in this answer than (At the time of writing) the ones in the others; that's because they use approaches that add a trailing newline to the strings being hashed, producing incorrect results if you want the exact hash:

```<code>$ echo AB1 | md5sum
d44aec35a11ff6fa8a800120dbef1cd7  -
$ echo -n AB1  | md5sum
1109867462b2f0f0470df8386036243c  -
</code>```

Body:
I have a scenario

where i want to hash some columns of csv file

how to do that with below data

ID|NAME|CITY|AGE
1|AB1|BBC|12
2|AB2|FGD|17
3|AB3|ASD|18
4|AB4|SDF|19
5|AB5|ASC|22

The Column name NAME | AGE should get hashed with random values

like below output

ID|NAME|CITY|AGE
1|68b329da9111314099c7d8ad5cb9c940|BBC|77bAD9da9893er34099c7d8ad5cb9c940
2|69b32fga9893e34099c7d8ad5cb9c940|FGD|68bAD9da989yue34099c7d8ad5cb9c940
3|46b329da9893e3403453d8ad5cb9c940|ASD|60bfgD9da9893e34099c7d8ad5cb9c940
4|50Cd29da9893e34099c7d8ad5cb9c940|SDF|67bAD9da98973e34099c7d8ad5cb9c940
5|67bAD9da9893e34099c7d8ad5cb9c940|ASC|67bAD9da11893e34099c7d8ad5cb9c940

When i tested this code below code gives me same value for the column 'NAME'  it should give  randomized values

awk '{
    tmp="echo " $2 " | openssl md5 | cut -f2 -d\" \""
tmp | getline cksum
close(tmp)
$2=cksum
print
}' < sample.csv

output :

 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940
 68b329da9893e34099c7d8ad5cb9c940

Body:
Example using GNU datamash to do the hashing and some awk to rearrange the columns it outputs:

$ datamash -t'|' --header-in -f md5 2,4 < input.txt | awk 'BEGIN { FS=OFS="|"; print "ID|NAME|CITY|AGE" } { print $1, $5, $3, $6 }'
ID|NAME|CITY|AGE
1|1109867462b2f0f0470df8386036243c|BBC|c20ad4d76fe97759aa27a0c99bff6710
2|14da3a611e2f8953d76b6fb7866b01d1|FGD|70efdf2ec9b086079795c442636b55fb
3|710a24b9eac0692b1adaabd07726211a|ASD|6f4922f45568161a8cdf4ad2299f6d23
4|c4d15b255ef3c6a89d1fe2e6a26b8eda|SDF|1f0e3dad99908345f7439f8ffabdffc4
5|96b24a28173a75cc3c682e25d3a6bd49|ASC|b6d767d2f8ed5d21a44b0e5886680cb9

Note that the MD5 hashes are different in this answer than (At the time of writing) the ones in the others; that's because they use approaches that add a trailing newline to the strings being hashed, producing incorrect results if you want the exact hash:

$ echo AB1 | md5sum
d44aec35a11ff6fa8a800120dbef1cd7  -
$ echo -n AB1  | md5sum
1109867462b2f0f0470df8386036243c  -


问:
Compare two dataframes Pyspark
I'm trying to compare two data frames with have same number of columns i.e. 4 columns with id as key column in both data frames

```<code>df1 = spark.read.csv("/path/to/data1.csv")
df2 = spark.read.csv("/path/to/data2.csv")
</code>```

Now I want to append new column to DF2 i.e. column_names which is the list of the columns with different values than df1

```<code>df2.withColumn("column_names",udf())
</code>```

DF1

```<code>+------+---------+--------+------+
|   id | |name  | sal  | Address |
+------+---------+--------+------+
|     1|  ABC   | 5000 | US      |
|     2|  DEF   | 4000 | UK      |
|     3|  GHI   | 3000 | JPN     |
|     4|  JKL   | 4500 | CHN     |
+------+---------+--------+------+
</code>```

DF2:

```<code>+------+---------+--------+------+
|   id | |name  | sal  | Address |
+------+---------+--------+------+
|     1|  ABC   | 5000 | US      |
|     2|  DEF   | 4000 | CAN     |
|     3|  GHI   | 3500 | JPN     |
|     4|  JKL_M | 4800 | CHN     |
+------+---------+--------+------+
</code>```

Now I want DF3

DF3:

```<code>+------+---------+--------+------+--------------+
|   id | |name  | sal  | Address | column_names |
+------+---------+--------+------+--------------+
|     1|  ABC   | 5000 | US      |  []          |
|     2|  DEF   | 4000 | CAN     |  [address]   |
|     3|  GHI   | 3500 | JPN     |  [sal]       |
|     4|  JKL_M | 4800 | CHN     |  [name,sal]  |
+------+---------+--------+------+--------------+
</code>```

I saw this SO question, How to compare two dataframe and print columns that are different in scala. Tried that, however the result is different.

I'm thinking of going with a UDF function by passing row from each dataframe to udf and compare column by column and return column list. However for that both the data frames should be in sorted order so that same id rows will be sent to udf. Sorting is costly operation here. Any solution?

答:
Python: PySpark version of my previous scala code.

```<code>import pyspark.sql.functions as f

df1 = spark.read.option("header", "true").csv("test1.csv")
df2 = spark.read.option("header", "true").csv("test2.csv")

columns = df1.columns
df3 = df1.alias("d1").join(df2.alias("d2"), f.col("d1.id") == f.col("d2.id"), "left")

for name in columns:
    df3 = df3.withColumn(name + "_temp", f.when(f.col("d1." + name) != f.col("d2." + name), f.lit(name)))

df3.withColumn("column_names", f.concat_ws(",", *map(lambda name: f.col(name + "_temp"), columns))).select("d1.*", "column_names").show()
</code>```

Scala: Here is my best approach for your problem.

```<code>val df1 = spark.read.option("header", "true").csv("test1.csv")
val df2 = spark.read.option("header", "true").csv("test2.csv")

val columns = df1.columns
val df3 = df1.alias("d1").join(df2.alias("d2"), col("d1.id") === col("d2.id"), "left")

columns.foldLeft(df3) {(df, name) => df.withColumn(name + "_temp", when(col("d1." + name) =!= col("d2." + name), lit(name)))}
  .withColumn("column_names", concat_ws(",", columns.map(name => col(name + "_temp")): _*))
  .show(false)
</code>```

First, I join two dataframe into df3 and used the columns from df1. By folding left to the df3 with temp columns that have the value for column name when df1 and df2 has the same id and other column values.

After that, concat_ws for those column names and the null's are gone away and only the column names are left.

```<code>+---+----+----+-------+------------+
|id |name|sal |Address|column_names|
+---+----+----+-------+------------+
|1  |ABC |5000|US     |            |
|2  |DEF |4000|UK     |Address     |
|3  |GHI |3000|JPN    |sal         |
|4  |JKL |4500|CHN    |name,sal    |
+---+----+----+-------+------------+
</code>```

The only thing different from your expected result is that the output is not a list but string.

p.s. I forgot to use PySpark but this is the normal spark, sorry.

Title: Compare two dataframes Pyspark

Body:
I'm trying to compare two data frames with have same number of columns i.e. 4 columns with id as key column in both data frames

df1 = spark.read.csv("/path/to/data1.csv")
df2 = spark.read.csv("/path/to/data2.csv")

Now I want to append new column to DF2 i.e. column_names which is the list of the columns with different values than df1

df2.withColumn("column_names",udf())

DF1

+------+---------+--------+------+
|   id | |name  | sal  | Address |
+------+---------+--------+------+
|     1|  ABC   | 5000 | US      |
|     2|  DEF   | 4000 | UK      |
|     3|  GHI   | 3000 | JPN     |
|     4|  JKL   | 4500 | CHN     |
+------+---------+--------+------+

DF2:

+------+---------+--------+------+
|   id | |name  | sal  | Address |
+------+---------+--------+------+
|     1|  ABC   | 5000 | US      |
|     2|  DEF   | 4000 | CAN     |
|     3|  GHI   | 3500 | JPN     |
|     4|  JKL_M | 4800 | CHN     |
+------+---------+--------+------+

Now I want DF3

DF3:

+------+---------+--------+------+--------------+
|   id | |name  | sal  | Address | column_names |
+------+---------+--------+------+--------------+
|     1|  ABC   | 5000 | US      |  []          |
|     2|  DEF   | 4000 | CAN     |  [address]   |
|     3|  GHI   | 3500 | JPN     |  [sal]       |
|     4|  JKL_M | 4800 | CHN     |  [name,sal]  |
+------+---------+--------+------+--------------+

I saw this SO question, How to compare two dataframe and print columns that are different in scala. Tried that, however the result is different.

I'm thinking of going with a UDF function by passing row from each dataframe to udf and compare column by column and return column list. However for that both the data frames should be in sorted order so that same id rows will be sent to udf. Sorting is costly operation here. Any solution?

Body:
Python: PySpark version of my previous scala code.

import pyspark.sql.functions as f

df1 = spark.read.option("header", "true").csv("test1.csv")
df2 = spark.read.option("header", "true").csv("test2.csv")

columns = df1.columns
df3 = df1.alias("d1").join(df2.alias("d2"), f.col("d1.id") == f.col("d2.id"), "left")

for name in columns:
    df3 = df3.withColumn(name + "_temp", f.when(f.col("d1." + name) != f.col("d2." + name), f.lit(name)))

df3.withColumn("column_names", f.concat_ws(",", *map(lambda name: f.col(name + "_temp"), columns))).select("d1.*", "column_names").show()

Scala: Here is my best approach for your problem.

val df1 = spark.read.option("header", "true").csv("test1.csv")
val df2 = spark.read.option("header", "true").csv("test2.csv")

val columns = df1.columns
val df3 = df1.alias("d1").join(df2.alias("d2"), col("d1.id") === col("d2.id"), "left")

columns.foldLeft(df3) {(df, name) => df.withColumn(name + "_temp", when(col("d1." + name) =!= col("d2." + name), lit(name)))}
  .withColumn("column_names", concat_ws(",", columns.map(name => col(name + "_temp")): _*))
  .show(false)

First, I join two dataframe into df3 and used the columns from df1. By folding left to the df3 with temp columns that have the value for column name when df1 and df2 has the same id and other column values.

After that, concat_ws for those column names and the null's are gone away and only the column names are left.

+---+----+----+-------+------------+
|id |name|sal |Address|column_names|
+---+----+----+-------+------------+
|1  |ABC |5000|US     |            |
|2  |DEF |4000|UK     |Address     |
|3  |GHI |3000|JPN    |sal         |
|4  |JKL |4500|CHN    |name,sal    |
+---+----+----+-------+------------+

The only thing different from your expected result is that the output is not a list but string.

p.s. I forgot to use PySpark but this is the normal spark, sorry.


问:
Select columns based on != condition
I have a dataframe and I have a list of some column names that correspond to the dataframe. How do I filter the dataframe so that it != the list of column names, i.e. I want the dataframe columns that are outside the specified list.

I tried the following:
quant_vair = X != true_binary_cols

but get the output error of: Unable to coerce to Series, length must be 545: given 155

Been battling for hours, any help will be appreciated.

答:
You can either drop the columns from the dataframe, or create a list that does not contain all these columns:

```<code>df_filtered = df.drop(columns=true_binary_cols)
</code>```

Or:

```<code>filtered_col = [col for col in df if col not in true_binary_cols]
df_filtered = df[filtered_col]
</code>```

Title: Select columns based on != condition

Body:
You can either drop the columns from the dataframe, or create a list that does not contain all these columns:

df_filtered = df.drop(columns=true_binary_cols)

Or:

filtered_col = [col for col in df if col not in true_binary_cols]
df_filtered = df[filtered_col]


问:
Input range slider not working on iOS Safari when clicking on track
I have a pretty straight-forward range input slider.  It works pretty well on all browsers except on iOS Safari.

The main problem I have is when I click on the slider track, it doesn't move the slider.  It merely highlights the slider.  It works fine when dragging the thumb.  Any ideas on how to fix this?

```<code><div class="slider-wrap">
    <div id="subtractBtn"></div>
    <input type="range" class="slider">
    <div id="addBtn"></div>
</div>
</code>```

答:
Enhanced version of the solution presented by Cameron Gilbert. This implementation works for sliders with a min value set to a negative number and optional a step size set.

For those not working with typescript I leave it to you to convert to plain javascript.

```<code>if (!!navigator.platform.match(/iPhone|iPad|iPod/)) {
mySlider.addEventListener(
    "touchend",
    (touchEvent: TouchEvent) => {
        var element = touchEvent.srcElement as HTMLInputElement;
        if (element.min && element.max && touchEvent.changedTouches && touchEvent.changedTouches.length > 0) {
            const max = Number(element.max);
            const min = Number(element.min);
            let step = 1;
            if (element.step) {
                step = Number(element.step);
            }
            //Calculate the complete range of the slider.
            const range = max - min;

            const boundingClientRect = element.getBoundingClientRect();
            const touch = touchEvent.changedTouches[0];

            //Calculate the slider value
            const sliderValue = (touch.pageX - boundingClientRect.left) / (boundingClientRect.right - boundingClientRect.left) * range + min;

            //Find the closest valid slider value in respect of the step size
            for (let i = min; i < max; i += step) {
                if (i >= sliderValue) {
                    const previousValue = i - step;
                    const previousDifference = sliderValue - previousValue;
                    const currentDifference = i - sliderValue;
                    if (previousDifference > currentDifference) {
                        //The sliderValue is closer to the previous value than the current value.
                        element.value = previousValue.toString();
                    } else {
                        element.value = i.toString();
                    }

                    //Trigger the change event.
                    element.dispatchEvent(new Event("change"));
                    break;
                }
            }
        }
    },
    {
        passive: true
    }
);
</code>```

}

Body:
I have a pretty straight-forward range input slider.  It works pretty well on all browsers except on iOS Safari.

The main problem I have is when I click on the slider track, it doesn't move the slider.  It merely highlights the slider.  It works fine when dragging the thumb.  Any ideas on how to fix this?

    <input type="range" class="slider">

Body:
Enhanced version of the solution presented by Cameron Gilbert. This implementation works for sliders with a min value set to a negative number and optional a step size set.

For those not working with typescript I leave it to you to convert to plain javascript.

if (!!navigator.platform.match(/iPhone|iPad|iPod/)) {
mySlider.addEventListener(
    "touchend",
    (touchEvent: TouchEvent) => {
        var element = touchEvent.srcElement as HTMLInputElement;
        if (element.min && element.max && touchEvent.changedTouches && touchEvent.changedTouches.length > 0) {
            const max = Number(element.max);
            const min = Number(element.min);
            let step = 1;
            if (element.step) {
                step = Number(element.step);
            }
            //Calculate the complete range of the slider.
            const range = max - min;

            const boundingClientRect = element.getBoundingClientRect();
            const touch = touchEvent.changedTouches[0];

            //Calculate the slider value
            const sliderValue = (touch.pageX - boundingClientRect.left) / (boundingClientRect.right - boundingClientRect.left) * range + min;

            //Find the closest valid slider value in respect of the step size
            for (let i = min; i < max; i += step) {
                if (i >= sliderValue) {
                    const previousValue = i - step;
                    const previousDifference = sliderValue - previousValue;
                    const currentDifference = i - sliderValue;
                    if (previousDifference > currentDifference) {
                        //The sliderValue is closer to the previous value than the current value.
                        element.value = previousValue.toString();
                    } else {
                        element.value = i.toString();
                    }

                    //Trigger the change event.
                    element.dispatchEvent(new Event("change"));
                    break;
                }
            }
        }
    },
    {
        passive: true
    }
);

}