问:
Convert array of string to array of struct in spark java
I have a bunch of json data in the below format

```<code>{"name": "Michael", "age": "30", "producta1": "blah1", "producta3": "blah2"}
{"name": "Michael", "age": "30", "producta1": "blah3", "producta3": "blah4"}
{"name": "Michael", "age": "30", "producta1": "blah5", "producta3": "blah6"}
{"name": "Andy", "age": "28", "producta1": "blah5", "producta3": "blah6"}
{"name": "Andy", "age": "28", "producta1": "blah6", "producta3": "blah6"}
{"name": "Andy", "age": "28", "producta1": "blah7", "producta3": "blah6"}
{"name": "Justin", "age": "12", "producta1": "blah5", "producta3": "blah6"}
{"name": "Justin", "age": "12", "producta1": "blah5", "producta3": "blah6"}
</code>```

My below code is in spark were i do some kind of aggregation as below

```<code> Dataset<Row> df = sc.read().json("/Users/g.bhageshpur/Downloads/spark-master/examples/src/main/examples/src/main/resources/people.json");

 df.createOrReplaceTempView("people");

 Dataset<Row> sqlDf = sc.sql("SELECT * FROM people");
 Dataset<Row> groupby = sqlDf.groupBy(new Column("name"), new Column("age"))
            .agg(org.apache.spark.sql.functions.collect_list("producta1"),
                    org.apache.spark.sql.functions.collect_list("producta3"))
                    .toDF("name","age","producta1","producta2");
</code>```

The above code gives me an output similar to

```<code>+-------+---+--------------------+--------------------+
|   name|age|           producta1|           producta2|
+-------+---+--------------------+--------------------+
|   Andy| 28|[blah5, blah6, bl...|[blah6, blah6, bl...|
| Justin| 12|      [blah5, blah6]|      [blah6, blah6]|
|Michael| 30|[blah1, blah3, bl...|[blah2, blah4, bl...|
+-------+---+--------------------+--------------------+

</code>```

I have a requirement where I need to convert the above array values in the producta1 column to array of json objects something similar to

```<code>[{"producta1": "blah5"},{"producta1": "blah6"},{"producta1": "blah7"}]
[{"producta1": "blah1"},{"producta1": "blah3"},{"producta1": "blah5"}]
</code>```

I tried something similar to

```<code>groupby.withColumn("newcolumn", functions.to_json(struct("producta1")));
</code>```

The above snippet does not give me the desired result. How do I achieve array of Json objects in spark java?

Body:
I have a bunch of json data in the below format

{"name": "Michael", "age": "30", "producta1": "blah1", "producta3": "blah2"}
{"name": "Michael", "age": "30", "producta1": "blah3", "producta3": "blah4"}
{"name": "Michael", "age": "30", "producta1": "blah5", "producta3": "blah6"}
{"name": "Andy", "age": "28", "producta1": "blah5", "producta3": "blah6"}
{"name": "Andy", "age": "28", "producta1": "blah6", "producta3": "blah6"}
{"name": "Andy", "age": "28", "producta1": "blah7", "producta3": "blah6"}
{"name": "Justin", "age": "12", "producta1": "blah5", "producta3": "blah6"}
{"name": "Justin", "age": "12", "producta1": "blah5", "producta3": "blah6"}

My below code is in spark were i do some kind of aggregation as below

 Dataset<Row> df = sc.read().json("/Users/g.bhageshpur/Downloads/spark-master/examples/src/main/examples/src/main/resources/people.json");

 df.createOrReplaceTempView("people");

 Dataset<Row> sqlDf = sc.sql("SELECT * FROM people");
 Dataset<Row> groupby = sqlDf.groupBy(new Column("name"), new Column("age"))
            .agg(org.apache.spark.sql.functions.collect_list("producta1"),
                    org.apache.spark.sql.functions.collect_list("producta3"))
                    .toDF("name","age","producta1","producta2");

The above code gives me an output similar to

+-------+---+--------------------+--------------------+
|   name|age|           producta1|           producta2|
+-------+---+--------------------+--------------------+
|   Andy| 28|[blah5, blah6, bl...|[blah6, blah6, bl...|
| Justin| 12|      [blah5, blah6]|      [blah6, blah6]|
|Michael| 30|[blah1, blah3, bl...|[blah2, blah4, bl...|
+-------+---+--------------------+--------------------+

I have a requirement where I need to convert the above array values in the producta1 column to array of json objects something similar to

[{"producta1": "blah5"},{"producta1": "blah6"},{"producta1": "blah7"}]
[{"producta1": "blah1"},{"producta1": "blah3"},{"producta1": "blah5"}]

I tried something similar to

groupby.withColumn("newcolumn", functions.to_json(struct("producta1")));

The above snippet does not give me the desired result. How do I achieve array of Json objects in spark java?

Body:
Try Below code.

df
.groupBy($"name",$"age")
.agg(
    collect_list(to_json(struct("producta1"))).as("producta1"), // use to_json & struct functions here.
    collect_list(to_json(struct($"producta3"))).as("producta3") // use to_json & struct functions here.
).show(false)
+-------+---+---------------------------------------------------------------------+---------------------------------------------------------------------+
|name   |age|producta1                                                            |producta3                                                            |
+-------+---+---------------------------------------------------------------------+---------------------------------------------------------------------+
|Andy   |28 |[{"producta1":"blah5"}, {"producta1":"blah6"}, {"producta1":"blah7"}]|[{"producta3":"blah6"}, {"producta3":"blah6"}, {"producta3":"blah6"}]|
|Justin |12 |[{"producta1":"blah5"}, {"producta1":"blah5"}]                       |[{"producta3":"blah6"}, {"producta3":"blah6"}]                       |
|Michael|30 |[{"producta1":"blah1"}, {"producta1":"blah3"}, {"producta1":"blah5"}]|[{"producta3":"blah2"}, {"producta3":"blah4"}, {"producta3":"blah6"}]|
+-------+---+---------------------------------------------------------------------+---------------------------------------------------------------------+


来源: stackexchange

问:
Detect Clipboard changes in Windows OS
I want to detect when clipboard changes in Windows, the change could come from any application in the machine. How can I achieve this in C++ (or C)?</p>

答:
Per MSDN documentation:

Using the Clipboard: Monitoring Clipboard Contents

Monitoring Clipboard Contents

There are three ways of monitoring changes to the clipboard. The oldest method is to create a clipboard viewer window. Windows 2000 added the ability to query the clipboard sequence number, and Windows Vista added support for clipboard format listeners. Clipboard viewer windows are supported for backward compatibility with earlier versions of Windows. New programs should use clipboard format listeners or the clipboard sequence number.

The same page explains each step in detail, but to recap:

call SetClipboardViewer() and then listen for WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD window messages.

or, call GetClipboardSequenceNumber() periodically, or at least just when you want to check if the clipboard has changed since your last check.

or, call AddClipboardFormatListener() and then listen for WM_CLIPBOARDUPDATE window messages.

ContentLicense: CC BY-SA 4.0

Title: Detect Clipboard changes in Windows OS


问:
How to fix: "@angular/fire"' has no exported member 'AngularFireModule'.ts(2305) ionic, firebase, angular
I'm trying to connect my app with a firebase db, but I receive 4 error messages on app.module.ts:

```<code>'"@angular/fire"' has no exported member 'AngularFireModule'.ts(2305),
'"@angular/fire/storage"' has no exported member 'AngularFireStorageModule'.ts(2305)
'"@angular/fire/database"' has no exported member 'AngularFireDatabaseModule'.ts(2305)
'"@angular/fire/auth"' has no exported member 'AngularFireAuthModule'.ts(2305)
</code>```

here is my package.json file:

```<code>{
  "name": "gescable",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "https://ionicframework.com/",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular-devkit/architect": "^0.1202.5",
    "@angular-devkit/architect-cli": "^0.1202.5",
    "@angular/common": "~12.1.1",
    "@angular/core": "~12.1.1",
    "@angular/fire": "^7.0.4",
    "@angular/forms": "~12.1.1",
    "@angular/platform-browser": "~12.1.1",
    "@angular/platform-browser-dynamic": "~12.1.1",
    "@angular/router": "~12.1.1",
    "@ionic/angular": "^5.5.2",
    "ajv": "^8.6.2",
    "angularfire2": "^5.4.2",
    "firebase": "^7.24.0",
    "rxfire": "^6.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.2.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~12.1.1",
    "@angular-eslint/builder": "~12.0.0",
    "@angular-eslint/eslint-plugin": "~12.0.0",
    "@angular-eslint/eslint-plugin-template": "~12.0.0",
    "@angular-eslint/template-parser": "~12.0.0",
    "@angular/cli": "~12.1.1",
    "@angular/compiler": "~12.1.1",
    "@angular/compiler-cli": "~12.1.1",
    "@angular/language-service": "~12.0.1",
    "@ionic/angular-toolkit": "^4.0.0",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "@typescript-eslint/eslint-plugin": "4.16.1",
    "@typescript-eslint/parser": "4.16.1",
    "eslint": "^7.6.0",
    "eslint-plugin-import": "2.22.1",
    "eslint-plugin-jsdoc": "30.7.6",
    "eslint-plugin-prefer-arrow": "1.2.2",
    "jasmine-core": "~3.8.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~6.3.2",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "typescript": "~4.2.4",
    "@angular-devkit/architect": "^0.1200.0",
    "firebase-tools": "^9.0.0",
    "fuzzy": "^0.1.3",
    "inquirer": "^6.2.2",
    "inquirer-autocomplete-prompt": "^1.0.1",
    "open": "^7.0.3",
    "jsonc-parser": "^3.0.0"
  },
  "description": "An Ionic project"
}
</code>```

And here is my app.module.ts:

```<code>import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ClientPageModule } from './client/client.module';
import { environment } from '../environments/environment';
import { AngularFireModule } from '@angular/fire';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { AngularFireStorageModule } from '@angular/fire/storage';
import { AngularFireDatabaseModule } from '@angular/fire/database';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    ClientPageModule,
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFireAuthModule,
    AngularFireStorageModule,
    AngularFireDatabaseModule
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule {}
</code>```

Here is my tsonfig.ts file

```<code>  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": ["es2018", "dom"]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true,
    "skipLibCheck": true
  }
}
</code>```

答:
First, change the imports by adding compact

```<code>import { AngularFireAuthModule } from "@angular/fire/compat/auth";
import { AngularFireStorageModule } from '@angular/fire/compat/storage';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
</code>```

If that doesn't solve the problem type ctrl+Z
and check compatibility
Angular     Firebase and    AngularFire

13              9          ^7.2

12              9           ^7.0

12             7,8          ^6.1.5

Body:
I'm trying to connect my app with a firebase db, but I receive 4 error messages on app.module.ts:

'"@angular/fire"' has no exported member 'AngularFireModule'.ts(2305),
'"@angular/fire/storage"' has no exported member 'AngularFireStorageModule'.ts(2305)
'"@angular/fire/database"' has no exported member 'AngularFireDatabaseModule'.ts(2305)
'"@angular/fire/auth"' has no exported member 'AngularFireAuthModule'.ts(2305)

here is my package.json file:

{
  "name": "gescable",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "https://ionicframework.com/",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular-devkit/architect": "^0.1202.5",
    "@angular-devkit/architect-cli": "^0.1202.5",
    "@angular/common": "~12.1.1",
    "@angular/core": "~12.1.1",
    "@angular/fire": "^7.0.4",
    "@angular/forms": "~12.1.1",
    "@angular/platform-browser": "~12.1.1",
    "@angular/platform-browser-dynamic": "~12.1.1",
    "@angular/router": "~12.1.1",
    "@ionic/angular": "^5.5.2",
    "ajv": "^8.6.2",
    "angularfire2": "^5.4.2",
    "firebase": "^7.24.0",
    "rxfire": "^6.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.2.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~12.1.1",
    "@angular-eslint/builder": "~12.0.0",
    "@angular-eslint/eslint-plugin": "~12.0.0",
    "@angular-eslint/eslint-plugin-template": "~12.0.0",
    "@angular-eslint/template-parser": "~12.0.0",
    "@angular/cli": "~12.1.1",
    "@angular/compiler": "~12.1.1",
    "@angular/compiler-cli": "~12.1.1",
    "@angular/language-service": "~12.0.1",
    "@ionic/angular-toolkit": "^4.0.0",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "@typescript-eslint/eslint-plugin": "4.16.1",
    "@typescript-eslint/parser": "4.16.1",
    "eslint": "^7.6.0",
    "eslint-plugin-import": "2.22.1",
    "eslint-plugin-jsdoc": "30.7.6",
    "eslint-plugin-prefer-arrow": "1.2.2",
    "jasmine-core": "~3.8.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~6.3.2",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "typescript": "~4.2.4",
    "@angular-devkit/architect": "^0.1200.0",
    "firebase-tools": "^9.0.0",
    "fuzzy": "^0.1.3",
    "inquirer": "^6.2.2",
    "inquirer-autocomplete-prompt": "^1.0.1",
    "open": "^7.0.3",
    "jsonc-parser": "^3.0.0"
  },
  "description": "An Ionic project"
}

And here is my app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ClientPageModule } from './client/client.module';
import { environment } from '../environments/environment';
import { AngularFireModule } from '@angular/fire';
import { AngularFireAuthModule } from '@angular/fire/auth';
import { AngularFireStorageModule } from '@angular/fire/storage';
import { AngularFireDatabaseModule } from '@angular/fire/database';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    ClientPageModule,
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFireAuthModule,
    AngularFireStorageModule,
    AngularFireDatabaseModule
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})
export class AppModule {}

