问:
Fully Uninstall opendjk-11 from WSL
I am Python programmer but wanted to use Java/Scala for a project (so learning Java/Scala).

In my Windows Subsystem Linux (WSL) I had previously installed OpenJDK v 11. I wanted to replace the OpenJdk 11.0.07 with a lower version or Java 8 because one of the programs I run needs Java 8.

When I look into Window's control panel, I do not see java (I meant I removed manually from Control Panel) and obviously, command prompt says there is no Java installed. But when I issue command in WSL:

```<code>java --version
</code>```

I get following results:

```<code>openjdk 11.0.7 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.7+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.7+10, mixed mode)
</code>```

How do I remove the above and install openjdk 8 in ubuntu (WSL) and Windows.

One of the commands I played with it is: sudo apt-get remove openjdk*

sudo apt-get remove openjdk*

```<code>Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'openjdk-9-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-jdk' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre' for glob 'openjdk*'
Note, selecting 'openjdk-6-jre' for glob 'openjdk*'
Note, selecting 'openjdk-6-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-11-demo' for glob 'openjdk*'
Note, selecting 'openjdk-8-demo' for glob 'openjdk*'
Note, selecting 'openjdk-11-source' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre-dcevm' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-11-dbg' for glob 'openjdk*'
Note, selecting 'openjdk-11-doc' for glob 'openjdk*'
Note, selecting 'openjdk-8-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-7-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre-zero' for glob 'openjdk*'
Note, selecting 'openjdk-8-source' for glob 'openjdk*'
Note, selecting 'openjdk-jre' for glob 'openjdk*'
Note, selecting 'openjdk-11-jdk' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre-zero' for glob 'openjdk*'
Note, selecting 'openjdk-7-jdk' for glob 'openjdk*'
Note, selecting 'openjdk-10-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-7-jre' for glob 'openjdk*'
Note, selecting 'openjdk-9-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre-dcevm' for glob 'openjdk*'
Note, selecting 'openjdk-11-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-dbg' for glob 'openjdk*'
Note, selecting 'openjdk-8-doc' for glob 'openjdk*'
Package 'openjdk-6-jre-headless' is not installed, so not removed
Package 'openjdk-7-jdk' is not installed, so not removed
Package 'openjdk-6-jre' is not installed, so not removed
Package 'openjdk-7-jre' is not installed, so not removed
Package 'openjdk-7-jre-headless' is not installed, so not removed
Package 'openjdk-9-jre-headless' is not installed, so not removed
Package 'openjdk-jre' is not installed, so not removed
Package 'openjdk-9-jdk-headless' is not installed, so not removed
Package 'openjdk-10-jdk-headless' is not installed, so not removed
Package 'openjdk-8-jre-dcevm' is not installed, so not removed
Package 'openjdk-11-dbg' is not installed, so not removed
Package 'openjdk-11-doc' is not installed, so not removed
Package 'openjdk-11-jdk' is not installed, so not removed
Package 'openjdk-11-jdk-headless' is not installed, so not removed
Package 'openjdk-11-jre' is not installed, so not removed
Package 'openjdk-11-jre-headless' is not installed, so not removed
Package 'openjdk-11-source' is not installed, so not removed
Package 'openjdk-11-demo' is not installed, so not removed
Package 'openjdk-11-jre-dcevm' is not installed, so not removed
Package 'openjdk-11-jre-zero' is not installed, so not removed
Package 'openjdk-8-dbg' is not installed, so not removed
Package 'openjdk-8-demo' is not installed, so not removed
Package 'openjdk-8-doc' is not installed, so not removed
Package 'openjdk-8-jdk' is not installed, so not removed
Package 'openjdk-8-jdk-headless' is not installed, so not removed
Package 'openjdk-8-jre' is not installed, so not removed
Package 'openjdk-8-jre-headless' is not installed, so not removed
Package 'openjdk-8-jre-zero' is not installed, so not removed
Package 'openjdk-8-source' is not installed, so not removed
The following packages were automatically installed and are no longer required:
  fonts-dejavu-extra java-common libasound2 libasound2-data libatk-wrapper-java libatk-wrapper-java-jni libgif7
  libice-dev libpcsclite1 libpthread-stubs0-dev libsm-dev libx11-dev libx11-doc libxau-dev libxcb1-dev libxdmcp-dev
  libxt-dev x11proto-core-dev x11proto-dev xorg-sgml-doctools xtrans-dev
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 140 not upgraded.
</code>```

答:
Wsl is a Linux system on the windows kernel. You should uninstall the JVM with the same Linux tool as you used to install it.

For Ubuntu this is Typically apt or dpkg

If you want to start completely over remove the app and install it again.

Title: Fully Uninstall opendjk-11 from WSL

Body:
I am Python programmer but wanted to use Java/Scala for a project (so learning Java/Scala).

In my Windows Subsystem Linux (WSL) I had previously installed OpenJDK v 11. I wanted to replace the OpenJdk 11.0.07 with a lower version or Java 8 because one of the programs I run needs Java 8.

When I look into Window's control panel, I do not see java (I meant I removed manually from Control Panel) and obviously, command prompt says there is no Java installed. But when I issue command in WSL:

java --version

I get following results:

openjdk 11.0.7 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.7+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.7+10, mixed mode)

How do I remove the above and install openjdk 8 in ubuntu (WSL) and Windows.

One of the commands I played with it is: sudo apt-get remove openjdk*

sudo apt-get remove openjdk*

Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'openjdk-9-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-jdk' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre' for glob 'openjdk*'
Note, selecting 'openjdk-6-jre' for glob 'openjdk*'
Note, selecting 'openjdk-6-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-11-demo' for glob 'openjdk*'
Note, selecting 'openjdk-8-demo' for glob 'openjdk*'
Note, selecting 'openjdk-11-source' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre-dcevm' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-11-dbg' for glob 'openjdk*'
Note, selecting 'openjdk-11-doc' for glob 'openjdk*'
Note, selecting 'openjdk-8-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-7-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre-zero' for glob 'openjdk*'
Note, selecting 'openjdk-8-source' for glob 'openjdk*'
Note, selecting 'openjdk-jre' for glob 'openjdk*'
Note, selecting 'openjdk-11-jdk' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre-zero' for glob 'openjdk*'
Note, selecting 'openjdk-7-jdk' for glob 'openjdk*'
Note, selecting 'openjdk-10-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-7-jre' for glob 'openjdk*'
Note, selecting 'openjdk-9-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-jre-headless' for glob 'openjdk*'
Note, selecting 'openjdk-11-jre-dcevm' for glob 'openjdk*'
Note, selecting 'openjdk-11-jdk-headless' for glob 'openjdk*'
Note, selecting 'openjdk-8-dbg' for glob 'openjdk*'
Note, selecting 'openjdk-8-doc' for glob 'openjdk*'
Package 'openjdk-6-jre-headless' is not installed, so not removed
Package 'openjdk-7-jdk' is not installed, so not removed
Package 'openjdk-6-jre' is not installed, so not removed
Package 'openjdk-7-jre' is not installed, so not removed
Package 'openjdk-7-jre-headless' is not installed, so not removed
Package 'openjdk-9-jre-headless' is not installed, so not removed
Package 'openjdk-jre' is not installed, so not removed
Package 'openjdk-9-jdk-headless' is not installed, so not removed
Package 'openjdk-10-jdk-headless' is not installed, so not removed
Package 'openjdk-8-jre-dcevm' is not installed, so not removed
Package 'openjdk-11-dbg' is not installed, so not removed
Package 'openjdk-11-doc' is not installed, so not removed
Package 'openjdk-11-jdk' is not installed, so not removed
Package 'openjdk-11-jdk-headless' is not installed, so not removed
Package 'openjdk-11-jre' is not installed, so not removed
Package 'openjdk-11-jre-headless' is not installed, so not removed
Package 'openjdk-11-source' is not installed, so not removed
Package 'openjdk-11-demo' is not installed, so not removed
Package 'openjdk-11-jre-dcevm' is not installed, so not removed
Package 'openjdk-11-jre-zero' is not installed, so not removed
Package 'openjdk-8-dbg' is not installed, so not removed
Package 'openjdk-8-demo' is not installed, so not removed
Package 'openjdk-8-doc' is not installed, so not removed
Package 'openjdk-8-jdk' is not installed, so not removed
Package 'openjdk-8-jdk-headless' is not installed, so not removed
Package 'openjdk-8-jre' is not installed, so not removed
Package 'openjdk-8-jre-headless' is not installed, so not removed
Package 'openjdk-8-jre-zero' is not installed, so not removed
Package 'openjdk-8-source' is not installed, so not removed
The following packages were automatically installed and are no longer required:
  fonts-dejavu-extra java-common libasound2 libasound2-data libatk-wrapper-java libatk-wrapper-java-jni libgif7
  libice-dev libpcsclite1 libpthread-stubs0-dev libsm-dev libx11-dev libx11-doc libxau-dev libxcb1-dev libxdmcp-dev
  libxt-dev x11proto-core-dev x11proto-dev xorg-sgml-doctools xtrans-dev
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 140 not upgraded.


来源: stackexchange

问:
Why I can't bind the background color in different platform?
Here is XAML:

```<code><?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App1.MainPage">

    <BoxView>
        <BoxView.BackgroundColor>
            <OnPlatform x:TypeArguments="Color">
                <On Platform="Android" Value="{Binding First}"></On>
                <On Platform="iOS" Value="{Binding Second}"></On>
            </OnPlatform>
        </BoxView.BackgroundColor>
    </BoxView>
</ContentPage>
</code>```

Here is code-behind:

```<code>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App1
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = this;
        }
        public Color First {
            get {
                return Color.FromHex("#575757");
            }
        }
        public Color Second
        {
            get
            {
                return Color.FromHex("#ffffff");
            }
        }
    }
}
</code>```

After I ran the program, it reports an error:
Specified cast is not valid.

What's the problem with it?