Here is my tsonfig.ts file

  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": ["es2018", "dom"]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true,
    "skipLibCheck": true
  }
}

Body:
First, change the imports by adding compact

import { AngularFireAuthModule } from "@angular/fire/compat/auth";
import { AngularFireStorageModule } from '@angular/fire/compat/storage';
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';

If that doesn't solve the problem type ctrl+Z
and check compatibility
Angular     Firebase and    AngularFire

13              9          ^7.2

12              9           ^7.0

12             7,8          ^6.1.5


问:
Prevent contenteditable element from getting focus when clicking parent
When clicking anywhere above the "Outside" div container in the following example, the contenteditable span element gets the focus.

```<code><div style="margin:30px">
    <span contenteditable="true" style="background:#eee">
        Hello World
    </span>
    <div>Outside</div>
</div>
</code>```

Here's a jsFiddle:
http://jsfiddle.net/AXM4Y/

I want the contenteditable behave more like a real text input, thus only clicking the span element itself should trigger its focus. How do I do this? How can the event capturing of the container element be stopped. I've already tried "e.stopPropagation()" with jQuery on the parent div, but it didn't work.

答:
There's quite a bit more to making a content editable behave like an input but in answer to your question, this works in Chrome 98 browser.

const myEditableContainer = document.querySelector('.my-editable__container');
const button = document.querySelector('button');
let disabled = false;
const buttonText = (disabled) => `Click to ${disabled ? 'enable' : 'disable'}`;