答:
The Xaml you pasted suppose that the OnPlatform object is the target of the Binding to string, and then the OnPlatform returns the right string depending on the Platform.

Unfortunately, that doesn't work because OnPlatform is not a BindableObject and can't be the target of a Binding.

It's well explained in this answer : https://stackoverflow.com/a/41829242/8187800 .

There are two ways to fix the problem .

Hard code the color string in xaml .

```<code><BoxView>
  <BoxView.BackgroundColor>
    <OnPlatform x:TypeArguments="Color">
        <On Platform="Android" Value="#575757"></On>
        <On Platform="iOS" Value="#ffffff"></On>
    </OnPlatform>
   </BoxView.BackgroundColor>
</BoxView>
</code>```

Refer https://forums.xamarin.com/discussion/33117/setting-platform-specific-background-color-in-xaml .

Change Color to BindingBase .

```<code>   <OnPlatform x:TypeArguments="BindingBase">
        <On Platform="Android" Value="{Binding First}"></On>
        <On Platform="iOS" Value="{Binding Second}"></On>
    </OnPlatform>
</code>```

in this way there is a warning but we could ignore it

ContentLicense: CC BY-SA 4.0

Body:
Here is XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="App1.MainPage">

    <BoxView>
        <BoxView.BackgroundColor>
            <OnPlatform x:TypeArguments="Color">
                <On Platform="Android" Value="{Binding First}"></On>
                <On Platform="iOS" Value="{Binding Second}"></On>
            </OnPlatform>
        </BoxView.BackgroundColor>
    </BoxView>
</ContentPage>

Here is code-behind:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App1
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = this;
        }
        public Color First {
            get {
                return Color.FromHex("#575757");
            }
        }
        public Color Second
        {
            get
            {
                return Color.FromHex("#ffffff");
            }
        }
    }
}

After I ran the program, it reports an error:
Specified cast is not valid.

What's the problem with it?

Body:
The Xaml you pasted suppose that the OnPlatform object is the target of the Binding to string, and then the OnPlatform returns the right string depending on the Platform.

Unfortunately, that doesn't work because OnPlatform is not a BindableObject and can't be the target of a Binding.

It's well explained in this answer : https://stackoverflow.com/a/41829242/8187800 .

There are two ways to fix the problem .

Hard code the color string in xaml .

<BoxView>
  <BoxView.BackgroundColor>
    <OnPlatform x:TypeArguments="Color">
        <On Platform="Android" Value="#575757"></On>
        <On Platform="iOS" Value="#ffffff"></On>
    </OnPlatform>
   </BoxView.BackgroundColor>
</BoxView>

Refer https://forums.xamarin.com/discussion/33117/setting-platform-specific-background-color-in-xaml .

Change Color to BindingBase .

   <OnPlatform x:TypeArguments="BindingBase">
        <On Platform="Android" Value="{Binding First}"></On>
        <On Platform="iOS" Value="{Binding Second}"></On>
    </OnPlatform>

in this way there is a warning but we could ignore it


问:
Action on google Smart home token exchange problem
I am getting stuck at a point.

Situation:

We use Firebase Authentication in Mobile App IOS/Android and Action On Google (Smart Home).
along side we use Firebase Function to handle request.

Problem:

Account linking on Action on google is my problem.
however my authentication URL works perfectly and able to send back data successfully.
but when it calls token url we get the problem here.

As, I said we use Firebase Authentication, we don't know how to fetch Access token and Refresh token from Firebase to send back to Google Home.

Here is my token code below, i just send constant token right now, i have no idea how to obtain Access token, please help, i would be really thankful to you.

Token URL Firebase Function:

```<code>export const token = functions.https.onRequest(async (request, response) => {
  //admin.auth().getUser(response)
  const grantType = request.query.grant_type ?
    request.query.grant_type : request.body.grant_type;
  const secondsInDay = 86400; // 60 * 60 * 24
  const HTTP_STATUS_OK = 200;
  console.log(`Grant type ${grantType}`);

  const user = admin.auth().getUser(request.body.code);

  user.getIdToken(true).then(function(idToken) {

}).catch(function(error) {

});

  console.log(request.body.client_id);
  console.log('test');
  console.log(request.body.client_secret);

  let obj = {};
  if (grantType === 'authorization_code')  {

      obj = {
        token_type: 'bearer',
        access_token: 'jkljkhasdjhjhkdhasdsd',
        refresh_token: 'nkjcajkguiahdilawjd,bcjkbakdjhdlasd',
        expires_in: secondsInDay,
      };
  } else if (grantType === 'refresh_token') {

    obj = {
      token_type: 'bearer',
      access_token: 'njkhasiumnabkdukchaskjhkhad',
      expires_in: secondsInDay,
    };
  }
  response.status(HTTP_STATUS_OK)
    .json(obj);
});
</code>```

答:
we use Firebase Authentication, we don't know how to fetch Access token and Refresh token from Firebase to send back to Google Home.

Firebase Authentication does not directly expose functionality to mint and validate OAuth tokens for users, it simply enables you to provide client-side user sign-in and validation. You will need to implement your own OAuth token management on top of Firebase Authentication.

We have an example app that does something similar which you might find helpful, and a companion blog post that describes some of the implementation details. The example uses JWT to encode the Firebase Authentication user data so each request can determine how to map the Assistant intents to the Firebase uid value.

Body:
I am getting stuck at a point.

Situation:

We use Firebase Authentication in Mobile App IOS/Android and Action On Google (Smart Home).
along side we use Firebase Function to handle request.

Problem:

Account linking on Action on google is my problem.
however my authentication URL works perfectly and able to send back data successfully.
but when it calls token url we get the problem here.

As, I said we use Firebase Authentication, we don't know how to fetch Access token and Refresh token from Firebase to send back to Google Home.

Here is my token code below, i just send constant token right now, i have no idea how to obtain Access token, please help, i would be really thankful to you.

Token URL Firebase Function:

export const token = functions.https.onRequest(async (request, response) => {
  //admin.auth().getUser(response)
  const grantType = request.query.grant_type ?
    request.query.grant_type : request.body.grant_type;
  const secondsInDay = 86400; // 60 * 60 * 24
  const HTTP_STATUS_OK = 200;
  console.log(`Grant type ${grantType}`);

  const user = admin.auth().getUser(request.body.code);

  user.getIdToken(true).then(function(idToken) {

}).catch(function(error) {

});

  console.log(request.body.client_id);
  console.log('test');
  console.log(request.body.client_secret);

  let obj = {};
  if (grantType === 'authorization_code')  {

      obj = {
        token_type: 'bearer',
        access_token: 'jkljkhasdjhjhkdhasdsd',
        refresh_token: 'nkjcajkguiahdilawjd,bcjkbakdjhdlasd',
        expires_in: secondsInDay,
      };
  } else if (grantType === 'refresh_token') {

    obj = {
      token_type: 'bearer',
      access_token: 'njkhasiumnabkdukchaskjhkhad',
      expires_in: secondsInDay,
    };
  }
  response.status(HTTP_STATUS_OK)
    .json(obj);
});


问:
Covert to unix timestamp
I want to convert the date by passing year, month, day, hour, minute and seconds to unix timestamp in scala.

def toUnixTimeStamp(year: String, month: String,day: String,hour:String, minute:String,second: String) =
{
   ???
}
And year, month and day should be today's date

toUnixTimeStamp("2020","6","1","3","3","0") should return 1591023823

答:
```<code>import java.time.LocalDateTime
import java.time.ZoneOffset

def toUnixTimeStamp(year: String, month: String, day: String, hour:String, minute:String,second: String): Long = {
  return LocalDateTime.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day), Integer.parseInt(hour), Integer.parseInt(minute), Integer.parseInt(second)).toEpochSecond(ZoneOffset.UTC)
}
</code>```

Please note you may need to specify the correct timezone if it is not UTC.

Title: Covert to unix timestamp

Body:
import java.time.LocalDateTime
import java.time.ZoneOffset

def toUnixTimeStamp(year: String, month: String, day: String, hour:String, minute:String,second: String): Long = {
  return LocalDateTime.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day), Integer.parseInt(hour), Integer.parseInt(minute), Integer.parseInt(second)).toEpochSecond(ZoneOffset.UTC)
}

Please note you may need to specify the correct timezone if it is not UTC.


问:
JS apply function to all values of object
I have an object like this:

```<code>const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}
</code>```

Then I want to apply a function to all names values:

```<code>const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

const normalizedPlayer = {
    ...player,
    namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}
</code>```

But I get an array of objects instead of object:

```<code>{
  id: 123,
  country: 'GB',
  names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
  namesNormalized: [
    { key1: 'John Paul' },
    { key2: 'Johny Paul' },
    { key3: 'Johny paul' }
  ]
}
</code>```

I want namesNormalized like this:

```<code> {
    id: 123,
    country: 'GB',
    names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
    namesNormalized: {
     key1: 'John Paul',
     key2: 'Johny Paul',
     key3: 'Johny paul'
   }
 }
</code>```

答:
You can use reduce method on Object.entries to return an object and assign it to namesNormalized property.

const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}

const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizedPlayer = { ...player }
normalizedPlayer.namesNormalized = Object.entries(player.names)
  .reduce((r, [k, v]) => Object.assign(r, {
    [k]: normalizeString(v)
  }), {})