button.innerHTML = buttonText(disabled);
button.addEventListener('click', () => {
    disabled = !disabled;
  button.innerHTML = buttonText(disabled);
  myEditableContainer.classList.toggle('my-editable-container--disabled', disabled);
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.my-editable__container {
  position: relative;
}

.my-editable__cover {
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  background-color: white;
}

.my-editable-container--disabled .my-editable__cover {
  pointer-events: all;
  opacity: 0.5;
}</code>```

        Hello World

   <button>
     Enable/Disable
   </button>

Outside

```

ContentLicense: CC BY-SA 3.0

Body:
When clicking anywhere above the "Outside" div container in the following example, the contenteditable span element gets the focus.

        Hello World

Outside

Here's a jsFiddle:
http://jsfiddle.net/AXM4Y/

I want the contenteditable behave more like a real text input, thus only clicking the span element itself should trigger its focus. How do I do this? How can the event capturing of the container element be stopped. I've already tried "e.stopPropagation()" with jQuery on the parent div, but it didn't work.

Body:
There's quite a bit more to making a content editable behave like an input but in answer to your question, this works in Chrome 98 browser.

const myEditableContainer = document.querySelector('.my-editable__container');
const button = document.querySelector('button');
let disabled = false;
const buttonText = (disabled) => `Click to ${disabled ? 'enable' : 'disable'}`;

button.innerHTML = buttonText(disabled);
button.addEventListener('click', () => {
    disabled = !disabled;
  button.innerHTML = buttonText(disabled);
  myEditableContainer.classList.toggle('my-editable-container--disabled', disabled);
});

.my-editable__container {
  position: relative;
}

.my-editable__cover {
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  background-color: white;
}

.my-editable-container--disabled .my-editable__cover {
  pointer-events: all;
  opacity: 0.5;
}

<div style="margin:30px">
  <div class="my-editable__container">
    <span class="my-editable" contenteditable="true" style="background:#eee">
        Hello World
    </span>
    <span class="my-editable__cover"></span>
  </div>

   <button>
     Enable/Disable
   </button>

  <div>Outside</div>
</div>


问:
Show different data from 3 columns in one column but in separated rows
i have some troubles with this situation in Crystal Reports, i have 3 columns with diferent data in each one, but i want to show them in one column but in different rows, i think is like an union equivalent in SQL, but im not sure, i have tried with an if but it doesn't work, heres an example that what i want to do:

My 3 columns if i put them separated, they display like this:

enter image description here

and i want to show them like this:

enter image description here

答:
You could create a formula field with a formula like this

```<code>If Not IsNull({Data1}) Then {Data1}
Else If Not IsNull({Data2}) Then {Data2}
Else If Not IsNull({Data3}) Then {Data3}
</code>```

(Values in square brackets are placeholders for your columns, you can add them in formula workshop dialog.)

Then place the new formula field into the report.

Body:
You could create a formula field with a formula like this

If Not IsNull({Data1}) Then {Data1}
Else If Not IsNull({Data2}) Then {Data2}
Else If Not IsNull({Data3}) Then {Data3}

(Values in square brackets are placeholders for your columns, you can add them in formula workshop dialog.)

Then place the new formula field into the report.


问:
Uninitialized Constant Error when catching Exception
I need to post articles to Wordpress via XMLRPC and catch any exceptions:

```<code>connection = XMLRPC::Client.new('mysite.com', '/xmlrpc.php', 80)
  connection.call(
  'metaWeblog.newPost',
  1,
  'user',
  'password',
  post,
  true
)
</code>```

There is en error:

```<code>C:/Ruby192/lib/ruby/1.9.1/rexml/parsers/baseparser.rb:441:in `rescue in pull': #<NoMethodError: undefined method `[]' for nil:NilClass> (REXML::ParseException)
C:/Ruby192/lib/ruby/1.9.1/rexml/parsers/baseparser.rb:341:in `pull'
C:/Ruby192/lib/ruby/1.9.1/rexml/parsers/streamparser.rb:16:in `parse'
C:/Ruby192/lib/ruby/1.9.1/rexml/document.rb:204:in `parse_stream'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/parser.rb:717:in `parse'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/parser.rb:460:in `parseMethodResponse'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/client.rb:421:in `call2'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/client.rb:410:in `call'
</code>```

I successfully caught the exception with:

```<code>connection = XMLRPC::Client.new('mysite.com', '/xmlrpc.php', 80)
begin
  connection.call(
    'metaWeblog.newPost',
    1,
    'user',
    'password',
    post,
    true
  )
rescue REXML::ParseException
  puts "Skipping error"
end
</code>```

Post is OK, article is in Wordpress.

Next I needed to catch an exception about site availability (when site is not accessible)
I tried to catch the exception with:

```<code>connection = XMLRPC::Client.new('notaccessibleSite.com', '/xmlrpc.php', 80)
begin
  connection.call(
    'metaWeblog.newPost',
    1,
    'user',
    'password',
    post,
    true
  )
rescue REXML::ParseException
  puts "Skipping error"
rescue
  puts "Others errors"
end
</code>```

But this does not work:

```<code>myscript.rb:47:in `rescue in makeRpc': uninitialized constant Object::REXML (NameError)
from myscript.rb:38:in `makeRpc'
from myscript.rb:62:in `block in postContent'
from myscript.rb:58:in `each'
from myscript.rb:58:in `postContent'
from myscript.rb:71:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
</code>```

Any suggestions?

答:
Have you tried require 'rexml/document'. Have a look at the documentation for rexml/document.rb. It requires 'rexml/rexml' for you as well as 'rexml/parseexception'.

The following doesn't produce any errors:

```<code>require "rexml/document"

begin
    doc = REXML::Document.new File.new('blah.txt')
rescue REXML::ParseException => msg
    puts "Failed: #{msg}"
end
</code>```

However if you replace the rexml/document with 'rexml/rexml', you get:

```<code>blah.rb:22:in `rescue in <main>': uninitialized constant REXML::ParseException (NameError)
    from abc.rb:20:in `<main>'
</code>```

Update (based on comments):

If you want to check that REXML::ParseException is defined, something like the following will work:

```<code>if defined?(REXML::ParseException) == 'constant' && REXML::ParseException.class == Class
  puts "REXML::ParseException is defined"
else
  puts "REXML::ParseException is NOT defined"
end
</code>```

Body:
I need to post articles to Wordpress via XMLRPC and catch any exceptions:

connection = XMLRPC::Client.new('mysite.com', '/xmlrpc.php', 80)
  connection.call(
  'metaWeblog.newPost',
  1,
  'user',
  'password',
  post,
  true
)

There is en error:

C:/Ruby192/lib/ruby/1.9.1/rexml/parsers/baseparser.rb:441:in `rescue in pull': #<NoMethodError: undefined method `[]' for nil:NilClass> (REXML::ParseException)
C:/Ruby192/lib/ruby/1.9.1/rexml/parsers/baseparser.rb:341:in `pull'
C:/Ruby192/lib/ruby/1.9.1/rexml/parsers/streamparser.rb:16:in `parse'
C:/Ruby192/lib/ruby/1.9.1/rexml/document.rb:204:in `parse_stream'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/parser.rb:717:in `parse'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/parser.rb:460:in `parseMethodResponse'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/client.rb:421:in `call2'
C:/Ruby192/lib/ruby/1.9.1/xmlrpc/client.rb:410:in `call'

I successfully caught the exception with:

connection = XMLRPC::Client.new('mysite.com', '/xmlrpc.php', 80)
begin
  connection.call(
    'metaWeblog.newPost',
    1,
    'user',
    'password',
    post,
    true
  )
rescue REXML::ParseException
  puts "Skipping error"
end

Post is OK, article is in Wordpress.

Next I needed to catch an exception about site availability (when site is not accessible)
I tried to catch the exception with:

connection = XMLRPC::Client.new('notaccessibleSite.com', '/xmlrpc.php', 80)
begin
  connection.call(
    'metaWeblog.newPost',
    1,
    'user',
    'password',
    post,
    true
  )
rescue REXML::ParseException
  puts "Skipping error"
rescue
  puts "Others errors"
end

But this does not work:

myscript.rb:47:in `rescue in makeRpc': uninitialized constant Object::REXML (NameError)
from myscript.rb:38:in `makeRpc'
from myscript.rb:62:in `block in postContent'
from myscript.rb:58:in `each'
from myscript.rb:58:in `postContent'
from myscript.rb:71:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `'

Any suggestions?

Body:
Have you tried require 'rexml/document'. Have a look at the documentation for rexml/document.rb. It requires 'rexml/rexml' for you as well as 'rexml/parseexception'.

The following doesn't produce any errors:

require "rexml/document"

begin
    doc = REXML::Document.new File.new('blah.txt')
rescue REXML::ParseException => msg
    puts "Failed: #{msg}"
end

However if you replace the rexml/document with 'rexml/rexml', you get:

blah.rb:22:in `rescue in <main>': uninitialized constant REXML::ParseException (NameError)
    from abc.rb:20:in `<main>'

Update (based on comments):

If you want to check that REXML::ParseException is defined, something like the following will work:

if defined?(REXML::ParseException) == 'constant' && REXML::ParseException.class == Class
  puts "REXML::ParseException is defined"
else
  puts "REXML::ParseException is NOT defined"
end


问:
I cannot send an ack confirmation from my client after receiving an ACK through socket
I have a server that's always listening and waiting for a connection. When a client connect then sends a file to it, it receives it, saves it and then send back an ACK file, my client send back a confirmation that he received the ACK and finally my server close the connection and my client too.

I had an issue while attempting to receive the ACK from my client, but now it's resolved.

BUT, now that I shutdown my socket connection with SHUT_WR (that's telling that we will stop sending after this, if I'm right) I cannot resend my confirmation.

I can't figure out how that's working and how can I:

From my client

Send a file to my server

Receive the ACK from my server

Resend a confirmation

From my server

Receive a file

Send an ACK

Receive the confirmation

I'm stuck. My server is working unless I try to receive or send something.

The following code blocks are my actual files

client.py

import socket
import os
import random
from socket import SHUT_WR

SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 8192

HOST = "127.0.0.1"
PORT = 8000

files = ["test1.HL7","test2.HL7","test3.HL7","test4.HL7","test5.HL7","test6.HL7","test7.HL7","test8.HL7"]

fileName = f".\\ClientFiles\\{files[random.randrange(1,8)]}"

filesize = os.path.getsize(fileName)

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

print(f"[+] Connecting to {HOST}:{PORT}")

socket.connect((HOST, PORT))

print("[+] Connected.")

socket.send(f"{fileName}{SEPARATOR}{filesize}".encode())

# opening file
with open(fileName, "rb") as f:
    print("[*] Reading")
    while True:
        # reading bytes
        bytes_read = f.read(BUFFER_SIZE)
        if not bytes_read:
            # Transmitting is done
            print("[+] File reading is done.")
            break
        # send all the buffer
        socket.sendall(bytes_read)
print(f"[+] File {fileName} sent")

socket.shutdown(SHUT_WR)

print("[*] Waiting for an acknowledgment")

data = socket.recv(BUFFER_SIZE)

print("[+] Acknoledgment recieved")

print(data.decode())

socket.sendall(data.decode().split('|')[9].encode())

print("[+] Acknowledgment confirmation sent")

print("[*] Closing")

socket.close()
```
<p><code>server.py</code></p>
<pre class="lang-py prettyprint-override"><code>import itertools

import socket

import signal

import ntpath

from pathlib import Path

from consts import *
from helper import *

# Setting Dicionnaries for HL7 ACK Requirements
MSH = {0:'MSH',2:'', 3:'', 4:'', 5:'', 6:'', 7:'', 8:'', 9:'', 10:'', 11:'',12:'', 13:'', 14:'', 15:'NE', 16:'AL', 17:'', 18:'', 19:'', 20:'', 21:''}
MSA = {0:'MSA', 1:'AA', 2:''}
ACK = {'MSH':{}, 'MSA':{}}

def hl7_ack_generator():
    """Generate the Acknowledgement file and sends it to the client

    Returns:
        String: Returns the Acknowledgment filename
    """
    content = ""

    # Switch sender-receiver
    MSH[3], MSH[5], MSH[4], MSH[6] = MSH[5], MSH[3], MSH[6], MSH[4]

    # Set the message type.
    # If possible get the message trigger to return the same trigger
    try:
        MSH[9] = f"ACK^{check_msh_9_trigger_event(MSH[9].decode().split('^'))}^ACK"
    except:
        MSH[9] = "ACK"

    # Set MSH values
    for param in MSH:
        ACK['MSH'][param] = MSH.get(param)
    # Set MSA values
    for param in MSA:
        ACK['MSA'][param] = MSA.get(param)
    # Create the ACK message
    # Handle integers & bytes in each fields
    # Get MSH values
    for i in range(0,21) :
        if i != 1:
            if ACK['MSH'][i]:
                # Generate a message id based on recieved message timestamp and message id
                # not exceeding 20 chars
                if i == 10:
                    ACK['MSH'][10] = ACK['MSH'][7].decode() + ACK['MSH'][10].decode()
                    if len(ACK['MSH'][10]) > 20:
                        ACK['MSH'][10] = ACK['MSH'][10][:20]
                    content += ACK['MSH'][10]
                else:
                    try:
                        content += ACK['MSH'][i].decode()
                    except:
                        if not ACK['MSH'][i] == None:
                            content += ACK['MSH'][i]
            content += '|'
    content += "\r"
    # Get MSA values
    for i in range(0,3):
        try:
            content += ACK['MSA'][i].decode()
        except:
            if not ACK['MSA'][i] == None:
                content += ACK['MSA'][i]
        content += "|"

    # Create the ACK filename
    filename = ACK['MSH'][10] + "_ACK.HL7"

    # create the ACK file and write its content
    with open(Path(SERVER_ACK_FILES_FOLDER + filename), "w") as f:
        f.write(content)
        f.close()

    return filename

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# test the binding
try:
    socket.bind((SERVER_HOST, SERVER_PORT))

except socket.error as error:

    print('Bind failed. Error Code : '
          + str(error[0]) + ' Message '
          + error[1])

    exit()

# Handle ctrl+c
def signal_handler(sign, frame):

    print('[*] Shutting down')
    exit(0)

while signal.signal(signal.SIGINT, signal_handler):

    # connection limit(5 connection try then deny)
    socket.listen(5)

    print(f"[*] Listening as {SERVER_HOST}:{SERVER_PORT}")

    # accept the connection if there is any
    client_socket, address = socket.accept()

    # Below code is executed if sender is connected
    print(f"[+] {address} is connected.")

    # get what the client is sending
    received = client_socket.recv(BUFFER_SIZE)

    filename, bytes_read = received.split(SEPARATOR.encode())

    # get the file size
    fileSize = bytes(itertools.takewhile(lambda i: bytes((i,)).isdigit(), bytes_read))
    bytes_read = bytes_read[len(fileSize):]

    #convert to integer
    fileSize = int(fileSize)
    filename = filename.decode()

    # remove absolute path if there is
    filename = ntpath.basename(filename)

    # start receiving the file from the socket and writing to the file stream
    with open(Path(SERVER_FILES_FOLDER + filename), "wb") as f:

        print("[+] File received")

        while True:
            # write to the file the bytes we just received
            f.write(bytes_read)

            # read 1024 bytes from the socket (receive)
            bytes_read = client_socket.recv(BUFFER_SIZE)

            if bytes_read.startswith(b'MSH'):
                messageHeader = bytes_read.partition(b'\r')[0].split(b'|')
                j = 0
                i = 2
                for i in range(2,17):
                    j+=1
                    # Exclude MSH fields(constant and/or unwanted)
                    if i not in (15,16):
                        MSH[i]= messageHeader[j]
                    #Get message ID
                    if i == 10:
                        MSA[2] = messageHeader[j]
                ackFilename = hl7_ack_generator()

            if not bytes_read:
                # file transmitting is done
                print("[+] File transfert is done")
                break

    with open(Path(SERVER_ACK_FILES_FOLDER + ackFilename), "rb") as f:
        while True:
            bytes_read = f.read(BUFFER_SIZE)
            if not bytes_read:
                print("[+] Acknoledgment Sent")
                break
            client_socket.sendall(bytes_read)

    confirmation = client_socket.recv(BUFFER_SIZE)

    print(confirmation)

    print("[+] Confirmation received")

    print("[*] Closing conneciton")

    client_socket.close()

    socket.close
</code>```

testX.hl7

```<code>MSH|^~\&|ADT1|MCM|LABADT|MCM|198808181126|SECURITY|ADT^A04|MSG00001|P|2.4
EVN|A01-|198808181123
PID|||PATID1234^5^M11||JONES^WILLIAM^A^III||19610615|M-||2106-3|1200 N ELM STREET^^GREENSBORO^NC^27401-1020|GL|(919)379-1212|(919)271-3434~(919)277-3114||S||PATID12345001^2^M10|123456789|9-87654^NC
NK1|1|JONES^BARBARA^K|SPO|||||20011105
NK1|1|JONES^MICHAEL^A|FTH
PV1|1|I|2000^2012^01||||004777^LEBAUER^SIDNEY^J.|||SUR||-||1|A0-
AL1|1||^PENICILLIN||PRODUCES HIVES~RASH
AL1|2||^CAT DANDER
DG1|001|I9|1550|MAL NEO LIVER, PRIMARY|19880501103005|F||
PR1|2234|M11|111^CODE151|COMMON PROCEDURES|198809081123
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^SMITH^ELLEN|199505011201
GT1|1122|1519|BILL^GATES^A
IN1|001|A357|1234|BCMD|||||132987
IN2|ID1551001|SSN12345678
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^ELLEN|199505011201
</code>```

Thanks for the attention!

答:
I changed my server into this:

final_size = b''

while True:
    # write to the file the bytes we just received
    f.write(bytes_read)

    final_size += bytes_read

    if len(final_size) >= fileSize:
        # file transmitting is done
        print("[+] File transfert is done")
        break

        # read 1024 bytes from the socket (receive)
        bytes_read = client_socket.recv(BUFFER_SIZE)

        if bytes_read.startswith(b'MSH'):
            messageHeader = bytes_read.partition(b'\r')[0].split(b'|')
            j = 0
            i = 2
            for i in range(2,17):
                j += 1
                # Exclude MSH fields(constant and/or unwanted)
                if i not in (15,16):
                    MSH[i]= messageHeader[j]
                    #Get message ID
                    if i == 10:
                        MSA[2] = messageHeader[j]
                ackFilename = hl7_ack_generator()
```
<p>And my client to this:</p>
<pre class="lang-py prettyprint-override"><code>print(f"[+] File {fileName} sent")
print("[*] Waiting for an acknowledgment")

data = sock.recv(BUFFER_SIZE)

print("[+] Acknoledgment recieved")

sock.sendall(data.decode().split('|')[9].encode())

print("[+] Acknowledgment confirmation sent")

print("[*] Closing")
sock.close()
</code>```

Body:
I have a server that's always listening and waiting for a connection. When a client connect then sends a file to it, it receives it, saves it and then send back an ACK file, my client send back a confirmation that he received the ACK and finally my server close the connection and my client too.

I had an issue while attempting to receive the ACK from my client, but now it's resolved.

BUT, now that I shutdown my socket connection with SHUT_WR (that's telling that we will stop sending after this, if I'm right) I cannot resend my confirmation.

I can't figure out how that's working and how can I:

From my client

Send a file to my server

Receive the ACK from my server

Resend a confirmation

From my server

Receive a file

Send an ACK

Receive the confirmation

I'm stuck. My server is working unless I try to receive or send something.

The following code blocks are my actual files

client.py

import socket
import os
import random
from socket import SHUT_WR

SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 8192

HOST = "127.0.0.1"
PORT = 8000

files = ["test1.HL7","test2.HL7","test3.HL7","test4.HL7","test5.HL7","test6.HL7","test7.HL7","test8.HL7"]

fileName = f".\\ClientFiles\\{files[random.randrange(1,8)]}"

filesize = os.path.getsize(fileName)

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

print(f"[+] Connecting to {HOST}:{PORT}")

socket.connect((HOST, PORT))

print("[+] Connected.")

socket.send(f"{fileName}{SEPARATOR}{filesize}".encode())

# opening file
with open(fileName, "rb") as f:
    print("[*] Reading")
    while True:
        # reading bytes
        bytes_read = f.read(BUFFER_SIZE)
        if not bytes_read:
            # Transmitting is done
            print("[+] File reading is done.")
            break
        # send all the buffer
        socket.sendall(bytes_read)
print(f"[+] File {fileName} sent")

socket.shutdown(SHUT_WR)

print("[*] Waiting for an acknowledgment")

data = socket.recv(BUFFER_SIZE)

print("[+] Acknoledgment recieved")

print(data.decode())

socket.sendall(data.decode().split('|')[9].encode())

print("[+] Acknowledgment confirmation sent")

print("[*] Closing")

socket.close()

server.py

import itertools

import socket

import signal

import ntpath

from pathlib import Path

from consts import *
from helper import *

# Setting Dicionnaries for HL7 ACK Requirements
MSH = {0:'MSH',2:'', 3:'', 4:'', 5:'', 6:'', 7:'', 8:'', 9:'', 10:'', 11:'',12:'', 13:'', 14:'', 15:'NE', 16:'AL', 17:'', 18:'', 19:'', 20:'', 21:''}
MSA = {0:'MSA', 1:'AA', 2:''}
ACK = {'MSH':{}, 'MSA':{}}

def hl7_ack_generator():
    """Generate the Acknowledgement file and sends it to the client

    Returns:
        String: Returns the Acknowledgment filename
    """
    content = ""

    # Switch sender-receiver
    MSH[3], MSH[5], MSH[4], MSH[6] = MSH[5], MSH[3], MSH[6], MSH[4]

    # Set the message type.
    # If possible get the message trigger to return the same trigger
    try:
        MSH[9] = f"ACK^{check_msh_9_trigger_event(MSH[9].decode().split('^'))}^ACK"
    except:
        MSH[9] = "ACK"

    # Set MSH values
    for param in MSH:
        ACK['MSH'][param] = MSH.get(param)
    # Set MSA values
    for param in MSA:
        ACK['MSA'][param] = MSA.get(param)
    # Create the ACK message
    # Handle integers & bytes in each fields
    # Get MSH values
    for i in range(0,21) :
        if i != 1:
            if ACK['MSH'][i]:
                # Generate a message id based on recieved message timestamp and message id
                # not exceeding 20 chars
                if i == 10:
                    ACK['MSH'][10] = ACK['MSH'][7].decode() + ACK['MSH'][10].decode()
                    if len(ACK['MSH'][10]) > 20:
                        ACK['MSH'][10] = ACK['MSH'][10][:20]
                    content += ACK['MSH'][10]
                else:
                    try:
                        content += ACK['MSH'][i].decode()
                    except:
                        if not ACK['MSH'][i] == None:
                            content += ACK['MSH'][i]
            content += '|'
    content += "\r"
    # Get MSA values
    for i in range(0,3):
        try:
            content += ACK['MSA'][i].decode()
        except:
            if not ACK['MSA'][i] == None:
                content += ACK['MSA'][i]
        content += "|"

    # Create the ACK filename
    filename = ACK['MSH'][10] + "_ACK.HL7"

    # create the ACK file and write its content
    with open(Path(SERVER_ACK_FILES_FOLDER + filename), "w") as f:
        f.write(content)
        f.close()

    return filename

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# test the binding
try:
    socket.bind((SERVER_HOST, SERVER_PORT))

except socket.error as error:

    print('Bind failed. Error Code : '
          + str(error[0]) + ' Message '
          + error[1])

    exit()

# Handle ctrl+c
def signal_handler(sign, frame):

    print('[*] Shutting down')
    exit(0)

while signal.signal(signal.SIGINT, signal_handler):

    # connection limit(5 connection try then deny)
    socket.listen(5)

    print(f"[*] Listening as {SERVER_HOST}:{SERVER_PORT}")

    # accept the connection if there is any
    client_socket, address = socket.accept()

    # Below code is executed if sender is connected
    print(f"[+] {address} is connected.")

    # get what the client is sending
    received = client_socket.recv(BUFFER_SIZE)

    filename, bytes_read = received.split(SEPARATOR.encode())

    # get the file size
    fileSize = bytes(itertools.takewhile(lambda i: bytes((i,)).isdigit(), bytes_read))
    bytes_read = bytes_read[len(fileSize):]

    #convert to integer
    fileSize = int(fileSize)
    filename = filename.decode()

    # remove absolute path if there is
    filename = ntpath.basename(filename)

    # start receiving the file from the socket and writing to the file stream
    with open(Path(SERVER_FILES_FOLDER + filename), "wb") as f:

        print("[+] File received")

        while True:
            # write to the file the bytes we just received
            f.write(bytes_read)

            # read 1024 bytes from the socket (receive)
            bytes_read = client_socket.recv(BUFFER_SIZE)

            if bytes_read.startswith(b'MSH'):
                messageHeader = bytes_read.partition(b'\r')[0].split(b'|')
                j = 0
                i = 2
                for i in range(2,17):
                    j+=1
                    # Exclude MSH fields(constant and/or unwanted)
                    if i not in (15,16):
                        MSH[i]= messageHeader[j]
                    #Get message ID
                    if i == 10:
                        MSA[2] = messageHeader[j]
                ackFilename = hl7_ack_generator()

            if not bytes_read:
                # file transmitting is done
                print("[+] File transfert is done")
                break

    with open(Path(SERVER_ACK_FILES_FOLDER + ackFilename), "rb") as f:
        while True:
            bytes_read = f.read(BUFFER_SIZE)
            if not bytes_read:
                print("[+] Acknoledgment Sent")
                break
            client_socket.sendall(bytes_read)

    confirmation = client_socket.recv(BUFFER_SIZE)

    print(confirmation)

    print("[+] Confirmation received")

    print("[*] Closing conneciton")

    client_socket.close()

    socket.close

testX.hl7

MSH|^~\&|ADT1|MCM|LABADT|MCM|198808181126|SECURITY|ADT^A04|MSG00001|P|2.4
EVN|A01-|198808181123
PID|||PATID1234^5^M11||JONES^WILLIAM^A^III||19610615|M-||2106-3|1200 N ELM STREET^^GREENSBORO^NC^27401-1020|GL|(919)379-1212|(919)271-3434~(919)277-3114||S||PATID12345001^2^M10|123456789|9-87654^NC
NK1|1|JONES^BARBARA^K|SPO|||||20011105
NK1|1|JONES^MICHAEL^A|FTH
PV1|1|I|2000^2012^01||||004777^LEBAUER^SIDNEY^J.|||SUR||-||1|A0-
AL1|1||^PENICILLIN||PRODUCES HIVES~RASH
AL1|2||^CAT DANDER
DG1|001|I9|1550|MAL NEO LIVER, PRIMARY|19880501103005|F||
PR1|2234|M11|111^CODE151|COMMON PROCEDURES|198809081123
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^SMITH^ELLEN|199505011201
GT1|1122|1519|BILL^GATES^A
IN1|001|A357|1234|BCMD|||||132987
IN2|ID1551001|SSN12345678
ROL|45^RECORDER^ROLE MASTER LIST|AD|CP|KATE^ELLEN|199505011201

Thanks for the attention!

Body:
I changed my server into this:

final_size = b''

while True:
    # write to the file the bytes we just received
    f.write(bytes_read)

    final_size += bytes_read

    if len(final_size) >= fileSize:
        # file transmitting is done
        print("[+] File transfert is done")
        break

        # read 1024 bytes from the socket (receive)
        bytes_read = client_socket.recv(BUFFER_SIZE)

        if bytes_read.startswith(b'MSH'):
            messageHeader = bytes_read.partition(b'\r')[0].split(b'|')
            j = 0
            i = 2
            for i in range(2,17):
                j += 1
                # Exclude MSH fields(constant and/or unwanted)
                if i not in (15,16):
                    MSH[i]= messageHeader[j]
                    #Get message ID
                    if i == 10:
                        MSA[2] = messageHeader[j]
                ackFilename = hl7_ack_generator()

And my client to this:

print(f"[+] File {fileName} sent")
print("[*] Waiting for an acknowledgment")

data = sock.recv(BUFFER_SIZE)

print("[+] Acknoledgment recieved")

sock.sendall(data.decode().split('|')[9].encode())

print("[+] Acknowledgment confirmation sent")

print("[*] Closing")
sock.close()


问:
Issue with spawning multiple processes
I am running a code and getting this error:

RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

```<code>    This probably means that you are not using fork to start your
    child processes and you have forgotten to use the proper idiom
    in the main module:
</code>```

Could someone help me with this?
Here is the code, I am running:

```<code>def heavy(n, myid):
        for x in range(1, n):
            for y in range(1, n):
                x**y
        print(myid, "is done")

    start=time.perf_counter()

    big=[]
    for i in range(50):
        p=multiprocessing.Process(target=heavy,args=(500,i))
        big.append(p)
        p.start()

    for i in big:
        i.join()

    end=time.perf_counter()

    print(end-start)
</code>```

答:
Depending on the OS, the new process will be either forked from the current one (in linux) or spawned (Windows, mac). A simplistic view of forking is that a copy of the current process is made: all the objects already created will exists in the new copy, alas will not be the same objects as in the initial process. Indeed, objects in one process are not directly accessible from the other process. Spawning starts a new python interpreter, re-runs the file (with a __name__ different from '__main__'), and then runs the target passed when creating the Process. The re-running of the file is what is part of the 'bootstraping phase'.

In your case, as you do not use the if __name__ == '__main__': guard, when the file is re-run tries to start new process, which would lead to an infinite tree of new processes. The multiprocessing module takes care of this cases and detects that you are trying to start new processes even before the target was run.

For a simple test of what happens when you use multiprocessing, see the code in this answer.

Title: Issue with spawning multiple processes

Body:
I am running a code and getting this error:

RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.

    This probably means that you are not using fork to start your
    child processes and you have forgotten to use the proper idiom
    in the main module:

Could someone help me with this?
Here is the code, I am running:

def heavy(n, myid):
        for x in range(1, n):
            for y in range(1, n):
                x**y
        print(myid, "is done")

    start=time.perf_counter()

    big=[]
    for i in range(50):
        p=multiprocessing.Process(target=heavy,args=(500,i))
        big.append(p)
        p.start()

    for i in big:
        i.join()

    end=time.perf_counter()

    print(end-start)


问:
How to watch public directory in Vite project for hot-reload?
I have a react project configured with Vite.

Hot reload works great, but I use react-i18next for multiple language support and this is my structure:

```<code>public
  -> en
    -> translation.json
  -> ru
    -> translation.json
</code>```

When I change the translation.json files, Vite doesn't watch it, and I have to refresh the page to see the changes.

Is there a way to tell Vite to watch all the files in the public directory?

答:
I've modified flydev's answer so that it can hot-reload the i18n-dependent components without reloading the whole page. (Currently using in a typescript project)

import { PluginOption } from "vite";

export default function I18nHotReload(): PluginOption {
  return {
    name: 'i18n-hot-reload',
    handleHotUpdate({ file, server }) {
      if (file.includes('locales') && file.endsWith('.json')) {
        console.log('Locale file updated')
        server.ws.send({
          type: "custom",
          event: "locales-update",
        });
      }
    },
  }
}
```
<p>Then adding it to the vite's plugins:</p>
<pre class="lang-js prettyprint-override"><code>plugins: [
    ...,
    i18nHotReload(),
]
</code>```

And then adding the listener anywhere your code can reach (I'm using it in the i18n initial config file)

if (import.meta.hot) {
  import.meta.hot.on('locales-update', () => {
    i18n.reloadResources().then(() => {
      i18n.changeLanguage(i18n.language)
    })
  })
}
```

i18n.reloadResources() alone doesn't trigger the translations hot reload

Body:
I have a react project configured with Vite.

Hot reload works great, but I use react-i18next for multiple language support and this is my structure:

public
  -> en
    -> translation.json
  -> ru
    -> translation.json

When I change the translation.json files, Vite doesn't watch it, and I have to refresh the page to see the changes.

Is there a way to tell Vite to watch all the files in the public directory?

Body:
I've modified flydev's answer so that it can hot-reload the i18n-dependent components without reloading the whole page. (Currently using in a typescript project)

import { PluginOption } from "vite";

export default function I18nHotReload(): PluginOption {
  return {
    name: 'i18n-hot-reload',
    handleHotUpdate({ file, server }) {
      if (file.includes('locales') && file.endsWith('.json')) {
        console.log('Locale file updated')
        server.ws.send({
          type: "custom",
          event: "locales-update",
        });
      }
    },
  }
}

Then adding it to the vite's plugins:

plugins: [
    ...,
    i18nHotReload(),
]

And then adding the listener anywhere your code can reach (I'm using it in the i18n initial config file)

if (import.meta.hot) {
  import.meta.hot.on('locales-update', () => {
    i18n.reloadResources().then(() => {
      i18n.changeLanguage(i18n.language)
    })
  })
}

i18n.reloadResources() alone doesn't trigger the translations hot reload


问:
If statement within return
How do I add an if statement in a return statement of this sort:

```<code>return {
    ID: select('core/editor').getEditedPostAttribute('featured_media'),
    if (ID) {
        media: select('core').getMedia( ID )
    }
};
</code>```

Clearly, I can't just drop an if statement if () directly within return {}.

答:
There are 2 things you can do, either use a ternary operator inline:

```<code>return {
    ID: select('core/editor').getEditedPostAttribute('featured_media'),
    media: (ID ? select('core').getMedia( ID ) : undefined)
};
</code>```

or create the object and conditionally add a new property

```<code>const obj = {
    ID: select('core/editor').getEditedPostAttribute('featured_media')
};

if(ID){
    obj.media = select('core').getMedia( ID )
}

return obj
</code>```

Title: If statement within return

Body:
How do I add an if statement in a return statement of this sort:

return {
    ID: select('core/editor').getEditedPostAttribute('featured_media'),
    if (ID) {
        media: select('core').getMedia( ID )
    }
};

Clearly, I can't just drop an if statement if () directly within return {}.

Body:
There are 2 things you can do, either use a ternary operator inline:

return {
    ID: select('core/editor').getEditedPostAttribute('featured_media'),
    media: (ID ? select('core').getMedia( ID ) : undefined)
};

or create the object and conditionally add a new property

const obj = {
    ID: select('core/editor').getEditedPostAttribute('featured_media')
};

if(ID){
    obj.media = select('core').getMedia( ID )
}

return obj


问:
Upload file to a graphql springboot microservice from another springboot microservice
I have one springboot microservice which is implemented using graphql technology and exposes a mutation as endpoint to upload file and other file related information.

```<code>mutation($file: Upload, $fileInfo: FileInfo) {
    uploadFile(file: $file, fileInfo: $fileInfo)
}

input FileInfo {
    name: String
    size: Int
}
</code>```

Curl command to call this,

```<code>curl -v -L http://localhost:8087/graphql \
-F operations='{ "query": "mutation($file: Upload, $fileInfo: FileInfo) { uploadFile(file: $file, fileInfo: $fileInfo)}", "variables": { "file": null, "fileInfo": {"name": "test.json", "size": 500} } }' \
-F map='{ "0": ["variables.file"]}' \
-F 0=test.json
</code>```

Same achieved through postman,

I know Its easy to call this mutation endpoint and upload file from UI as there are many good clients available for UI but I have to call this mutation from another springboot microservice which has file as InputStream and FileInfo stored in a HashMap<String, Object>.

How can I achieve this from java code? can we create a restTemplate.exchange or restTemplate.postForEntity http request with MediaType.MULTIPART_FORM_DATA as content type to achieve this? a code snippet would be very useful.

答:
It gave me a hard time also, so here you go.
[Spring Boot 2.6.3 / DGS Netflix / Java 17]

I added the Query in a 'uploadFile.graphql' file

uploadFile.graphql

```<code>mutation($file: Upload!, $fileInfo: FileInfo!) {
    uploadFile(file: $file, fileInfo: $fileInfo)
}
</code>```

Here is a sample Code. (didn't run it but should work)

```<code>
@Autowired
private RestTemplate restTemplate;

@Autowired
private ObjectMapper objectMapper;

private void uploadFile(){

  // Build the Query Variables Map
  var fileInfo = new FileInfo("test.json", 500);
  var fileInfoJson = objectMapper.writeValueAsString(fileInfo);

  var variables = new LinkedHashMap();
  variables.put("fileInfo", fileInfoJson);
  variables.put("file", null);

  // Build the GraphQL-Params
  var query = StreamUtils.copyToString( new ClassPathResource("uploadFile.graphql").getInputStream(), Charset.defaultCharset());

  var params = new LinkedHashMap();
  params.put("operationName", "FileUploadMutation");
  params.put("variables", variables);
  params.put("query", query)

  // Build Multi-Part Upload Request
  var file = Paths.get("src/test/resources/test.json");
  try{
    var contentBytes = Files.readAllBytes(file)
    var multiPartFile = new MultiPartByteArrayResource(file.getFileName(), contentBytes);

    var formData = new LinkedMultiValueMap<>();
    formData.set("operations", objectMapper.writeValueAsString(params));
    formData.set("map": "{\"file\": [\"variables.file\"]}");
    formData.set("file",multiPartFile);

    var headers = new HttpHeaders(); // If you need additional headers... here you go!

    var requestEntity = new HttpEntity<>(formData, headers);
    var response = restTemplate.exchange("/graphql", HttpMethod.POST, requestEntity, String.class);

    //Done!
  } catch(final IOException e){
    log.error(e.getMessage());
  }
}
</code>```

I use it for Integration Testing  of my GraphQl-Upload Mutations.

Body:
I have one springboot microservice which is implemented using graphql technology and exposes a mutation as endpoint to upload file and other file related information.

mutation($file: Upload, $fileInfo: FileInfo) {
    uploadFile(file: $file, fileInfo: $fileInfo)
}

input FileInfo {
    name: String
    size: Int
}

Curl command to call this,

curl -v -L http://localhost:8087/graphql \
-F operations='{ "query": "mutation($file: Upload, $fileInfo: FileInfo) { uploadFile(file: $file, fileInfo: $fileInfo)}", "variables": { "file": null, "fileInfo": {"name": "test.json", "size": 500} } }' \
-F map='{ "0": ["variables.file"]}' \
-F 0=test.json

Same achieved through postman,

I know Its easy to call this mutation endpoint and upload file from UI as there are many good clients available for UI but I have to call this mutation from another springboot microservice which has file as InputStream and FileInfo stored in a HashMap<String, Object>.

How can I achieve this from java code? can we create a restTemplate.exchange or restTemplate.postForEntity http request with MediaType.MULTIPART_FORM_DATA as content type to achieve this? a code snippet would be very useful.

Body:
It gave me a hard time also, so here you go.
[Spring Boot 2.6.3 / DGS Netflix / Java 17]

I added the Query in a 'uploadFile.graphql' file

uploadFile.graphql

mutation($file: Upload!, $fileInfo: FileInfo!) {
    uploadFile(file: $file, fileInfo: $fileInfo)
}

Here is a sample Code. (didn't run it but should work)

@Autowired
private RestTemplate restTemplate;

@Autowired
private ObjectMapper objectMapper;

private void uploadFile(){

  // Build the Query Variables Map
  var fileInfo = new FileInfo("test.json", 500);
  var fileInfoJson = objectMapper.writeValueAsString(fileInfo);

  var variables = new LinkedHashMap();
  variables.put("fileInfo", fileInfoJson);
  variables.put("file", null);

  // Build the GraphQL-Params
  var query = StreamUtils.copyToString( new ClassPathResource("uploadFile.graphql").getInputStream(), Charset.defaultCharset());

  var params = new LinkedHashMap();
  params.put("operationName", "FileUploadMutation");
  params.put("variables", variables);
  params.put("query", query)

  // Build Multi-Part Upload Request
  var file = Paths.get("src/test/resources/test.json");
  try{
    var contentBytes = Files.readAllBytes(file)
    var multiPartFile = new MultiPartByteArrayResource(file.getFileName(), contentBytes);

    var formData = new LinkedMultiValueMap<>();
    formData.set("operations", objectMapper.writeValueAsString(params));
    formData.set("map": "{\"file\": [\"variables.file\"]}");
    formData.set("file",multiPartFile);

    var headers = new HttpHeaders(); // If you need additional headers... here you go!

    var requestEntity = new HttpEntity<>(formData, headers);
    var response = restTemplate.exchange("/graphql", HttpMethod.POST, requestEntity, String.class);

    //Done!
  } catch(final IOException e){
    log.error(e.getMessage());
  }
}

I use it for Integration Testing  of my GraphQl-Upload Mutations.


问:
Karatsuba multiplication error for large integers in Python
I've been trying to implement the Karatsuba algorithm in Python3 in the following way:

```<code>def karatsuba(num1,num2):
    n_max = max(len(str(int(num1))), len(str(int(num2))))
    if n_max == 1:
        return int(num1*num2)

    n = n_max + n_max%2

    a = num1//10**(n/2)
    b = num1%10**(n/2)
    c = num2//10**(n/2)
    d = num2%10**(n/2)

    t1 = karatsuba(a,c)
    t3 = karatsuba(b,d)
    t2 = karatsuba(a+b,c+d) - t1 - t3

    return int(t1*10**n + t2*10**(n/2) + t3)
</code>```

While the function works for small products, it fails for ones that exceed 18 digits. One can see this by running, say,

```<code>import random

for i in range(1,12):
    a = random.randint(10**i, 10**(i+1)-1)
    b = random.randint(10**i, 10**(i+1)-1)
    print(f"{len(str(a*b))} digits, error: {abs(a*b - karatsuba(a,b))}")
</code>```

I would appreciate if someone could explain what is the root of this problem and, if possible, how could this code be modified to fix it. My best guess is that some round-off error is committed by Python at some point. That said, I don't really know how int fundamentally works in this language.

答: Use n//2 instead of n/2 to stay with ints and avoid that precision loss due to that float value.

Body:
I've been trying to implement the Karatsuba algorithm in Python3 in the following way:

def karatsuba(num1,num2):
    n_max = max(len(str(int(num1))), len(str(int(num2))))
    if n_max == 1:
        return int(num1*num2)

    n = n_max + n_max%2

    a = num1//10**(n/2)
    b = num1%10**(n/2)
    c = num2//10**(n/2)
    d = num2%10**(n/2)

    t1 = karatsuba(a,c)
    t3 = karatsuba(b,d)
    t2 = karatsuba(a+b,c+d) - t1 - t3

    return int(t1*10**n + t2*10**(n/2) + t3)

While the function works for small products, it fails for ones that exceed 18 digits. One can see this by running, say,

import random

for i in range(1,12):
    a = random.randint(10**i, 10**(i+1)-1)
    b = random.randint(10**i, 10**(i+1)-1)
    print(f"{len(str(a*b))} digits, error: {abs(a*b - karatsuba(a,b))}")

I would appreciate if someone could explain what is the root of this problem and, if possible, how could this code be modified to fix it. My best guess is that some round-off error is committed by Python at some point. That said, I don't really know how int fundamentally works in this language.


问:
SAS: How to replace delimit and split column to multiple rows?
I have just started to learn SAS programming and I'm trying to experiment with replacing a phrase "@@@@" with "|" before splitting the cell into multiple rows in SAS Studio.

I have created an example below for this experiment. It was reference from How to split a column into multiple rows in SAS but I couldn't get it to work. The SYSTEM_ID column is printing well but the ITEM_LIST is not splitting.

My current output is as follows:

Here's my current code. Please help.

```<code>data example1;
    input SYSTEM_ID $ ITEM_LIST $ 5-50 ;
    datalines;
    ID_1 Apple Juice @@@@ Orange @@@@ Banana Milk
    ;
run;

data example2 (keep=SYSTEM_ID ITEM_LIST_SUB rename=(ITEM_LIST_SUB=ITEM_LIST));
    set example1;

    ITEM_LIST_TRANS = tranwrd(ITEM_LIST,"@@@@","|");
    do i = 1 to countw(ITEM_LIST_TRANS,"|");
       ITEM_LIST_SUB = scan(ITEM_LIST,i,"|");
       output;
    end;
run;

proc print data = example2;run;
</code>```

答:
DLMSTR will allow direct read.

```<code>data example1;
   infile cards dlmstr='@@@@' missover;
   input SYSTEM_ID $ @;
   length item $50;
   do until(missing(item));
      input item @;
      if not missing(item) then output;
      end;
   datalines;
ID_1 Apple Juice @@@@ Orange @@@@ Banana Milk
ID_2 Apple Juice @@@@ Orange @@@@ Banana Milk @@@@ Apple Juice @@@@ Orange @@@@ Banana Milk
;
run;
proc print;
   run;
</code>```

Body:
I have just started to learn SAS programming and I'm trying to experiment with replacing a phrase "@@@@" with "|" before splitting the cell into multiple rows in SAS Studio.

I have created an example below for this experiment. It was reference from How to split a column into multiple rows in SAS but I couldn't get it to work. The SYSTEM_ID column is printing well but the ITEM_LIST is not splitting.

My current output is as follows:

Here's my current code. Please help.

data example1;
    input SYSTEM_ID $ ITEM_LIST $ 5-50 ;
    datalines;
    ID_1 Apple Juice @@@@ Orange @@@@ Banana Milk
    ;
run;

data example2 (keep=SYSTEM_ID ITEM_LIST_SUB rename=(ITEM_LIST_SUB=ITEM_LIST));
    set example1;

    ITEM_LIST_TRANS = tranwrd(ITEM_LIST,"@@@@","|");
    do i = 1 to countw(ITEM_LIST_TRANS,"|");
       ITEM_LIST_SUB = scan(ITEM_LIST,i,"|");
       output;
    end;
run;

proc print data = example2;run;

Body:
DLMSTR will allow direct read.

data example1;
   infile cards dlmstr='@@@@' missover;
   input SYSTEM_ID $ @;
   length item $50;
   do until(missing(item));
      input item @;
      if not missing(item) then output;
      end;
   datalines;
ID_1 Apple Juice @@@@ Orange @@@@ Banana Milk
ID_2 Apple Juice @@@@ Orange @@@@ Banana Milk @@@@ Apple Juice @@@@ Orange @@@@ Banana Milk
;
run;
proc print;
   run;


问:
Cannot import beautiful soup with all packages installed
I have installed anaconda in my laptop as well. So it returned me this message

ImportError: cannot import name 'beautifulsoup' from 'bs4' (C:\Users\jinfe\anaconda3\lib\site-packages\bs4_init_.py)

答: Here you are trying to import 'beautifulsoup' but we can see on the docs of the library that the name to import is 'BeautifulSoup' instead


问:
Elastic Search Synonym filter behaviour is different when applied at analyzer filter compared to multiplexer level
Synonym filter i.e my_synonym when i applied at Analyzer level is working as expected

```<code>PUT /test_index?pretty
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [
             "my_synonym"
            ]
          }
        },
        "filter": {
          "my_synonym": {
            "type": "synonym",
            "synonyms": [
              "foo, bar => baz",
              "The hero => CaptainAmerica"
            ]
          },
          "my_multiplexer": {
            "type": "multiplexer",
            "filters": [
              "my_synonym"
            ]
          }
        }
      }
    }
  }
}
</code>```

And when execute

```<code>GET /test_index/_analyze?pretty
{
   "analyzer": "my_analyzer",
  "text": "The hero bar"
}
</code>```

i am getting below output which is what i am expecting

```<code>{
  "tokens" : [
    {
      "token" : "CaptainAmerica",
      "start_offset" : 0,
      "end_offset" : 8,
      "type" : "SYNONYM",
      "position" : 0
    },
    {
      "token" : "baz",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "SYNONYM",
      "position" : 1
    }
  ]
}
</code>```

But when i apply my_synonym filter to my_multiplexer and injecting my_multiplexer to analyzer filter is yielding different results

```<code>PUT /test_index?pretty
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [
              "my_multiplexer"
            ]
          }
        },
        "filter": {
          "my_synonym": {
            "type": "synonym",
            "synonyms": [
              "foo, bar => baz",
              "The hero => CaptainAmerica"
            ]
          },
          "my_multiplexer": {
            "type": "multiplexer",
            "filters": [
              "my_synonym"
            ]
          }
        }
      }
    }
  }
}
</code>```

the result for same query is

```<code>{
  "tokens" : [
    {
      "token" : "The",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "hero",
      "start_offset" : 4,
      "end_offset" : 8,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "bar",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "baz",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "SYNONYM",
      "position" : 2
    }
  ]
}
</code>```

I observed that if i use coma (,) in place of whitespace ' ' in synonym list it is working as expected but i need to join few words and link to single entity.

Please let me know what went wrong or other workarounds

答:
Found the issue.

Apparently, I am facing of a side effect of the "remove duplicates" filter used at the output of the Multiplexer filter. In the code of the "remove duplicates" filter, we can see:

boolean duplicate = (posIncrement == 0 && previous.contains(term, 0, length));

Workaround :

Replace the "contains" String method by the "equals" in the test of the "RemoveDuplicatesTokenFilter"

Body:
Synonym filter i.e my_synonym when i applied at Analyzer level is working as expected

PUT /test_index?pretty
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [
             "my_synonym"
            ]
          }
        },
        "filter": {
          "my_synonym": {
            "type": "synonym",
            "synonyms": [
              "foo, bar => baz",
              "The hero => CaptainAmerica"
            ]
          },
          "my_multiplexer": {
            "type": "multiplexer",
            "filters": [
              "my_synonym"
            ]
          }
        }
      }
    }
  }
}

And when execute

GET /test_index/_analyze?pretty
{
   "analyzer": "my_analyzer",
  "text": "The hero bar"
}

i am getting below output which is what i am expecting

{
  "tokens" : [
    {
      "token" : "CaptainAmerica",
      "start_offset" : 0,
      "end_offset" : 8,
      "type" : "SYNONYM",
      "position" : 0
    },
    {
      "token" : "baz",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "SYNONYM",
      "position" : 1
    }
  ]
}

But when i apply my_synonym filter to my_multiplexer and injecting my_multiplexer to analyzer filter is yielding different results

PUT /test_index?pretty
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "standard",
            "filter": [
              "my_multiplexer"
            ]
          }
        },
        "filter": {
          "my_synonym": {
            "type": "synonym",
            "synonyms": [
              "foo, bar => baz",
              "The hero => CaptainAmerica"
            ]
          },
          "my_multiplexer": {
            "type": "multiplexer",
            "filters": [
              "my_synonym"
            ]
          }
        }
      }
    }
  }
}

the result for same query is

{
  "tokens" : [
    {
      "token" : "The",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "hero",
      "start_offset" : 4,
      "end_offset" : 8,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "bar",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "baz",
      "start_offset" : 9,
      "end_offset" : 12,
      "type" : "SYNONYM",
      "position" : 2
    }
  ]
}

I observed that if i use coma (,) in place of whitespace ' ' in synonym list it is working as expected but i need to join few words and link to single entity.

Please let me know what went wrong or other workarounds


问:
Array of string that looks like a date
If I have an array like:
let array = ["Friday, 11 February","Tuesday, 10 February","Friday, 04 March",  "Thursday, 17 February", "Today", "Monday, 9 February"];.
What I try to do is to find the closest date to today or the smaller and I don't want to take "Today".
Until now I tried:

```<code>let array = ["Friday, 11 February","Tuesday, 10 February","Friday, 04 March",  "Thursday, 17 February", "Today", "Monday, 9 February"];
array = array.map(el => el.split(", ").slice(1).join()).filter(el =>el)
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
let closest = "";