console.log(normalizedPlayer)```

Body:
I have an object like this:

const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}

Then I want to apply a function to all names values:

const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

const normalizedPlayer = {
    ...player,
    namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}

But I get an array of objects instead of object:

{
  id: 123,
  country: 'GB',
  names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
  namesNormalized: [
    { key1: 'John Paul' },
    { key2: 'Johny Paul' },
    { key3: 'Johny paul' }
  ]
}

I want namesNormalized like this:

 {
    id: 123,
    country: 'GB',
    names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
    namesNormalized: {
     key1: 'John Paul',
     key2: 'Johny Paul',
     key3: 'Johny paul'
   }
 }


问:
Setting Up Database Connection with Sequelize & PostgreSQL
I am wondering if anyone in the community is able to help me understand a bit more about the connection between PostgreSQL and Sequelize through node-Postgres. I understand that I install Sequelize, that if I am using someone of the SQL flavors that I need to install their dependencies in order for the connection from a database interface to connect to the files in the application I am building. The question I have is when I use node-Postgres 'POOL' to connection is it the same as using the Sequelize instance? Or is it that node-Postgres is the actual part of the connection and Sequelize is the way I interact with the database in my file applications? Please help me understand. I appreciate all the feedback I can get. If a visualization would help then here is it:</p>

```<code>export const pool = new Pool({
   database: 'postgres',
   port: 5432,
   host: process.env.HOST,
   user: process.env.USER_NAME,
   password: process.env.DB_PASS
});

const sequelize = new Sequelize('postgres', process.env.USER_NAME, process.env.DB_PASS, {
   host: process.env.HOST,
   dialect: 'postgres'
});

</code>```

答:
Under the hood Sequelize uses pg package when you set dialect: 'postgres'.
So if you wish to use connection pool you can indicate this like:

```<code>const sequelize = new Sequelize(/* ... */, {
  // ...
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
});
</code>```

I suppose Sequelize uses Pool object from pg to achieve a connection pool.

Body:
I am wondering if anyone in the community is able to help me understand a bit more about the connection between PostgreSQL and Sequelize through node-Postgres. I understand that I install Sequelize, that if I am using someone of the SQL flavors that I need to install their dependencies in order for the connection from a database interface to connect to the files in the application I am building. The question I have is when I use node-Postgres 'POOL' to connection is it the same as using the Sequelize instance? Or is it that node-Postgres is the actual part of the connection and Sequelize is the way I interact with the database in my file applications? Please help me understand. I appreciate all the feedback I can get. If a visualization would help then here is it:

export const pool = new Pool({
   database: 'postgres',
   port: 5432,
   host: process.env.HOST,
   user: process.env.USER_NAME,
   password: process.env.DB_PASS
});

const sequelize = new Sequelize('postgres', process.env.USER_NAME, process.env.DB_PASS, {
   host: process.env.HOST,
   dialect: 'postgres'
});

Body:
Under the hood Sequelize uses pg package when you set dialect: 'postgres'.
So if you wish to use connection pool you can indicate this like:

const sequelize = new Sequelize(/* ... */, {
  // ...
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
});

I suppose Sequelize uses Pool object from pg to achieve a connection pool.


问:
Dragable and Rotatable polygon
```<code>import numpy as np
from tkinter import *
#import tkinter as tk
#from shapely.geometry import Point, Polygon

class obstaclelist:
    def __init__(self,):
        self.obsL=[]
        self.obsnums=0

    def setobnums(self,obamount):
        self.obsnums=obamount    #set number of obstacles

    def insertobs(self,newob):   #insert newly created obstacles
        self.obsL.append(newob)

class obstacleS:
    def __init__(self,):
        self.obs=[]
        self.configure=[]
        self.polynum=0
    def setobs(self,obS):       #set polygons of the obstacle
        self.obs.append(obS)
    def setconfigure(self,con):  #set initial configuration (x,y,angle)
        self.configure=con
    def setpolynum(self,numm):  #set number of polygons of an obstacle
        self.polynum=numm

class polygon:
    def __init__(self,):
        self.vertex=[]
        self.numvertex=0
    def setpoly(self,v):           #set vertexes of the polygon
        self.vertex=v
    def setvertexnum(self,numv):   #set number of vertex of a polygon
        self.numvertex=numv

class project:
    def __init__(self,):
        self.link=None
        self.layer=None
        self.root=Tk()
        self.frames =[]
        self.widgets =[]
        self.numPoly=0
        self.store=[]
        self.canvas=None
        self.halfwindow=200

    def RUN(self):
        #root=Tk()
        self.root.title("potential field")
        fullwindow=self.halfwindow*2
        self.canvas=Canvas(self.root,width=fullwindow,height=fullwindow,background='white',relief='raised',borderwidth=1)
        self.canvas.grid(row=0,column=0)
        self.canvas.config(scrollregion=self.canvas.bbox(ALL))
        self.canvas.pack()

        FR= Frame(self.root).pack(side = "bottom")

        #btn1 = Button(FR, text = "Input", fg = "Orange",command=self.numObstacle).pack(side = "left")
        #btn2 = Button(FR, text = "Build", fg = "Red",command=self.add_polygon).pack(side = "left")
        #btn3 = Button(FR, text = "Robot", fg = "Blue",command=self.add_robot).pack(side = "left")

        self.root.mainloop()

//////////////////////////////////////////////////////////////////////////////
import sys
import pygame as pg
from pygame.math import Vector2

pg.init()

WHITE = (255, 255, 255)
RED   = (255,   0,   0)

screen = pg.display.set_mode((500, 500))

selected_rect = None  # Currently selected rectangle.
rectangles = []
for y in range(5):
    rectangles.append(pg.Rect(20, 30*y, 17, 17))
# As a list comprehension.
# rectangles = [pg.Rect(20, 30*y, 17, 17) for y in range(5)]

clock = pg.time.Clock()
running = True

while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
        elif event.type == pg.MOUSEBUTTONDOWN:
            if event.button == 1:
                for rectangle in rectangles:
                    if rectangle.collidepoint(event.pos):
                        offset = Vector2(rectangle.topleft) - event.pos
                        selected_rect = rectangle
        elif event.type == pg.MOUSEBUTTONUP:
            if event.button == 1:
                selected_rect = None
        elif event.type == pg.MOUSEMOTION:
            if selected_rect:
                selected_rect.topleft = event.pos + offset

    screen.fill(WHITE)
    for rectangle in rectangles:
        pg.draw.rect(screen, RED, rectangle)

    pg.display.flip()
    clock.tick(30)

pg.quit()
sys.exit()
</code>```

I'm trying to create a dragable and rotatable obstacles on the panel. The obstacle consists of one or more polygons which are connected together, e.g L-shape obstacle consists of 2 rectangles. When the mouse drag the obstacles, the position information of polygons of the obstacle will be updated.

So far, I've tried to create a obstacle class, a polygon class, and a obstacle list class to record the initial position and angle of the obstacles. And I tried to create the panel using 'tkinter'.

Besides, I also see others using Pygame to implement the dragable rectangles. However, the code uses many attributes in pygame.Rect, such as collidepoint, which I'm not sure if it is also applicable to polygons as well.

Is there any suggestion that I can implement this idea? Thank you.

答:
It is minimal example to drag rect, oval and polygon in tkinter.

I use canvas's functions to create object and I get object's id which I can use to assign mouse function.

For more complex opbject it would need something more complex.

BTW: For rect,oval it needs fill color to move when you click inside object. Without fill color you have to click in border to move object.

```<code>import tkinter as tk

def on_press_tag(event, tag):
    '''start dragging'''
    global selected
    global previous_x
    global previous_y

    selected = tag
    previous_x = event.x
    previous_y = event.y

    print('press:', event, tag)

def on_release_tag(event, tag):
    '''end dragging'''
    global selected

    selected = None

    print('release:', event, tag)

def on_move_tag(event):
    '''during dragging'''
    global previous_x
    global previous_y

    #print(event.x, event.x)
    if selected:
        dx = event.x - previous_x
        dy = event.y - previous_y
        canvas.move(selected, dx, dy)
        previous_x = event.x
        previous_y = event.y

# --- main ---

# default values at start
previous_x = None
previous_y = None
selected = None

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.pack()

items = [
    canvas.create_rectangle((100, 100, 120, 120), fill="blue"),
    canvas.create_rectangle((200, 200, 220, 220), fill="red"),
    canvas.create_oval((200, 100, 220, 120), fill='green'),
    canvas.create_polygon((300, 100, 320, 120, 340, 100)),
]

for item in items:
    canvas.tag_bind(item, '<ButtonPress-1>',   lambda event, tag=item: on_press_tag(event, tag))
    canvas.tag_bind(item, '<ButtonRelease-1>', lambda event, tag=item: on_release_tag(event, tag))
    canvas.tag_bind(item, '<B1-Motion>', on_move_tag)

#canvas.bind('<B1-Motion>', on_move_tag)

root.mainloop()
</code>```

EDIT: Example which can move many objects

```<code>import tkinter as tk

class Item():

    def __init__(self, canvas, items):

        self.previous_x = None
        self.previous_y = None
        self.selected = None

        self.items = items

        for item in self.items:
            canvas.tag_bind(item, '<ButtonPress-1>',   lambda event, tag=item: self.on_press_tag(event, tag))
            canvas.tag_bind(item, '<ButtonRelease-1>', lambda event, tag=item: self.on_release_tag(event, tag))
            canvas.tag_bind(item, '<B1-Motion>', self.on_move_tag)

    def on_press_tag(self, event, tag):
        self.selected = True
        self.previous_x = event.x
        self.previous_y = event.y

        print('press:', event, tag)

    def on_release_tag(self, event, tag):
        self.selected = False
        self.previous_x = None
        self.previous_y = None

        print('release:', event, tag)

    def on_move_tag(self, event):
        #print(event.x, event.x)
        if self.selected:
            dx = event.x - self.previous_x
            dy = event.y - self.previous_y

            for item in self.items:
                canvas.move(item, dx, dy)
            self.previous_x = event.x
            self.previous_y = event.y

# --- main ---

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.pack()

items = [
            canvas.create_oval((100, 80, 120, 100), fill='green'),
            canvas.create_rectangle((100, 100, 120, 120), fill="blue"),
            canvas.create_rectangle((100, 120, 120, 140), fill="red"),
        ]
Item(canvas, items)

items = [
            canvas.create_polygon((300,  60, 320,  80, 340,  60), fill='green'),
            canvas.create_rectangle((310, 80, 330, 100), fill='red', width=0),
            canvas.create_polygon((300, 120, 320, 100, 340, 120), fill='green'),
]
Item(canvas, items)

root.mainloop()
</code>```

But using standard objects you can't rotate them. You would have to use polygon and create function which rotate it.

EDIT: I made example which can move polygon or move one of node (red rectangle) to change polygon

```<code>import tkinter as tk

class Item():

    def __init__(self, canvas, points):

        self.previous_x = None
        self.previous_y = None
        self.selected = None

        self.points = points

        # polygon
        self.polygon = canvas.create_polygon(self.points)
        canvas.tag_bind(self.polygon, '<ButtonPress-1>',   lambda event, tag=self.polygon: self.on_press_tag(event, 0, tag))
        canvas.tag_bind(self.polygon, '<ButtonRelease-1>', lambda event, tag=self.polygon: self.on_release_tag(event, 0, tag))
        canvas.tag_bind(self.polygon, '<B1-Motion>', self.on_move_polygon)

        # nodes - red rectangles
        self.nodes = []
        for number, point in enumerate(self.points):
            x, y = point
            node = canvas.create_rectangle((x-3, y-3, x+3, y+3), fill='red')
            self.nodes.append(node)
            canvas.tag_bind(node, '<ButtonPress-1>',   lambda event, number=number, tag=node: self.on_press_tag(event, number, tag))
            canvas.tag_bind(node, '<ButtonRelease-1>', lambda event, number=number, tag=node: self.on_release_tag(event, number, tag))
            canvas.tag_bind(node, '<B1-Motion>', lambda event, number=number: self.on_move_node(event, number))

    def on_press_tag(self, event, number, tag):
        self.selected = tag
        self.previous_x = event.x
        self.previous_y = event.y

        print('press:', event, tag)

    def on_release_tag(self, event, number, tag):
        self.selected = None
        self.previous_x = None
        self.previous_y = None

        print('release:', event, tag)

    def on_move_node(self, event, number):
        '''move single node in polygon'''
        if self.selected:
            dx = event.x - self.previous_x
            dy = event.y - self.previous_y

            canvas.move(self.selected, dx, dy)
            self.points[number][0] += dx
            self.points[number][1] += dy

            # flatten list of points [[x1, y1], [x2, y2], ... ] to list of numbers [x1, y1, x2, y2, ... ]
            #coords = []
            #for item in self.points:
            #    coords += item
            coords = sum(self.points, [])
            #print('coords:', coords)

            # change points in polygons
            canvas.coords(self.polygon, coords)

            self.previous_x = event.x
            self.previous_y = event.y

    def on_move_polygon(self, event):
        '''move polygon and red rectangles in nodes'''
        if self.selected:
            dx = event.x - self.previous_x
            dy = event.y - self.previous_y

            # move polygon
            canvas.move(self.selected, dx, dy)

            # move red nodes
            for item in self.nodes:
                canvas.move(item, dx, dy)

            # recalculate values in self.points
            for item in self.points:
                item[0] += dx
                item[1] += dy

            self.previous_x = event.x
            self.previous_y = event.y

# --- main ---

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.pack()

points = [[100, 60], [210, 130], [100, 200], [340, 200], [230, 130], [340, 60]]
Item(canvas, points)

root.mainloop()
</code>```

Polygon at start:

Polygon after moving nodes:

Title: Dragable and Rotatable polygon

Body:
import numpy as np
from tkinter import *
#import tkinter as tk
#from shapely.geometry import Point, Polygon

class obstaclelist:
    def __init__(self,):
        self.obsL=[]
        self.obsnums=0

    def setobnums(self,obamount):
        self.obsnums=obamount    #set number of obstacles

    def insertobs(self,newob):   #insert newly created obstacles
        self.obsL.append(newob)

class obstacleS:
    def __init__(self,):
        self.obs=[]
        self.configure=[]
        self.polynum=0
    def setobs(self,obS):       #set polygons of the obstacle
        self.obs.append(obS)
    def setconfigure(self,con):  #set initial configuration (x,y,angle)
        self.configure=con
    def setpolynum(self,numm):  #set number of polygons of an obstacle
        self.polynum=numm

class polygon:
    def __init__(self,):
        self.vertex=[]
        self.numvertex=0
    def setpoly(self,v):           #set vertexes of the polygon
        self.vertex=v
    def setvertexnum(self,numv):   #set number of vertex of a polygon
        self.numvertex=numv

class project:
    def __init__(self,):
        self.link=None
        self.layer=None
        self.root=Tk()
        self.frames =[]
        self.widgets =[]
        self.numPoly=0
        self.store=[]
        self.canvas=None
        self.halfwindow=200

    def RUN(self):
        #root=Tk()
        self.root.title("potential field")
        fullwindow=self.halfwindow*2
        self.canvas=Canvas(self.root,width=fullwindow,height=fullwindow,background='white',relief='raised',borderwidth=1)
        self.canvas.grid(row=0,column=0)
        self.canvas.config(scrollregion=self.canvas.bbox(ALL))
        self.canvas.pack()

        FR= Frame(self.root).pack(side = "bottom")

        #btn1 = Button(FR, text = "Input", fg = "Orange",command=self.numObstacle).pack(side = "left")
        #btn2 = Button(FR, text = "Build", fg = "Red",command=self.add_polygon).pack(side = "left")
        #btn3 = Button(FR, text = "Robot", fg = "Blue",command=self.add_robot).pack(side = "left")

        self.root.mainloop()

//////////////////////////////////////////////////////////////////////////////
import sys
import pygame as pg
from pygame.math import Vector2

pg.init()

WHITE = (255, 255, 255)
RED   = (255,   0,   0)

screen = pg.display.set_mode((500, 500))

selected_rect = None  # Currently selected rectangle.
rectangles = []
for y in range(5):
    rectangles.append(pg.Rect(20, 30*y, 17, 17))
# As a list comprehension.
# rectangles = [pg.Rect(20, 30*y, 17, 17) for y in range(5)]

clock = pg.time.Clock()
running = True

while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
        elif event.type == pg.MOUSEBUTTONDOWN:
            if event.button == 1:
                for rectangle in rectangles:
                    if rectangle.collidepoint(event.pos):
                        offset = Vector2(rectangle.topleft) - event.pos
                        selected_rect = rectangle
        elif event.type == pg.MOUSEBUTTONUP:
            if event.button == 1:
                selected_rect = None
        elif event.type == pg.MOUSEMOTION:
            if selected_rect:
                selected_rect.topleft = event.pos + offset

    screen.fill(WHITE)
    for rectangle in rectangles:
        pg.draw.rect(screen, RED, rectangle)

    pg.display.flip()
    clock.tick(30)

pg.quit()
sys.exit()

I'm trying to create a dragable and rotatable obstacles on the panel. The obstacle consists of one or more polygons which are connected together, e.g L-shape obstacle consists of 2 rectangles. When the mouse drag the obstacles, the position information of polygons of the obstacle will be updated.

So far, I've tried to create a obstacle class, a polygon class, and a obstacle list class to record the initial position and angle of the obstacles. And I tried to create the panel using 'tkinter'.

Besides, I also see others using Pygame to implement the dragable rectangles. However, the code uses many attributes in pygame.Rect, such as collidepoint, which I'm not sure if it is also applicable to polygons as well.

Is there any suggestion that I can implement this idea? Thank you.

Body:
It is minimal example to drag rect, oval and polygon in tkinter.

I use canvas's functions to create object and I get object's id which I can use to assign mouse function.

For more complex opbject it would need something more complex.

BTW: For rect,oval it needs fill color to move when you click inside object. Without fill color you have to click in border to move object.

import tkinter as tk

def on_press_tag(event, tag):
    '''start dragging'''
    global selected
    global previous_x
    global previous_y

    selected = tag
    previous_x = event.x
    previous_y = event.y

    print('press:', event, tag)

def on_release_tag(event, tag):
    '''end dragging'''
    global selected

    selected = None

    print('release:', event, tag)

def on_move_tag(event):
    '''during dragging'''
    global previous_x
    global previous_y

    #print(event.x, event.x)
    if selected:
        dx = event.x - previous_x
        dy = event.y - previous_y
        canvas.move(selected, dx, dy)
        previous_x = event.x
        previous_y = event.y

# --- main ---

# default values at start
previous_x = None
previous_y = None
selected = None

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.pack()

items = [
    canvas.create_rectangle((100, 100, 120, 120), fill="blue"),
    canvas.create_rectangle((200, 200, 220, 220), fill="red"),
    canvas.create_oval((200, 100, 220, 120), fill='green'),
    canvas.create_polygon((300, 100, 320, 120, 340, 100)),
]

for item in items:
    canvas.tag_bind(item, '<ButtonPress-1>',   lambda event, tag=item: on_press_tag(event, tag))
    canvas.tag_bind(item, '<ButtonRelease-1>', lambda event, tag=item: on_release_tag(event, tag))
    canvas.tag_bind(item, '<B1-Motion>', on_move_tag)

#canvas.bind('<B1-Motion>', on_move_tag)

root.mainloop()

EDIT: Example which can move many objects

import tkinter as tk

class Item():

    def __init__(self, canvas, items):

        self.previous_x = None
        self.previous_y = None
        self.selected = None

        self.items = items

        for item in self.items:
            canvas.tag_bind(item, '<ButtonPress-1>',   lambda event, tag=item: self.on_press_tag(event, tag))
            canvas.tag_bind(item, '<ButtonRelease-1>', lambda event, tag=item: self.on_release_tag(event, tag))
            canvas.tag_bind(item, '<B1-Motion>', self.on_move_tag)

    def on_press_tag(self, event, tag):
        self.selected = True
        self.previous_x = event.x
        self.previous_y = event.y

        print('press:', event, tag)

    def on_release_tag(self, event, tag):
        self.selected = False
        self.previous_x = None
        self.previous_y = None

        print('release:', event, tag)

    def on_move_tag(self, event):
        #print(event.x, event.x)
        if self.selected:
            dx = event.x - self.previous_x
            dy = event.y - self.previous_y

            for item in self.items:
                canvas.move(item, dx, dy)
            self.previous_x = event.x
            self.previous_y = event.y

# --- main ---

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.pack()

items = [
            canvas.create_oval((100, 80, 120, 100), fill='green'),
            canvas.create_rectangle((100, 100, 120, 120), fill="blue"),
            canvas.create_rectangle((100, 120, 120, 140), fill="red"),
        ]
Item(canvas, items)

items = [
            canvas.create_polygon((300,  60, 320,  80, 340,  60), fill='green'),
            canvas.create_rectangle((310, 80, 330, 100), fill='red', width=0),
            canvas.create_polygon((300, 120, 320, 100, 340, 120), fill='green'),
]
Item(canvas, items)

root.mainloop()

But using standard objects you can't rotate them. You would have to use polygon and create function which rotate it.

EDIT: I made example which can move polygon or move one of node (red rectangle) to change polygon

import tkinter as tk

class Item():

    def __init__(self, canvas, points):

        self.previous_x = None
        self.previous_y = None
        self.selected = None

        self.points = points

        # polygon
        self.polygon = canvas.create_polygon(self.points)
        canvas.tag_bind(self.polygon, '<ButtonPress-1>',   lambda event, tag=self.polygon: self.on_press_tag(event, 0, tag))
        canvas.tag_bind(self.polygon, '<ButtonRelease-1>', lambda event, tag=self.polygon: self.on_release_tag(event, 0, tag))
        canvas.tag_bind(self.polygon, '<B1-Motion>', self.on_move_polygon)

        # nodes - red rectangles
        self.nodes = []
        for number, point in enumerate(self.points):
            x, y = point
            node = canvas.create_rectangle((x-3, y-3, x+3, y+3), fill='red')
            self.nodes.append(node)
            canvas.tag_bind(node, '<ButtonPress-1>',   lambda event, number=number, tag=node: self.on_press_tag(event, number, tag))
            canvas.tag_bind(node, '<ButtonRelease-1>', lambda event, number=number, tag=node: self.on_release_tag(event, number, tag))
            canvas.tag_bind(node, '<B1-Motion>', lambda event, number=number: self.on_move_node(event, number))

    def on_press_tag(self, event, number, tag):
        self.selected = tag
        self.previous_x = event.x
        self.previous_y = event.y

        print('press:', event, tag)

    def on_release_tag(self, event, number, tag):
        self.selected = None
        self.previous_x = None
        self.previous_y = None

        print('release:', event, tag)

    def on_move_node(self, event, number):
        '''move single node in polygon'''
        if self.selected:
            dx = event.x - self.previous_x
            dy = event.y - self.previous_y

            canvas.move(self.selected, dx, dy)
            self.points[number][0] += dx
            self.points[number][1] += dy

            # flatten list of points [[x1, y1], [x2, y2], ... ] to list of numbers [x1, y1, x2, y2, ... ]
            #coords = []
            #for item in self.points:
            #    coords += item
            coords = sum(self.points, [])
            #print('coords:', coords)

            # change points in polygons
            canvas.coords(self.polygon, coords)

            self.previous_x = event.x
            self.previous_y = event.y

    def on_move_polygon(self, event):
        '''move polygon and red rectangles in nodes'''
        if self.selected:
            dx = event.x - self.previous_x
            dy = event.y - self.previous_y

            # move polygon
            canvas.move(self.selected, dx, dy)

            # move red nodes
            for item in self.nodes:
                canvas.move(item, dx, dy)

            # recalculate values in self.points
            for item in self.points:
                item[0] += dx
                item[1] += dy

            self.previous_x = event.x
            self.previous_y = event.y

# --- main ---

root = tk.Tk()

canvas = tk.Canvas(root)
canvas.pack()

points = [[100, 60], [210, 130], [100, 200], [340, 200], [230, 130], [340, 60]]
Item(canvas, points)

root.mainloop()

Polygon at start:

Polygon after moving nodes:


问:
Are member functions part of a structure in memory?
I am working on a networking application in C# for which I need to transfer a structure (It contains 3 string members).

I would also like to include member functions that test those 3 strings for validity in certain ways.

I am wondering, if I were to convert that structure (I use Marshal.StructToPtr) to bytes in order to send it over a connection, would it just convert the member variables (the 3 strings) or every function too?

答:
The application code (the IL instructions, methods, machine code, etc) is not part of any serialization process. It will only serialize the data (the fields) in there.

You can view memory as different segments where class/struct definitions are separated from the instance data.

It is a bad practice to send code over the wire for serialization purposes since it opens the remote process for executing arbitrary code.


问:
Twitter library for smalltalk
I am new to smalltalk. I have some experience in java and I am looking forward to develop a twitter client in smalltalk (pharo environment). I have done this in java with the twitter4j library but I really have no clue about how to proceed with the same in smalltalk.

Is there a twitter library available for the smalltalk platform? Would polymorph be a good choice to develop the client?

答:
Have a look at the Pier-Twitter package in http://source.lukas-renggli.ch/pier2addons. It is dedicated to Pier, but you should be able to extract what you want.

Regarding, the graphical library to develop the client, you have multiple choices. For the desktop, you may choose Polymorph. Also, you may want to have a look at Glamour which might be simpler to use (http://www.moosetechnology.org/tools/glamour). For the web, I would either choose Seaside or Aida/Web.

ContentLicense: CC BY-SA 3.0

Title: Twitter library for smalltalk


答:
You could loop through each key of the object and then assign that key to the normalized version, like this:

```<code>const generateNormalizedObj = (obj) => {
    const normalizedObj = {};
    Object.keys(obj).forEach(key => {
        normalizedObj[key] = obj[key];
    })

    return normalizedObj;
}
</code>```

Then you could simply set the namesNormalized property in the last variable to be output of that function.

Here's the final code:

```<code>const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}