for(let i = 0; i < array.length; i++){
    for(let j = 1; j < array.length; j++){
    let numberOne = array[i].match(/\d+/)[0];
    let monthOne = array[i].match(/\b[a-zA-Z]+\b/g)[0];
    let numberTwo = array[j].match(/\d+/)[0];
    let monthTwo = array[j].match(/\b[a-zA-Z]+\b/g)[0];
    if(+(numberOne) < +(numberTwo) && months.indexOf(monthOne) <= months.indexOf(monthTwo)){
      closest = array[i]
    }

  }
}
console.log(closest)
</code>```

Everything is ok but I want to know if I can transform in a Date and sort by date. Anyone have a solution to this or a cleaner way to find the closest date? The array is dynamic and until now I didn't find any date which is before today and to take that one. Thank you!

答:
First of all, here are one issue: year is not defined, so let's clarify we mean current year by transforming all dates to actual Date:

const now = new Date();
array.map(el => new Date(`${el} ${now.getFullYear()}`);
```
<p>Then we can calculate differences from now (in milliseconds):</p>
<pre class="lang-js prettyprint-override"><code>array.map(el => new Date(`${el} ${now.getFullYear()}`) - now.getTime());
</code>```

Let's wrap them into Math.abs to easely find which one in smallest using Math.min():

const offsets = array.map(el => Math.abs(new Date(`${el} ${now.getFullYear()}`) - now.getTime()));
const closestIndex = offsets.findIndex(el => el === Math.min(...offsets));
```
<p><code>closestIndex</code> - index of date with smallest offset which means "closest to now".</p>
<p><strong>Full code (excluding "Today" from the beginning):</strong></p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const array = ["Friday, 11 February", "Tuesday, 10 February", "Friday, 04 March",  "Thursday, 17 February", "Today", "Monday, 9 February"].filter(el => el !== 'Today');