const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

const normalizedPlayer = {
    ...player,
    namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}

const generateNormalizedObj = (obj) => {
    const normalizedObj = {};
    Object.keys(obj).forEach(key => {
        normalizedObj[key] = obj[key];
    })

    return normalizedObj;
}

const normalizedPlayer = {
    ...player,
    namesNormalized: generateNormalizedObj(player.names)
}
</code>```

Title: JS apply function to all values of object

Body:
You could loop through each key of the object and then assign that key to the normalized version, like this:

const generateNormalizedObj = (obj) => {
    const normalizedObj = {};
    Object.keys(obj).forEach(key => {
        normalizedObj[key] = obj[key];
    })

    return normalizedObj;
}

Then you could simply set the namesNormalized property in the last variable to be output of that function.

Here's the final code:

const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}

const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

const normalizedPlayer = {
    ...player,
    namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}

const generateNormalizedObj = (obj) => {
    const normalizedObj = {};
    Object.keys(obj).forEach(key => {
        normalizedObj[key] = obj[key];
    })

    return normalizedObj;
}

const normalizedPlayer = {
    ...player,
    namesNormalized: generateNormalizedObj(player.names)
}


问:
Changing the colour of the grey "border" on input[type=text]
Is it possible to change the colour of the grey "border" around a text input without changing the border thickness using CSS?

I initially thought that using border-color would allow me to change the colour, however, as seen in the image / code example below, changing the colour also appears to make the border thicker. I would like to keep the default width (2px) but change the colour of the border.

The image is a zoomed in screenshot of the code snippet below to highlight the apparent change in border thickness when the colour is changed.

* {
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-direction: column;
}

input[type=text] {
  flex: 1 1 0;
  margin-bottom: 2px;
}

.different_color {
  border-color: red;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <input type="text">
  <input type="text" class="different_color">
</div></code>```

Edit

To clarify, the default border, which according to the developer console has a border-width of 2px appears to be rendered as only part of the 2px whilst still essentially padding the content in by a fixed 2px. However, when I set a colour on the border, it no longer renders only this small part, but the whole 2px. The image below shows this with the left side of the image being the default border and the right side of the image being the border with the border-color set to red.

答:
You also have to specify the border style :

```<code>.specialborder{
    border: 1px solid red;
}
</code>```

Body:
Is it possible to change the colour of the grey "border" around a text input without changing the border thickness using CSS?

I initially thought that using border-color would allow me to change the colour, however, as seen in the image / code example below, changing the colour also appears to make the border thicker. I would like to keep the default width (2px) but change the colour of the border.

The image is a zoomed in screenshot of the code snippet below to highlight the apparent change in border thickness when the colour is changed.

* {
  box-sizing: border-box;
}

.container {
  display: flex;
  flex-direction: column;
}

input[type=text] {
  flex: 1 1 0;
  margin-bottom: 2px;
}

.different_color {
  border-color: red;
}

  <input type="text">
  <input type="text" class="different_color">

Edit

To clarify, the default border, which according to the developer console has a border-width of 2px appears to be rendered as only part of the 2px whilst still essentially padding the content in by a fixed 2px. However, when I set a colour on the border, it no longer renders only this small part, but the whole 2px. The image below shows this with the left side of the image being the default border and the right side of the image being the border with the border-color set to red.

Body:
You also have to specify the border style :

.specialborder{
    border: 1px solid red;
}


问:
Laravel : raw sql subquery
I know Raw statements could create SQL injection vulnerabilities ,
but i want to copy paste the subqueries from my terminal to laravel controller cause really i'm out of time and i need to hurry.

i want something like this :

```<code>$nmbrP = DB::select('SELECT count(*) from ( SELECT patient , medcine from dossier_medicals GROUP by patient having medcine = ? ) as nbr;' , [$id]);
dd($nmbrP);
</code>```

the subquery is working perfectly working in the terminal but throwing an error in the browser.

答:
try:

```<code>$nmbrP = DB::selectRaw('count(*) from ( SELECT patient , medcine from
dossier_medicals GROUP by patient having medcine = ? ) as nbr;' , [$id]);
dd($nmbrP);
</code>```

more about selectRaw in:

https://laravel.com/docs/7.x/queries#raw-methods

Title: Laravel : raw sql subquery

Body:
I know Raw statements could create SQL injection vulnerabilities ,
but i want to copy paste the subqueries from my terminal to laravel controller cause really i'm out of time and i need to hurry.

i want something like this :

$nmbrP = DB::select('SELECT count(*) from ( SELECT patient , medcine from dossier_medicals GROUP by patient having medcine = ? ) as nbr;' , [$id]);
dd($nmbrP);

the subquery is working perfectly working in the terminal but throwing an error in the browser.

Body:
try:

$nmbrP = DB::selectRaw('count(*) from ( SELECT patient , medcine from
dossier_medicals GROUP by patient having medcine = ? ) as nbr;' , [$id]);
dd($nmbrP);

more about selectRaw in:

https://laravel.com/docs/7.x/queries#raw-methods


问:
How do I print the index of the maximum and minimum values?
The following code prints the maximum and minimum value. How do I go about printing the index of those values rather than the values themselves?</p>

```<code>#include <stdio.h>

int main()
{
    int arr1[100];
    int i, mx, mn, n;

       printf("Input the number of elements to be stored in the array :");
       scanf("%d",&n);

       printf("Input %d elements in the array :\n",n);
       for(i=0;i<n;i++)
            {
          printf("element - %d : ",i);
          scanf("%d",&arr1[i]);
        }

    mx = arr1[0];
    mn = arr1[0];

    for(i=1; i<n; i++)
    {
        if(arr1[i]>mx)
        {
            mx = arr1[i];
        }

        if(arr1[i]<mn)
        {
            mn = arr1[i];
        }
    }
    printf("Maximum element is : %d\n", mx);
    printf("Minimum element is : %d\n\n", mn);

    return 0;
}
</code>```

答:
As an alternative to the previous answer, you can use pointers and pointer arithmetic:

```<code>#include <stdio.h>

int main()
{
    int arr1[100];
    int i, n;
    int *mn, *mx;

    printf("Input the number of elements to be stored in the array :");
    scanf("%d", &n);

    printf("Input %d elements in the array :\n",n);
    for(i = 0; i < n; i++)
    {
        printf("element - %d : ", i);
        scanf("%d", &arr1[i]);
    }

    mx = &arr1[0];
    mn = &arr1[0];

    for(i = 1; i < n; i++)
    {
        if(arr1[i] > *mx)
            mx = &arr1[i];

        if(arr1[i] < *mn)
            mn = &arr1[i];
    }

    printf("Maximum element is : %d (%d)\n", *mx, mx - arr1);
    printf("Minimum element is : %d (%d)\n\n", *mn, mn - arr1);

    return 0;
}
</code>```

Example:

```
$ gcc main.c -o main.exe; ./main.exe;
Input the number of elements to be stored in the array :5
Input 5 elements in the array :
element - 0 : 3
element - 1 : 2
element - 2 : 1
element - 3 : 5
element - 4 : 4
Maximum element is : 5 (3)
Minimum element is : 1 (2)
```

Body:
The following code prints the maximum and minimum value. How do I go about printing the index of those values rather than the values themselves?

#include <stdio.h>

int main()
{
    int arr1[100];
    int i, mx, mn, n;

       printf("Input the number of elements to be stored in the array :");
       scanf("%d",&n);

       printf("Input %d elements in the array :\n",n);
       for(i=0;i<n;i++)
            {
          printf("element - %d : ",i);
          scanf("%d",&arr1[i]);
        }

    mx = arr1[0];
    mn = arr1[0];

    for(i=1; i<n; i++)
    {
        if(arr1[i]>mx)
        {
            mx = arr1[i];
        }

        if(arr1[i]<mn)
        {
            mn = arr1[i];
        }
    }
    printf("Maximum element is : %d\n", mx);
    printf("Minimum element is : %d\n\n", mn);

    return 0;
}

Body:
As an alternative to the previous answer, you can use pointers and pointer arithmetic:

#include <stdio.h>

int main()
{
    int arr1[100];
    int i, n;
    int *mn, *mx;

    printf("Input the number of elements to be stored in the array :");
    scanf("%d", &n);

    printf("Input %d elements in the array :\n",n);
    for(i = 0; i < n; i++)
    {
        printf("element - %d : ", i);
        scanf("%d", &arr1[i]);
    }

    mx = &arr1[0];
    mn = &arr1[0];

    for(i = 1; i < n; i++)
    {
        if(arr1[i] > *mx)
            mx = &arr1[i];

        if(arr1[i] < *mn)
            mn = &arr1[i];
    }

    printf("Maximum element is : %d (%d)\n", *mx, mx - arr1);
    printf("Minimum element is : %d (%d)\n\n", *mn, mn - arr1);

    return 0;
}

Example:

$ gcc main.c -o main.exe; ./main.exe;
Input the number of elements to be stored in the array :5
Input 5 elements in the array :
element - 0 : 3
element - 1 : 2
element - 2 : 1
element - 3 : 5
element - 4 : 4
Maximum element is : 5 (3)
Minimum element is : 1 (2)


问:
How to capture selected Column from array
I have an array data captured from a googlesheet.

My Spreadsheet looks like this:

```<code> var ss = SpreadsheetApp.openById('19xxxxxxxxxxxxxxxxxxxxxxxOI');
 var sheet = ss.getSheetByName('Sheet2');
 var data = sheet.getDataRange.getValues();
</code>```

Now I want to filter/capture selected column:

col 1, col3, col4 and all the column where week = 5 (Col H & Col I) and class = 2.

filter method can filter the data horizontally. but how to filter vertically.

data = data.filter(function(item){return item[1] == 2}); //here I can filter where class=2

But I want to filter the column according to row 3 where week = 5.

*Note that the date Range here is just an example it could be of any size. I have date range in variables If the date as variable say  x = 2/1/2020 y =2/30/2020.

答:
I think this might work and if you want me to test it then post me some csv data of you Spreadsheet. I tested it with the data below.

```<code>function mifunc() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName("Sheet1");
  const rg=sh.getDataRange();
  var vA=rg.getDisplayValues();
  var hA1=vA.shift();//Row one
  vA.shift();
  var hA3=vA.shift();//Row three
  const idx1={};//this will return array indices when you access the properties because the properties are the strings in row
  const idx3={};
  hA1.forEach(function(h,i){idx1[h]=i;});//this does the column header to index assignment for the columns in row3
  hA3.forEach(function(h,i){idx3[h]=i;});
  var data=vA.map(function(r){if(r[idx3['Class']]==2){return [r[0],r[2],r[3],r[idx1['2/1/2020']],r[idx1['2/2/2020']]];}}).filter(function(e){return e;});
  const end="is near";//just a break point to stop on
}
</code>```

Data:

```<code>,,,,,,,2/1/2020,2/2/2020,,,,,,
,,,,,,,,,,,,,,
COL1,Class,COL3,COL4,COL5,COL6,COL7,COL8,COL9,COL10,COL11,COL12,COL13,COL14,COL15
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2,2,2,2,2,2,2,D,D,2,2,2,2,2,2
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2,2,2,2,2,2,2,D,D,2,2,2,2,2,2
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
</code>```

Result:

```<code>2,2,2,D,D
2,2,2,D,D
</code>```

This might work for your extended needs:

```<code>function mifunc() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName("Sheet1");
  const rg=sh.getRange(3,1,sh.getLastRow()-2,sh.getLastColumn());
  var vA=rg.getDisplayValues();
  var hA3=vA.shift();//Row three
  const idx3={};
  hA3.forEach(function(h,i){idx3[h]=i;});
  var data=vA.map(function(r,i){
    if(r[idx3['Class']]==2){
      const keep=new Set([0,2,3])
      var row=[];
      r.forEach(function(c,j){
        if(keep.has(j) || hA3[j]==5) {
          row.push(c);
        }
      });
    return row;
  }}).filter(function(e){return e;});
  const end="is near";//just a break point to stop on
}
</code>```

Body:
I have an array data captured from a googlesheet.

My Spreadsheet looks like this:

 var ss = SpreadsheetApp.openById('19xxxxxxxxxxxxxxxxxxxxxxxOI');
 var sheet = ss.getSheetByName('Sheet2');
 var data = sheet.getDataRange.getValues();

Now I want to filter/capture selected column:

col 1, col3, col4 and all the column where week = 5 (Col H & Col I) and class = 2.

filter method can filter the data horizontally. but how to filter vertically.

data = data.filter(function(item){return item[1] == 2}); //here I can filter where class=2

But I want to filter the column according to row 3 where week = 5.

*Note that the date Range here is just an example it could be of any size. I have date range in variables If the date as variable say  x = 2/1/2020 y =2/30/2020.

Body:
I think this might work and if you want me to test it then post me some csv data of you Spreadsheet. I tested it with the data below.

function mifunc() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName("Sheet1");
  const rg=sh.getDataRange();
  var vA=rg.getDisplayValues();
  var hA1=vA.shift();//Row one
  vA.shift();
  var hA3=vA.shift();//Row three
  const idx1={};//this will return array indices when you access the properties because the properties are the strings in row
  const idx3={};
  hA1.forEach(function(h,i){idx1[h]=i;});//this does the column header to index assignment for the columns in row3
  hA3.forEach(function(h,i){idx3[h]=i;});
  var data=vA.map(function(r){if(r[idx3['Class']]==2){return [r[0],r[2],r[3],r[idx1['2/1/2020']],r[idx1['2/2/2020']]];}}).filter(function(e){return e;});
  const end="is near";//just a break point to stop on
}

Data:

,,,,,,,2/1/2020,2/2/2020,,,,,,
,,,,,,,,,,,,,,
COL1,Class,COL3,COL4,COL5,COL6,COL7,COL8,COL9,COL10,COL11,COL12,COL13,COL14,COL15
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2,2,2,2,2,2,2,D,D,2,2,2,2,2,2
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2,2,2,2,2,2,2,D,D,2,2,2,2,2,2
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6