const now = new Date();

const offsets = array.map(el => Math.abs(new Date(`${el} ${now.getFullYear()}`) - now.getTime()));

const closestIndex = offsets.findIndex(el => el === Math.min(...offsets));

console.log(array[closestIndex]);</code>```

Title: Array of string that looks like a date

Body:
If I have an array like:
let array = ["Friday, 11 February","Tuesday, 10 February","Friday, 04 March",  "Thursday, 17 February", "Today", "Monday, 9 February"];.
What I try to do is to find the closest date to today or the smaller and I don't want to take "Today".
Until now I tried:

let array = ["Friday, 11 February","Tuesday, 10 February","Friday, 04 March",  "Thursday, 17 February", "Today", "Monday, 9 February"];
array = array.map(el => el.split(", ").slice(1).join()).filter(el =>el)
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
let closest = "";

for(let i = 0; i < array.length; i++){
    for(let j = 1; j < array.length; j++){
    let numberOne = array[i].match(/\d+/)[0];
    let monthOne = array[i].match(/\b[a-zA-Z]+\b/g)[0];
    let numberTwo = array[j].match(/\d+/)[0];
    let monthTwo = array[j].match(/\b[a-zA-Z]+\b/g)[0];
    if(+(numberOne) < +(numberTwo) && months.indexOf(monthOne) <= months.indexOf(monthTwo)){
      closest = array[i]
    }

  }
}
console.log(closest)

Everything is ok but I want to know if I can transform in a Date and sort by date. Anyone have a solution to this or a cleaner way to find the closest date? The array is dynamic and until now I didn't find any date which is before today and to take that one. Thank you!

Body:
First of all, here are one issue: year is not defined, so let's clarify we mean current year by transforming all dates to actual Date:

const now = new Date();
array.map(el => new Date(`${el} ${now.getFullYear()}`);

Then we can calculate differences from now (in milliseconds):

array.map(el => new Date(`${el} ${now.getFullYear()}`) - now.getTime());

Let's wrap them into Math.abs to easely find which one in smallest using Math.min():

const offsets = array.map(el => Math.abs(new Date(`${el} ${now.getFullYear()}`) - now.getTime()));
const closestIndex = offsets.findIndex(el => el === Math.min(...offsets));

closestIndex - index of date with smallest offset which means "closest to now".

Full code (excluding "Today" from the beginning):

const array = ["Friday, 11 February", "Tuesday, 10 February", "Friday, 04 March",  "Thursday, 17 February", "Today", "Monday, 9 February"].filter(el => el !== 'Today');

const now = new Date();

const offsets = array.map(el => Math.abs(new Date(`${el} ${now.getFullYear()}`) - now.getTime()));

const closestIndex = offsets.findIndex(el => el === Math.min(...offsets));

console.log(array[closestIndex]);


问:
JavaScript: How can you select random elements from an array without allowing duplicates?
I am looking to randomly select a number from this array WITHOUT duplicates. There can only be two possibilities for each number as shown in the array, select up to a maximum of 6.
This works to select a random number but allows duplicates...

```<code>const smallNums = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10];

const randomSmallNumArr = smallNums[Math.floor(Math.random() * smallNums.length)];
</code>```

When using the splice() method, each time I generate a number based on a random index, it's removed but shows up again in the array the next time a random is generated

答:
If I understand your requirement clearly, You want to generate a non-repeating random numbers from an array of numbers ? If Yes, I added a solution below.

// Input array
const arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10];

// Remove duplicate elements from an array
let uniqueElementsArr = [...new Set(arr)];

// Find out random number from an array
const randomNum = uniqueElementsArr[Math.floor(Math.random()*uniqueElementsArr.length)];

// removing the random number from the existing array so that it should not be replicate.
if (uniqueElementsArr.indexOf(randomNum) !== -1) {
    uniqueElementsArr.splice(uniqueElementsArr.indexOf(randomNum), 1)
}

console.log(randomNum);```

Body:
I am looking to randomly select a number from this array WITHOUT duplicates. There can only be two possibilities for each number as shown in the array, select up to a maximum of 6.
This works to select a random number but allows duplicates...

const smallNums = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10];

const randomSmallNumArr = smallNums[Math.floor(Math.random() * smallNums.length)];

When using the splice() method, each time I generate a number based on a random index, it's removed but shows up again in the array the next time a random is generated


问:
What's the best way to send a signal to all members of a process group?
I want to kill a whole process tree.  What is the best way to do this using any common scripting languages? I am looking for a simple solution.</p>