Result:

2,2,2,D,D
2,2,2,D,D

This might work for your extended needs:

function mifunc() {
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName("Sheet1");
  const rg=sh.getRange(3,1,sh.getLastRow()-2,sh.getLastColumn());
  var vA=rg.getDisplayValues();
  var hA3=vA.shift();//Row three
  const idx3={};
  hA3.forEach(function(h,i){idx3[h]=i;});
  var data=vA.map(function(r,i){
    if(r[idx3['Class']]==2){
      const keep=new Set([0,2,3])
      var row=[];
      r.forEach(function(c,j){
        if(keep.has(j) || hA3[j]==5) {
          row.push(c);
        }
      });
    return row;
  }}).filter(function(e){return e;});
  const end="is near";//just a break point to stop on
}


问:
Is there a way to get email or text notifications each time data is written to my Google Cloud Firestore bucket?
I have a google cloud bucket and firebase writes my app data there. I would like to monitor my data, and have any new update (write) to my firebase database it sent via a text or email to me. I currently have Twilio set up on Nodejs to send texts on Firebase and my code is:

```<code>const functions = require('firebase-functions');
var twilio = require('twilio');
const admin = require('firebase-admin');
admin.initializeApp();
var accountSid = 'account id'; // Account SID from www.twilio.com/console
var authToken = 'account token';   // Auth Token from www.twilio.com/console

var client = new twilio(accountSid, authToken);

exports.useWildcard = functions.firestore
    .document('comments/{commentContent}')
    .onWrite((change, context) => {
      client.messages.create({
    body: context.params.commentContent,
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });
</code>```

Currently, I would like to build it out for just the comments document, which are organized inside firebase through comments/{commentContent}. Later, I would like to expand to other trees. I am however, unsure if the above will run each time there is a write to my comments tree. Does it require the firebase-admin module as I have put above? Thanks!

答:
Yes, the onWrite method will not only run when there is a write to the comments tree, but will also be triggered by any change in any document and on the deletion of a document. This means that right now your code will responde in the same way to any of the above cases, and this could cause problems, especially in the case of a document being deleted since it will try to send a comment that doesent exist and will likely get some null exceptions.

Said that you have different solutions.
If you only want the function to react to a new comment, but not to an update or deletion you should use onCreate trigger instead of onWrite.

If you also want to handle a comment update notification you can use both onCreate and onUpdate, but sending different messages by doing something like:

```<code>exports.useWildcardCreate = functions.firestore
    .document('comments/{commentContent}')
    .onCreate((change, context) => {
      client.messages.create({
    body: context.params.commentContent,
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });

exports.useWildcardUpdate = functions.firestore
    .document('comments/{commentContent}')
    .onUpdate((change, context) => {

        const newComment = change.after.data();
        const previuosComment = change.before.data();

      client.messages.create({
    body: 'The comment ${previuosComment} has been changed to  ${newComment}',
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });
</code>```

At last if you also need to notify when a comment has been deleted you should use onWrite method but differentiating between the 3 different cases as shown below:

```<code>exports.useWildcard = functions.firestore
    .document('comments/{commentContent}')
    .onWrite((change, context) => {
    var textBody;
    const oldComment = change.before.data();
    const newComment = change.after.data();

    if (change.after.exists == false) { // comment has been deleted
        textBody = 'The comment ${oldComment} has been deleted';
    }
    else if (oldComment != newComment) { // comment has been updated
        textBody = 'The comment ${oldComment} has been changed to ${newComment}';
    }
    else { // if its not an update or a deletion its a new comment
        textBody = newComment;
    }
      client.messages.create({
    body: textBody,
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });
</code>```

Finally require('firebase-admin') is needed since it will allow you to interact with Firebase from privileged environments. Here you can find all the information to the Firebase Admin SDK

Body:
I have a google cloud bucket and firebase writes my app data there. I would like to monitor my data, and have any new update (write) to my firebase database it sent via a text or email to me. I currently have Twilio set up on Nodejs to send texts on Firebase and my code is:

const functions = require('firebase-functions');
var twilio = require('twilio');
const admin = require('firebase-admin');
admin.initializeApp();
var accountSid = 'account id'; // Account SID from www.twilio.com/console
var authToken = 'account token';   // Auth Token from www.twilio.com/console

var client = new twilio(accountSid, authToken);

exports.useWildcard = functions.firestore
    .document('comments/{commentContent}')
    .onWrite((change, context) => {
      client.messages.create({
    body: context.params.commentContent,
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });

Currently, I would like to build it out for just the comments document, which are organized inside firebase through comments/{commentContent}. Later, I would like to expand to other trees. I am however, unsure if the above will run each time there is a write to my comments tree. Does it require the firebase-admin module as I have put above? Thanks!

Body:
Yes, the onWrite method will not only run when there is a write to the comments tree, but will also be triggered by any change in any document and on the deletion of a document. This means that right now your code will responde in the same way to any of the above cases, and this could cause problems, especially in the case of a document being deleted since it will try to send a comment that doesent exist and will likely get some null exceptions.

Said that you have different solutions.
If you only want the function to react to a new comment, but not to an update or deletion you should use onCreate trigger instead of onWrite.

If you also want to handle a comment update notification you can use both onCreate and onUpdate, but sending different messages by doing something like:

exports.useWildcardCreate = functions.firestore
    .document('comments/{commentContent}')
    .onCreate((change, context) => {
      client.messages.create({
    body: context.params.commentContent,
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });

exports.useWildcardUpdate = functions.firestore
    .document('comments/{commentContent}')
    .onUpdate((change, context) => {

        const newComment = change.after.data();
        const previuosComment = change.before.data();

      client.messages.create({
    body: 'The comment ${previuosComment} has been changed to  ${newComment}',
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });

At last if you also need to notify when a comment has been deleted you should use onWrite method but differentiating between the 3 different cases as shown below:

exports.useWildcard = functions.firestore
    .document('comments/{commentContent}')
    .onWrite((change, context) => {
    var textBody;
    const oldComment = change.before.data();
    const newComment = change.after.data();

    if (change.after.exists == false) { // comment has been deleted
        textBody = 'The comment ${oldComment} has been deleted';
    }
    else if (oldComment != newComment) { // comment has been updated
        textBody = 'The comment ${oldComment} has been changed to ${newComment}';
    }
    else { // if its not an update or a deletion its a new comment
        textBody = newComment;
    }
      client.messages.create({
    body: textBody,
    to: '+15555555555',  // Text this number
    from: '+15555555556' // From a valid Twilio number
    })
    .then((message) => console.log(message.sid));
    });

Finally require('firebase-admin') is needed since it will allow you to interact with Firebase from privileged environments. Here you can find all the information to the Firebase Admin SDK


问:
Custom JComponent (A Line) Doesn't Show Up On JPanel
It shows the line without jpanel on jframe, but it doesn't when I add it to jpanel. I've tried setting the layout manager of jpanel to null but no result. I want to use JComponents for drawing lines because I want them clickable.

Main.java file:

```<code>import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(500, 500);

    //Parent Panel
    JPanel panel = new JPanel();
    panel.setBackground(Color.YELLOW);
    panel.setLayout(null);

    //Add Line To Panel
    Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

    panel.add(line);
    panel.repaint();

    frame.add(panel);
    frame.setVisible(true);
  }
}

class Line extends JComponent {

   private final Point2D start, end;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLUE);
        g2.setStroke(new BasicStroke(2.0F));
        g2.draw(new Line2D.Double(start,end));
    }

    public Line( Point2D start, Point2D end){
        this.start = start;
        this.end = end;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouse clicked");
            }
        });
    }
}
</code>```

答:
It shows the line without jpanel on jframe, but it doesn't when I add it to jpanel

Swing components are responsible for determining their own preferred size.

When you add a component to a panel, the layout manager will then set the size/location of the component based on the rules of the layout manager.

When you add a component to the frame you really add it to the content pane of the frame which is a Jpanel which uses a BorderLayout by default. So the component is sized to fill the space available in the frame.

```<code>panel.setLayout(null);
</code>```

You then added the component to a panel with a null layout. Now you are responsible for setting the size/location of the component. If you don't the size is (0, 0) so there is nothing to paint.

You should override the getPreferredSize() method of your class to return the preferred size of the component. Then layout managers can do their job.

If you really need a null layout, then the size of the component should be set in the application code, not it the Line class itself.

But now my line has a big container that listens for any clicks,

If you want hit detection then you override the contains(...) method.

Here is a basic example implementing the above suggestions:

```<code>import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Line extends JComponent
{
   private Line2D.Double line;

    public Line( Point2D start, Point2D end)
    {
        line = new Line2D.Double(start, end);

        addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                System.out.println("mouse clicked");
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setColor( Color.BLUE );
        g2.setStroke( new BasicStroke(2.0F) );
        g2.draw( line );
    }

    @Override
    public Dimension getPreferredSize()
    {
        Rectangle bounds = line.getBounds();

        int width = bounds.x + bounds.width;
        int height = bounds.y + bounds.height;

        return new Dimension(width, height);
    }

    @Override
    public boolean contains(int x, int y)
    {
        double distance = line.ptSegDist( new Point2D.Double(x, y) );

        return distance < 2;
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);

        //Parent Panel
        JPanel panel = new JPanel();
        panel.setBackground(Color.YELLOW);

        //Add Line To Panel
        Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

        panel.add(line);
        panel.repaint();

        frame.add(panel);
        frame.setVisible(true);
    }
}
</code>```

Body:
It shows the line without jpanel on jframe, but it doesn't when I add it to jpanel. I've tried setting the layout manager of jpanel to null but no result. I want to use JComponents for drawing lines because I want them clickable.

Main.java file:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(500, 500);

    //Parent Panel
    JPanel panel = new JPanel();
    panel.setBackground(Color.YELLOW);
    panel.setLayout(null);

    //Add Line To Panel
    Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

    panel.add(line);
    panel.repaint();

    frame.add(panel);
    frame.setVisible(true);
  }
}

class Line extends JComponent {

   private final Point2D start, end;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLUE);
        g2.setStroke(new BasicStroke(2.0F));
        g2.draw(new Line2D.Double(start,end));
    }

    public Line( Point2D start, Point2D end){
        this.start = start;
        this.end = end;
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouse clicked");
            }
        });
    }
}