答:
To kill the whole process group at once, just like ^C does:

PID="$(pgrep -f unique_command_line_part)"
if [[ -n "$PID" ]]
then
    PGID="$(ps --no-headers -p $PID -o pgid)"
    kill -SIGINT -- -${PGID// /}
fi
```

Each line is explained in this answer

OwnerDisplayName: Adam Peck

LastEditorDisplayName: TravisO

Body:
To kill the whole process group at once, just like ^C does:

PID="$(pgrep -f unique_command_line_part)"
if [[ -n "$PID" ]]
then
    PGID="$(ps --no-headers -p $PID -o pgid)"
    kill -SIGINT -- -${PGID// /}
fi

Each line is explained in this answer


问:
Group by - Excel Power Query multiple rows into one
I have data I loaded to Power Query  - each Employee has mulitple rows and its looks like this:

empNum reason 1 reason 2 reason 3

3453    1         null    null

3453    null      1       null

3453    null      null    1

How can I transform the data to look like this?

empNum reason 1 reason 2 reason 3

3453    1        1        1

答:
EDIT

You may try in this way as well, so, the steps are as follows:

• Select any cell of the source,

• From Data Tab --> Click From Table/Range (Under Get & Transform Group)

• Select the First Column i.e. EmpNum and right click Unpivot Other Columns,

• From Home Tab --> Under Transform Group --> Click Group By,

• GroupBy EmpNum --> New Column Name -> Group --> Operation --> All Rows --> Press Ok

• From Add Custom Tab --> Under General Group --> Click --> Custom Column

• New Column Name --> Reason

• Custom Column Formula -->

```<code>`Table.Column([Group],"Value")`
</code>```

• Press Ok

• Then Extract The Values From The Reason Column By Pressing The Dropdown and Click Extract Values

• Select Delimiter as your choice ( I took comma )

• Once Extracted Goto Home Tab --> Select Split Column by,

• By Delimiter -> Delimiter is Comma should be at Each Occurence of the delimiter and press Ok (Also Note in Advanced Options By Default it is Split into Columns)

• Remove the column that not required and from Home Tab press Close & Load Drop down, from Import Data choose either Existing sheet or New Sheet and press Ok

```<code>let
    Source = Excel.CurrentWorkbook(){[Name="Table13"]}[Content],
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"EmpNum"}, "Attribute", "Value"),
    #"Grouped Rows" = Table.Group(#"Unpivoted Other Columns", {"EmpNum"}, {{"Group", each _, type table [EmpNum=number, Attribute=text, Value=number]}}),
    #"Added Custom" = Table.AddColumn(#"Grouped Rows", "Reason", each Table.Column([Group],"Value")),
    #"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Reason", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "Reason", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Reason.1", "Reason.2", "Reason.3"}),
    #"Removed Columns" = Table.RemoveColumns(#"Split Column by Delimiter",{"Group"})
in
    #"Removed Columns"
</code>```

Body:
EDIT

You may try in this way as well, so, the steps are as follows:

• Select any cell of the source,

• From Data Tab --> Click From Table/Range (Under Get & Transform Group)

• Select the First Column i.e. EmpNum and right click Unpivot Other Columns,

• From Home Tab --> Under Transform Group --> Click Group By,

• GroupBy EmpNum --> New Column Name -> Group --> Operation --> All Rows --> Press Ok

• From Add Custom Tab --> Under General Group --> Click --> Custom Column

• New Column Name --> Reason

• Custom Column Formula -->

`Table.Column([Group],"Value")`

• Press Ok

• Then Extract The Values From The Reason Column By Pressing The Dropdown and Click Extract Values

• Select Delimiter as your choice ( I took comma )

• Once Extracted Goto Home Tab --> Select Split Column by,

• By Delimiter -> Delimiter is Comma should be at Each Occurence of the delimiter and press Ok (Also Note in Advanced Options By Default it is Split into Columns)

• Remove the column that not required and from Home Tab press Close & Load Drop down, from Import Data choose either Existing sheet or New Sheet and press Ok

let
    Source = Excel.CurrentWorkbook(){[Name="Table13"]}[Content],
    #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"EmpNum"}, "Attribute", "Value"),
    #"Grouped Rows" = Table.Group(#"Unpivoted Other Columns", {"EmpNum"}, {{"Group", each _, type table [EmpNum=number, Attribute=text, Value=number]}}),
    #"Added Custom" = Table.AddColumn(#"Grouped Rows", "Reason", each Table.Column([Group],"Value")),
    #"Extracted Values" = Table.TransformColumns(#"Added Custom", {"Reason", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "Reason", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Reason.1", "Reason.2", "Reason.3"}),
    #"Removed Columns" = Table.RemoveColumns(#"Split Column by Delimiter",{"Group"})
in
    #"Removed Columns"


问:
Tomcat 9 service using older version of java
I am using Tomcat 9 and Java 11 on my windows server.

In my system there are total 3 JDKs present (two Java 1.8.x and one JDK 11 )

JAVA_HOME environment varibable points to JDK11
Also registry keys current version points to JDK11

I cannot uninstall older version of java 1.8 from my system as some of the apps are still using java 8.

Now when I am running Tomcat 9 service , it is picking older version of Java 1.8.x & not Java 11.

In catalina.bat file I have also added following explicitly

```<code>set JAVA_HOME=D:\Java\jdk 11.0.8
</code>```

But still it picks older version of java. In the tomcat configuration java tab also points to Java 11 dll file.

When I run the tomcat locally using startup.bat file & not start the service through services app then in catalina logs I get correct version of Java.

Please suggest why tomcat service is not picking latest java 11 version.

答:
Try uninstalling your Tomcat service and installing it again using service.bat in tomcat folder.

```<code>service.bat remove
service.bat install
</code>```

If that doesn't work ,check the appropriate registry key. Here is mine:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\Tomcat7.55\Parameters\Java

change the Jvm key value .

Note :To open regedit ,
In the search box on the taskbar, type regedit, then select Registry Editor (Desktop app) from the results.
Right-click Start , then select Run. Type regedit in the Open: box, and then select OK.

Body:
I am using Tomcat 9 and Java 11 on my windows server.

In my system there are total 3 JDKs present (two Java 1.8.x and one JDK 11 )

JAVA_HOME environment varibable points to JDK11
Also registry keys current version points to JDK11

I cannot uninstall older version of java 1.8 from my system as some of the apps are still using java 8.

Now when I am running Tomcat 9 service , it is picking older version of Java 1.8.x & not Java 11.

In catalina.bat file I have also added following explicitly

set JAVA_HOME=D:\Java\jdk 11.0.8

But still it picks older version of java. In the tomcat configuration java tab also points to Java 11 dll file.

When I run the tomcat locally using startup.bat file & not start the service through services app then in catalina logs I get correct version of Java.

Please suggest why tomcat service is not picking latest java 11 version.

Body:
Try uninstalling your Tomcat service and installing it again using service.bat in tomcat folder.

service.bat remove
service.bat install

If that doesn't work ,check the appropriate registry key. Here is mine:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Apache Software Foundation\Procrun 2.0\Tomcat7.55\Parameters\Java

change the Jvm key value .

Note :To open regedit ,
In the search box on the taskbar, type regedit, then select Registry Editor (Desktop app) from the results.
Right-click Start , then select Run. Type regedit in the Open: box, and then select OK.


问:
Microsoft SQL Server Streak Counter
I have data in the following format:

ID
Period
Date

1
1
2020-09-05

1
2
2020-10-01

1
3
2020-10-30

2
2
2020-10-01

2
4
2020-12-05

2
6
2021-02-05

3
1
2020-09-05

I want to calculate a streak grouping by both ID and period. The first date instance for each group should start at one, and if the date in the next row is less than 30 days from the first row, +1 to the streak counter. This should reset to 1 if the next row is 30 or more days.

This is my desired output:

ID
Period
Date
Counter

1
1
2020-09-05
1

1
2
2020-10-01
2

1
3
2020-10-30
3

2
2
2020-10-01
1

2
4
2020-12-05
1

2
6
2021-02-05
1

3
1
2020-09-05
1

I'm completely stuck on this - any help would be greatly appreciated. I'm using Microsoft SQL server.

EDIT: Actually using Microsoft SQL Server

答:
From Oracle 12c, you can use MATCH_RECOGNIZE to perform a row-by-row comparison:

SELECT id,
       period,
       "DATE",
       counter
FROM   table_name
MATCH_RECOGNIZE(
  PARTITION BY id
  ORDER     BY "DATE"
  MEASURES
    COUNT(*) AS counter
  ALL ROWS PER MATCH
  PATTERN (any_date streak_date*)
  DEFINE
    streak_date AS "DATE" <= PREV("DATE") + INTERVAL '30' DAY
              -- AND PREV(period) < period
)
```
<p>Which, for the sample data:</p>
<pre class="lang-sql prettyprint-override"><code>CREATE TABLE table_name (ID, Period, "DATE") AS
SELECT 1, 1, DATE '2020-09-05' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-10-30' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 2, 4, DATE '2020-12-05' FROM DUAL UNION ALL
SELECT 2, 6, DATE '2021-02-05' FROM DUAL UNION ALL
SELECT 3, 1, DATE '2020-09-05' FROM DUAL
</code>```

Note: DATE is a reserved word and it is bad practice to use it as a column name.

Outputs:

ID
PERIOD
DATE
COUNTER

1
1
2020-09-05 00:00:00
1

1
2
2020-10-01 00:00:00
2

1
3
2020-10-30 00:00:00
3

2
2
2020-10-01 00:00:00
1

2
4
2020-12-05 00:00:00
1

2
6
2021-02-05 00:00:00
1

3
1
2020-09-05 00:00:00
1

db<>fiddle here

Title: Microsoft SQL Server Streak Counter

Body:
From Oracle 12c, you can use MATCH_RECOGNIZE to perform a row-by-row comparison:

SELECT id,
       period,
       "DATE",
       counter
FROM   table_name
MATCH_RECOGNIZE(
  PARTITION BY id
  ORDER     BY "DATE"
  MEASURES
    COUNT(*) AS counter
  ALL ROWS PER MATCH
  PATTERN (any_date streak_date*)
  DEFINE
    streak_date AS "DATE" <= PREV("DATE") + INTERVAL '30' DAY
              -- AND PREV(period) < period
)

Which, for the sample data:

CREATE TABLE table_name (ID, Period, "DATE") AS
SELECT 1, 1, DATE '2020-09-05' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-10-30' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 2, 4, DATE '2020-12-05' FROM DUAL UNION ALL
SELECT 2, 6, DATE '2021-02-05' FROM DUAL UNION ALL
SELECT 3, 1, DATE '2020-09-05' FROM DUAL

Note: DATE is a reserved word and it is bad practice to use it as a column name.

Outputs:

ID
PERIOD
DATE
COUNTER

1
1
2020-09-05 00:00:00
1

1
2
2020-10-01 00:00:00
2

1
3
2020-10-30 00:00:00
3

2
2
2020-10-01 00:00:00
1

2
4
2020-12-05 00:00:00
1

2
6
2021-02-05 00:00:00
1

3
1
2020-09-05 00:00:00
1

db<>fiddle here