Body:
It shows the line without jpanel on jframe, but it doesn't when I add it to jpanel

Swing components are responsible for determining their own preferred size.

When you add a component to a panel, the layout manager will then set the size/location of the component based on the rules of the layout manager.

When you add a component to the frame you really add it to the content pane of the frame which is a Jpanel which uses a BorderLayout by default. So the component is sized to fill the space available in the frame.

panel.setLayout(null);

You then added the component to a panel with a null layout. Now you are responsible for setting the size/location of the component. If you don't the size is (0, 0) so there is nothing to paint.

You should override the getPreferredSize() method of your class to return the preferred size of the component. Then layout managers can do their job.

If you really need a null layout, then the size of the component should be set in the application code, not it the Line class itself.

But now my line has a big container that listens for any clicks,

If you want hit detection then you override the contains(...) method.

Here is a basic example implementing the above suggestions:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Line extends JComponent
{
   private Line2D.Double line;

    public Line( Point2D start, Point2D end)
    {
        line = new Line2D.Double(start, end);

        addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                System.out.println("mouse clicked");
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        g2.setColor( Color.BLUE );
        g2.setStroke( new BasicStroke(2.0F) );
        g2.draw( line );
    }

    @Override
    public Dimension getPreferredSize()
    {
        Rectangle bounds = line.getBounds();

        int width = bounds.x + bounds.width;
        int height = bounds.y + bounds.height;

        return new Dimension(width, height);
    }

    @Override
    public boolean contains(int x, int y)
    {
        double distance = line.ptSegDist( new Point2D.Double(x, y) );

        return distance < 2;
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);

        //Parent Panel
        JPanel panel = new JPanel();
        panel.setBackground(Color.YELLOW);

        //Add Line To Panel
        Line line = new Line(new Point2D.Double(20,20), new Point2D.Double(180,180));

        panel.add(line);
        panel.repaint();

        frame.add(panel);
        frame.setVisible(true);
    }
}


答:
```<code>const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

const normalizedPlayer = {
    ...player,
    namesNormalized: Object.keys(player.names).reduce((namesNormalized, k) => {
      return {
        ...namesNormalized, // spread over previous key/value pairs
        [k]: normalizeString(player.names[k]) // store current key/value pair
      }
    }, {}) // initial value for reducer is an empty object
}
</code>```

Body:
I have an object like this:

const player = {
  id: 123,
  country: 'GB',
  names: {
    key1: 'John Paul',
    key2: 'Johny Paul',
    key3: 'Johny-paul'
  }
}

Then I want to apply a function to all names values:

const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");

const normalizedPlayer = {
    ...player,
    namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}

But I get an array of objects instead of object:

{
  id: 123,
  country: 'GB',
  names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
  namesNormalized: [
    { key1: 'John Paul' },
    { key2: 'Johny Paul' },
    { key3: 'Johny paul' }
  ]
}

I want namesNormalized like this:

 {
    id: 123,
    country: 'GB',
    names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
    namesNormalized: {
     key1: 'John Paul',
     key2: 'Johny Paul',
     key3: 'Johny paul'
   }
 }


问:
Open a word document with python using windows
I am trying to open a word document with python in windows, but I am unfamiliar with windows.

My code is as follows.

```<code>import docx as dc
doc = dc.Document(r'C:\Users\justin.white\Desktop\01100-Allergan-UD1314-SUMMARY OF WORK.docx')
</code>```

Through another post, I learned that I had to put the r in front of my string to convert it to a raw string or it would interpret the \U as an escape sequence.

The error I get is

```<code>PackageNotFoundError: Package not found at 'C:\Users\justin.white\Desktop\01100-Allergan-UD1314-SUMMARY OF WORK.docx'
</code>```

I'm unsure of why it cannot find my document, 01100-Allergan-UD1314-SUMMARY OF WORK.docx. The pathway is correct as I copied it directly from the file system.

Any help is appreciated thanks.

答:
If you want to open the document in Microsoft Word try using os.startfile().

In your example it would be:

```<code>os.startfile(r'C:\Users\justin.white\Desktop\01100-Allergan-UD1314-SUMMARY OF WORK.docx')
</code>```

This will open the document in word on your computer.

Body:
I am trying to open a word document with python in windows, but I am unfamiliar with windows.

My code is as follows.

import docx as dc
doc = dc.Document(r'C:\Users\justin.white\Desktop\01100-Allergan-UD1314-SUMMARY OF WORK.docx')

Through another post, I learned that I had to put the r in front of my string to convert it to a raw string or it would interpret the \U as an escape sequence.

The error I get is

PackageNotFoundError: Package not found at 'C:\Users\justin.white\Desktop\01100-Allergan-UD1314-SUMMARY OF WORK.docx'

I'm unsure of why it cannot find my document, 01100-Allergan-UD1314-SUMMARY OF WORK.docx. The pathway is correct as I copied it directly from the file system.

Any help is appreciated thanks.

Body:
If you want to open the document in Microsoft Word try using os.startfile().

In your example it would be:

os.startfile(r'C:\Users\justin.white\Desktop\01100-Allergan-UD1314-SUMMARY OF WORK.docx')

This will open the document in word on your computer.


问:
Simulate types of customers on a 9AM-6PM basis
I started simulating via SimPy in Python and am stuck simulating the uniformly distributed arrival of customer type A (25% of the total amount of customers), customer type B (30%), customer type C (35%) and customer type D (10%) on a daily 9AM-6PM basis.

Would anybody know how to approach this?

Thank you in advance :)

答:
Here is how I would simulate the arrival of 100 customers.

import random

p = ['A', 'B', 'C', 'D']
w = [0.25, 0.30, 0.35, 0.10]

size = 100
customers = random.choices(
    population=p,
    weights=w,
    k=size)

counts = { x: 0 for x in p }

for x in customers:
    counts[x] += 1

print({x: counts[x]/size for x in counts})
```


问:
WGET seems not to work with user data on AWS EC2 launch
I launch an centos AMI I created, and try to add user data as a file which looks like this:

```<code>#!/bin/bash
mkdir /home/centos/testing
cd testing
wget https://validlink
</code>```

So simply, on launch, the user data creates a folder called testing and downloads this validURL which I will not put as it links to my data - however it is valid and accessible.

When I launch the instance, the folder testing is created successfully, however there is no file inside the directory.

When I ssh into the instance, and run the wget command as a sudo, the file is downloaded successfully inside the testing folder.

Why does the file not get downloaded on the ec2 launch through user data?

答:
Run it using the root user.

Try this instead:

#!/bin/bash
sudo su
yum -y install wget
mkdir /home/centos/testing
cd /home/centos/testing
wget https://validlink
```

Body:
I launch an centos AMI I created, and try to add user data as a file which looks like this:

#!/bin/bash
mkdir /home/centos/testing
cd testing
wget https://validlink

So simply, on launch, the user data creates a folder called testing and downloads this validURL which I will not put as it links to my data - however it is valid and accessible.

When I launch the instance, the folder testing is created successfully, however there is no file inside the directory.

When I ssh into the instance, and run the wget command as a sudo, the file is downloaded successfully inside the testing folder.

Why does the file not get downloaded on the ec2 launch through user data?


问:
How to convert an object to a string?
I want to assign the name of the current directory to construct the path of a parallel directory (to run some diff commands).

However when I do this:

```<code>New-Item -ItemType Directory -Name my_test_dir;
Set-Location my_test_dir;
$a = $( Get-Item . | Select-Object Name );
write-host( "x${a}x" );
</code>```

I get

x@{Name=my_test_dir}x

instead of what I expected:

xmy_test_dirx

So, how do I "unbox" the name of the directory?

PS - for ease of testing I use:

```<code>mkdir my_test_dir; cd my_test_dir; $a = $( Get-Item . | Select Name ); echo "x${a}x"; cd ..; rmdir my_test_dir
</code>```

答:
When you use ... |Select-Object PropertyName, it produces an object with a property named PropertyName, copying the value from the corresponding property on the input item.

Use Select-Object -ExpandProperty PropertyName or ForEach-Object MemberName to get just the value of the property:

```<code>$a = Get-Item . | Select-Object -ExpandProperty Name
# or
$a = Get-Item . | ForEach-Object Name
</code>```

... or reference the property directly:

```<code>$a = (Get-Item .).Name
</code>```

Title: How to convert an object to a string?

Body:
I want to assign the name of the current directory to construct the path of a parallel directory (to run some diff commands).

However when I do this:

New-Item -ItemType Directory -Name my_test_dir;
Set-Location my_test_dir;
$a = $( Get-Item . | Select-Object Name );
write-host( "x${a}x" );

I get

x@{Name=my_test_dir}x

instead of what I expected:

xmy_test_dirx

So, how do I "unbox" the name of the directory?

PS - for ease of testing I use:

mkdir my_test_dir; cd my_test_dir; $a = $( Get-Item . | Select Name ); echo "x${a}x"; cd ..; rmdir my_test_dir

Body:
When you use ... |Select-Object PropertyName, it produces an object with a property named PropertyName, copying the value from the corresponding property on the input item.

Use Select-Object -ExpandProperty PropertyName or ForEach-Object MemberName to get just the value of the property:

$a = Get-Item . | Select-Object -ExpandProperty Name
# or
$a = Get-Item . | ForEach-Object Name

... or reference the property directly:

$a = (Get-Item .).Name