答:
Note: Unfortunately, part of the component in this solution won't work on older MySQL version; as OP mentioned in her previous question, she is using MySQL 5.7.

I see, in that case you can upgrade the query a bit. Let's consider that maybe the condition will change somehow to first 30 rows of data, then you might want to use prepared statement so that you don't need to keep on changing the query.

I'll be using 3 variables for this example:

a. @columns : for generating the columns SUM(CASE ...

b. @sql : for the final query.

c. @maxrows : to define the "first of xx rows".

All the variables will be set as:

```<code>SET @columns := NULL;
SET @sql := NULL;
SET @maxrows := XX; /*how many first rows*/
</code>```

Setting @columns and @sql as NULL is just a precaution, and @maxrows is just the rows you required to pivot, in your current situation it should be SET @maxrows := 20;

Setting the @columns variables.

```<code>WITH RECURSIVE cte AS (
SELECT 1 seq UNION ALL
SELECT seq+1 FROM cte WHERE seq+1 <= @maxrows)
SELECT GROUP_CONCAT(cols SEPARATOR ', \r\n')
             INTO @columns
FROM (
SELECT CONCAT('SUM(CASE WHEN rn =',seq,' THEN vals ELSE 0 END) AS "day_',seq,'"')
         AS cols
FROM cte UNION
SELECT CONCAT('SUM(CASE WHEN rn >',seq,' THEN vals ELSE 0 END) AS "day_others"')
FROM cte WHERE seq=@maxrows) c;
</code>```

There are two components here, first is using common table expression to generate row sequences based on @maxrows then the second one is concatenating the SUM(CASE .. that you have in your SELECT query. The last condition of WHEN rn > 20 is generated separately and combined using UNION with the first 20 SUM(CASE ... Lastly, the GEOUP_CONCAT() is necessary to make the generated syntax into one single row so that it can be assign to the @columns variable. Note: setting variable will only be valid if it's a single row. Otherwise, you'll get Subquery returns more than 1 row error.

 Run this query to check the @columns variable afterward: SELECT @columns;

Setting the @sql variable:

```<code>SELECT CONCAT('SELECT id,',@columns,'
FROM
(SELECT SUM(value) AS vals, id, DATE_FORMAT(date,"%Y-%m-%d") AS dt,
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS rn
FROM test_table
GROUP BY id, date) v
GROUP BY id;') INTO @sql;
</code>```

This is basically just concatenating the subquery that you already have with @columns variable and assign it to @sql variable. Check the variable: SELECT @sql;

The last part is just preparing the statement based on @sql, execute then deallocate it:

```<code>PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
</code>```

Demo fiddle with separated components and checkings..

Demo fiddle with final forms.

P/S: You should be able to copy this query and directly run it however if there's an error (other than the possible table or column names), then it's probably caused by the group_concat_max_len setting. If so, you can check the setting by running:

```<code>SHOW VARIABLES like 'group_concat_max_len';
</code>```

If it shows 1024 (in bytes), that means it's the default setting and with the operation we're going with our GROUP_CONCAT() here, it's not going to work out. Therefore, you might want to either permanently increase the value or you can add this syntax before your full query:

```<code>SET SESSION group_concat_max_len = 1000000;
</code>```

Title: how to sum value by DATE_FORMAT(date,'%Y-%m-%d'),the limit 20 sum(day by day), and sum remaining value if greater than 20?

Body:
How to sum value by DATE_FORMAT(date,'%Y-%m-%d') and id the first 20 rows of data(order by data desc), and sum the remaining value if greater than 20 else 0? supposed I have below data with below SQL, how to do it? thanks so much for any advice.

SELECT SUM(value), id, DATE_FORMAT(date,'%Y-%m-%d')
FROM test_table
GROUP BY id, DATE_FORMAT(date,'%Y-%m-%d')

sum(value)  id  DATE_FORMAT(date,'%Y-%m-%d')
--------------------------------------------
64.98   123456  2021-01-01
64.98   123456  2021-01-02
64.98   123456  2021-01-03
64.98   123456  2021-01-04
64.98   123456  2021-01-05
64.98   123456  2021-01-06
72.34   123456  2021-01-07
64.98   123456  2021-01-08
64.98   123456  2021-01-09
103.80  123456  2021-01-10
64.98   123456  2021-01-11
64.98   123456  2021-01-12
64.98   123456  2021-01-13
64.98   123456  2021-01-14
64.98   123456  2021-01-15
64.98   123456  2021-01-16
64.98   123456  2021-01-17
64.98   123456  2021-01-18
64.98   123456  2021-01-19
64.98   123456  2021-01-20
64.98   123456  2021-01-21
64.98   123456  2021-01-22
64.98   123456  2021-01-23
64.98   123456  2021-01-24
144.98  123456  2021-01-25
64.98   123456  2021-01-26
64.98   123456  2021-01-27
64.98   123456  2021-01-28
64.98   123456  2021-01-29
64.98   123456  2021-01-30
64.98   123456  2021-01-31
64.98   123456  2021-02-01
64.98   123456  2021-02-02
64.98   123456  2021-02-03
64.98   123456  2021-02-04
720.92  123456  2021-02-05
66.98   123456  2021-02-06
66.98   123456  2021-02-07
66.98   123456  2021-02-08
64.98   123456  2021-02-09
64.98   123456  2021-02-10
64.98   223456  2021-01-20
54.98   223456  2021-01-21

...................................

I need the output like below:

  id      day_1    day_2   .....  day_20   day_other
    --------------------------------------------
   123456  64.98   64.98  .....  234.67      2342.12
   223456  64.98   64.98  .....  234.67      2342.12

Body:
Note: Unfortunately, part of the component in this solution won't work on older MySQL version; as OP mentioned in her previous question, she is using MySQL 5.7.

I see, in that case you can upgrade the query a bit. Let's consider that maybe the condition will change somehow to first 30 rows of data, then you might want to use prepared statement so that you don't need to keep on changing the query.

I'll be using 3 variables for this example:

a. @columns : for generating the columns SUM(CASE ...

b. @sql : for the final query.

c. @maxrows : to define the "first of xx rows".

All the variables will be set as:

SET @columns := NULL;
SET @sql := NULL;
SET @maxrows := XX; /*how many first rows*/

Setting @columns and @sql as NULL is just a precaution, and @maxrows is just the rows you required to pivot, in your current situation it should be SET @maxrows := 20;

Setting the @columns variables.

WITH RECURSIVE cte AS (
SELECT 1 seq UNION ALL
SELECT seq+1 FROM cte WHERE seq+1 <= @maxrows)
SELECT GROUP_CONCAT(cols SEPARATOR ', \r\n')
             INTO @columns
FROM (
SELECT CONCAT('SUM(CASE WHEN rn =',seq,' THEN vals ELSE 0 END) AS "day_',seq,'"')
         AS cols
FROM cte UNION
SELECT CONCAT('SUM(CASE WHEN rn >',seq,' THEN vals ELSE 0 END) AS "day_others"')
FROM cte WHERE seq=@maxrows) c;

There are two components here, first is using common table expression to generate row sequences based on @maxrows then the second one is concatenating the SUM(CASE .. that you have in your SELECT query. The last condition of WHEN rn > 20 is generated separately and combined using UNION with the first 20 SUM(CASE ... Lastly, the GEOUP_CONCAT() is necessary to make the generated syntax into one single row so that it can be assign to the @columns variable. Note: setting variable will only be valid if it's a single row. Otherwise, you'll get Subquery returns more than 1 row error.

 Run this query to check the @columns variable afterward: SELECT @columns;

Setting the @sql variable:

SELECT CONCAT('SELECT id,',@columns,'
FROM
(SELECT SUM(value) AS vals, id, DATE_FORMAT(date,"%Y-%m-%d") AS dt,
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS rn
FROM test_table
GROUP BY id, date) v
GROUP BY id;') INTO @sql;

This is basically just concatenating the subquery that you already have with @columns variable and assign it to @sql variable. Check the variable: SELECT @sql;

The last part is just preparing the statement based on @sql, execute then deallocate it:

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Demo fiddle with separated components and checkings..

Demo fiddle with final forms.

P/S: You should be able to copy this query and directly run it however if there's an error (other than the possible table or column names), then it's probably caused by the group_concat_max_len setting. If so, you can check the setting by running:

SHOW VARIABLES like 'group_concat_max_len';

If it shows 1024 (in bytes), that means it's the default setting and with the operation we're going with our GROUP_CONCAT() here, it's not going to work out. Therefore, you might want to either permanently increase the value or you can add this syntax before your full query:

SET SESSION group_concat_max_len = 1000000;


来源: stackexchange

问:
How to replace overlapping strings in Javascript without destroying the HTML structure
I have a string and an array of N items:

sometimes the fox can fly really high

```
<pre class="lang-js prettyprint-override"><code>const arr = ['the fox can', 'fox can fly', 'really high']`
</code>```

I want to find a way to replace the text inside the div with HTML to highlight those specific phrases inside the array without breaking the HTML. This can be problematic because I can't do a simple loop and replace because then other words will not match after a replacement because the highlight span would break something like indexOf or includes on the innerHTML, sure I can use innerText to read the text but it doesn't provide anything that makes it so I can add the "next" span without breaking the original HTML highlights. Ideally, I also want to be able to customize the class name depending on the word I use rather than just a generic highlight class too.

The outcome should be

sometimes
the fox can fly really high

```
<p><strong>What have I tried?</strong></p>
<p>I've really thought about this and cannot find any resources online that help with this scenario and the main, Currently, I also need extra values such as <code>charStart</code> and <code>charEnd</code> of the word, I don't like this solution because it depends on using the <code>DOMParser()</code> API and it feels really hacky, definitely isn't performant and I just get a "vibe" that I shouldn't be doing this method and there must be better solutions, I am reaching out to SO for ideas on how I can accomplish this challenge.</p>
<pre class="lang-js prettyprint-override"><code>      let text = `<p id="content">${content}</p>`
      let parser = new DOMParser().parseFromString(text, "text/html")

      for (const str of strings) {
        const content = parser.querySelector("#content")
        let descLength = 0

        for (const node of content.childNodes) {
          const text = node.textContent

          let newTextContent = ""

          for (const letter in text) {
            let newText = text[letter]
            if (descLength === str.charStart) {
              newText = `<em class="highlight ${str.type}" data-id="${str.id}">${text[letter]}`
            } else if (descLength === str.charEnd) {
              newText = `${text[letter]}</em>`
            }

            newTextContent += newText
            descLength++
          }

          node.textContent = newTextContent
        }

        // Replace the < with `<` and replace > with `>` to construct the HTML as text inside lastHtml
        const lastHtml = parser
          .querySelector("#content")
          .outerHTML.split("<")
          .join("<")
          .split(">")
          .join(">")

        // Redefine the parser variable with the updated HTML and let it automatically correct the element structure
        parser = new DOMParser().parseFromString(lastHtml, "text/html")

        /**
         * Replace the placeholder `<em>` element with the span elements to prevent future issues. We need the HTML
         * to be invalid for it to be correctly fixed by DOMParser, otherwise the HTML would be valid and *not* render how we'd like it to
         * Invalid => `<span>test <em>title </span>here</em>
         * Invalid (converted) => `<span>test <em>title </em></span><em>here</em>
         * Valid => `<span>test <span>title </span>here</span>
         */

        parser.querySelector("#content").innerHTML = parser
          .querySelector("#content")
          .innerHTML.replaceAll("<em ", "<span ")
          .replaceAll("</em>", "</span>")
      }

</code>```

答:
I'll go over your example just to give an idea. Below code is not a clean function, please adjust it according to your needs.</p>
```<code>const str = "sometimes the fox can fly really high";
const arr = ['the fox can', 'fox can fly', 'really high'];

// First, find the indices of start and end positions for your substrings.
// Call them event points and push them to an array.
eventPoints = [];
arr.forEach((a, i) => {
  let index = strLower.indexOf(a)
  while (index !== -1) {
    let tagClass = `highlight-${i}`
    eventPoints.push({ pos: index, className: tagClass, eventType: "start" })
    eventPoints.push({ pos: index + a.length, className: tagClass, eventType: "end" })
    index = strLower.indexOf(a, index + 1)
  }
  return
});

// Sort the event points based on the position properties
eventPoints.sort((a, b) => a.pos < b.pos ? -1 : a.pos > b.pos ? 1 : 0);

// Init the final string, a stack and an index to keep track of the current position on the full string
let result = "";
let stack = [];
let index = 0;
// Loop over eventPoints
eventPoints.forEach(e => {
    // concat the substring between index and e.pos to the result
    result += str.substring(index, e.pos);
    if (e.eventType === "start") {
        // when there is a start event, open a span
        result += `<span class="${e.className}">`;
        // keep track of which span is opened
        stack.push(e.className);
    }
    else {
        // when there is an end event, close tags opened after this one, keep track of them, reopen them afterwards
        let tmpStack = [];
        while (stack.length > 0) {
            result += "</span>";
            let top = stack.pop();
            if (top === e.className) {
                break;
            }
            tmpStack.push(top);
        }
        while (tmpStack.length > 0) {
            let tmp = tmpStack.pop();
            result += `<span class="${tmp}">`;
            stack.push(tmp);
        }
    }
    index = e.pos;
});

result += str.substring(index, str.length)

console.log(result);
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a string and an array of N items:

sometimes the fox can fly really high

const arr = ['the fox can', 'fox can fly', 'really high']`

I want to find a way to replace the text inside the div with HTML to highlight those specific phrases inside the array without breaking the HTML. This can be problematic because I can't do a simple loop and replace because then other words will not match after a replacement because the highlight span would break something like indexOf or includes on the innerHTML, sure I can use innerText to read the text but it doesn't provide anything that makes it so I can add the "next" span without breaking the original HTML highlights. Ideally, I also want to be able to customize the class name depending on the word I use rather than just a generic highlight class too.

The outcome should be

sometimes
the fox can fly really high

What have I tried?

I've really thought about this and cannot find any resources online that help with this scenario and the main, Currently, I also need extra values such as charStart and charEnd of the word, I don't like this solution because it depends on using the DOMParser() API and it feels really hacky, definitely isn't performant and I just get a "vibe" that I shouldn't be doing this method and there must be better solutions, I am reaching out to SO for ideas on how I can accomplish this challenge.

      let text = `<p id="content">${content}</p>`
      let parser = new DOMParser().parseFromString(text, "text/html")

      for (const str of strings) {
        const content = parser.querySelector("#content")
        let descLength = 0

        for (const node of content.childNodes) {
          const text = node.textContent

          let newTextContent = ""

          for (const letter in text) {
            let newText = text[letter]
            if (descLength === str.charStart) {
              newText = `<em class="highlight ${str.type}" data-id="${str.id}">${text[letter]}`
            } else if (descLength === str.charEnd) {
              newText = `${text[letter]}</em>`
            }

            newTextContent += newText
            descLength++
          }

          node.textContent = newTextContent
        }

        // Replace the < with `<` and replace > with `>` to construct the HTML as text inside lastHtml
        const lastHtml = parser
          .querySelector("#content")
          .outerHTML.split("<")
          .join("<")
          .split(">")
          .join(">")

        // Redefine the parser variable with the updated HTML and let it automatically correct the element structure
        parser = new DOMParser().parseFromString(lastHtml, "text/html")

        /**
         * Replace the placeholder `<em>` element with the span elements to prevent future issues. We need the HTML
         * to be invalid for it to be correctly fixed by DOMParser, otherwise the HTML would be valid and *not* render how we'd like it to
         * Invalid => `test title here
         * Invalid (converted) => `test title here
         * Valid => `test title here
         */

        parser.querySelector("#content").innerHTML = parser
          .querySelector("#content")
          .innerHTML.replaceAll("<em ", "<span ")
          .replaceAll("", "")
      }

Body:
I'll go over your example just to give an idea. Below code is not a clean function, please adjust it according to your needs.

const str = "sometimes the fox can fly really high";
const arr = ['the fox can', 'fox can fly', 'really high'];

// First, find the indices of start and end positions for your substrings.
// Call them event points and push them to an array.
eventPoints = [];
arr.forEach((a, i) => {
  let index = strLower.indexOf(a)
  while (index !== -1) {
    let tagClass = `highlight-${i}`
    eventPoints.push({ pos: index, className: tagClass, eventType: "start" })
    eventPoints.push({ pos: index + a.length, className: tagClass, eventType: "end" })
    index = strLower.indexOf(a, index + 1)
  }
  return
});

// Sort the event points based on the position properties
eventPoints.sort((a, b) => a.pos < b.pos ? -1 : a.pos > b.pos ? 1 : 0);

// Init the final string, a stack and an index to keep track of the current position on the full string
let result = "";
let stack = [];
let index = 0;
// Loop over eventPoints
eventPoints.forEach(e => {
    // concat the substring between index and e.pos to the result
    result += str.substring(index, e.pos);
    if (e.eventType === "start") {
        // when there is a start event, open a span
        result += `<span class="${e.className}">`;
        // keep track of which span is opened
        stack.push(e.className);
    }
    else {
        // when there is an end event, close tags opened after this one, keep track of them, reopen them afterwards
        let tmpStack = [];
        while (stack.length > 0) {
            result += "</span>";
            let top = stack.pop();
            if (top === e.className) {
                break;
            }
            tmpStack.push(top);
        }
        while (tmpStack.length > 0) {
            let tmp = tmpStack.pop();
            result += `<span class="${tmp}">`;
            stack.push(tmp);
        }
    }
    index = e.pos;
});

result += str.substring(index, str.length)

console.log(result);


问:
React-Native SVG background
I'm trying to get a background pattern using an SVG in React-Native.

I have created an Component using 'react-native-svg' library as follows:

```<code>import React from "react";
import { SvgXml } from "react-native-svg";

const xml = `
  <svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'>
    <g
      fill='#ffb6c1'
      fill-opacity='0.2'
    >
      <polygon
        fill-rule='evenodd'
        points='8 4 12 6 8 8 6 12 4 8 0 6 4 4 6 0 8 4'
      />
    </g>
  </svg>
`;

export default () => <SvgXml xml={xml}  />;
</code>```

I then tried to import it into App.js as follows:

```<code>import React from 'react';
import { StyleSheet, ImageBackground, Text, View } from 'react-native';
import Header from './components/Header'
import SVG from './assets/4-point-star'

export default function App() {
  return (
    <View  style={styles.container}>
      <ImageBackground source={{uri: SVG}} style={styles.image}>
      <View>
        <Text style={styles.text}>Open up App.js to start working on your app!</Text>
      </View>
      </ImageBackground>
    </View>
  );
}

const styles = StyleSheet.create({
container: {
    flex: 1,
    backgroundColor: 'black',
    color: 'white',
    alignItems: 'center',
    justifyContent: 'center',
},
  image: {
    width: '100%',
    height: '100%',
  },
  text: {
    color: 'white'
  },
});
</code>```

However, I get the following error on the device:

Appreciate any help

Thanks

答: I had the same issue and I've discovered it happens when I run my app on web and change the view to Iphone. I'm using expo so I read the QR code with the app Expo Go and I see it perfectly. I looked everywhere and my code seemed right, i returned my SVG as a component as someone said before.</p>

Title: React-Native SVG background

Body:
I'm trying to get a background pattern using an SVG in React-Native.

I have created an Component using 'react-native-svg' library as follows:

import React from "react";
import { SvgXml } from "react-native-svg";

const xml = `
  <svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'>
    <g
      fill='#ffb6c1'
      fill-opacity='0.2'
    >
      <polygon
        fill-rule='evenodd'
        points='8 4 12 6 8 8 6 12 4 8 0 6 4 4 6 0 8 4'
      />
    </g>
  </svg>
`;

export default () => <SvgXml xml={xml}  />;

I then tried to import it into App.js as follows:

import React from 'react';
import { StyleSheet, ImageBackground, Text, View } from 'react-native';
import Header from './components/Header'
import SVG from './assets/4-point-star'

export default function App() {
  return (
    <View  style={styles.container}>
      <ImageBackground source={{uri: SVG}} style={styles.image}>
      <View>
        <Text style={styles.text}>Open up App.js to start working on your app!</Text>
      </View>
      </ImageBackground>
    </View>
  );
}

const styles = StyleSheet.create({
container: {
    flex: 1,
    backgroundColor: 'black',
    color: 'white',
    alignItems: 'center',
    justifyContent: 'center',
},
  image: {
    width: '100%',
    height: '100%',
  },
  text: {
    color: 'white'
  },
});

However, I get the following error on the device:

Appreciate any help

Thanks


问:
Why is reading a bitmap so slow in Racket?
I'm writing a CRUD app to learn Racket. Each item has an image associated with it, so I'm using read-bitmap to open the file and load the bitmap. Only one bitmap is loaded at a time, initiated by user-selection in a list-box%. Without drawing to any context, this operation takes ~5 seconds to load a 2-3MB jpeg. Why is it so slow? Is there a better way?

I figured I was doing something wrong in the application so I tried read-bitmap in DrRacket, which led to the same slowness:

#lang racket/gui
(require racket/draw)

(read-bitmap "/path/to/my.JPEG")
```

答:
FYI this was fixed in a later build. The question was using Racket v7.9, but 8.x builds fixed this.

https://github.com/racket/racket/issues/3669


问:
Running 'code .' in MacOS terminal no longer opens VSCode. Python error?
Previously, I've been able to open a directory in VS Code by running code . in the terminal. I'm not sure when it stopped working but recently it has. I'm running on MacOS 12.3 beta 2.

I have Python 3.9.10 installed via Homebrew. Brew says all the symlinks are linked but I'm not so sure. Just running regular python -V no longer is valid, I can only run via python3 -V

I have run the command from inside VS Code Shell Command: Install 'code' command in PATH multiple times to no avail.

答:
My symlink looks like this:
code -> /Users/myUserName/OtherApplications/Visual Studio Code.app/Contents/Resources/app/bin/code

Double check the path to code, which code will do it.
If that fails, then it's not in your path.

If your symlink, and your path to it are both correct you should be ready to go.  If you need to make a new symlink ln -s [file_you_want_to_link_to] [the_name_of_your_new_link]

If you need to find the executable: From your home directory (just  cd and hit enter will take you there) and if, like me, your VS Code is installed under your home directory, find ~ -type f -name code will find it.

If it's installed system-wide, then find /Applications/ -type f -name code will find it there.

Once you find the executable, use the above ln -s command to make a symlink, but do it from somewhere in your path.

I simplify my life by creating my own bin directory for all my little scripts right in my home directory.  I call mine "mybin" and used mkdir ~/mybin to create it. In my .bash_profile (in my home directory) I have a line like this: export PATH="$PATH:/Users/myUserName/homebrew/bin:/Users/myUserName/mybin"

Which is where my symlink to code lives. :)

Once you locate code and make a symlink to it somewhere in your path, code . should work again.

To make my symlink, I did this from inside
~/mybin ln -s "/Users/myUserName/OtherApplications/Visual Studio Code.app/Contents/Resources/app/bin/code" code (I needed to put the path to code in quotes because it has spaces in it).


问:
Unable to get object metadata from S3. Check object key, region and/or access permissions in aws Rekognition
```<code>import boto3

if __name__ == "__main__":

    bucket='MyBucketName'
sourceFile='pic1.jpg'
targetFile='pic2.jpg'

client=boto3.client('rekognition','us-east-1')

response=client.compare_faces(SimilarityThreshold=70,
                              SourceImage={'S3Object':{'Bucket':bucket,'Name':sourceFile}},
                              TargetImage={'S3Object':{'Bucket':bucket,'Name':targetFile}})

for faceMatch in response['FaceMatches']:
    position = faceMatch['Face']['BoundingBox']
    confidence = str(faceMatch['Face']['Confidence'])
    print('The face at ' +
           str(position['Left']) + ' ' +
           str(position['Top']) +
           ' matches with ' + confidence + '% confidence')
</code>```

I am trying to compare two images present in my bucket but no matter which region i select i always get the following error:-

botocore.errorfactory.InvalidS3ObjectException: An error occurred (InvalidS3ObjectException) when calling the CompareFaces operation: Unable to get object metadata from S3. Check object key, region and/or access permissions.

My bucket's region is us-east-1 and I have configured the same in my code.
what am I doing wrong?

答: In my case I had the path to my object prefixed with a slash (/). Removing it did the trick.</p>

Body:
import boto3

if __name__ == "__main__":

    bucket='MyBucketName'
sourceFile='pic1.jpg'
targetFile='pic2.jpg'

client=boto3.client('rekognition','us-east-1')

response=client.compare_faces(SimilarityThreshold=70,
                              SourceImage={'S3Object':{'Bucket':bucket,'Name':sourceFile}},
                              TargetImage={'S3Object':{'Bucket':bucket,'Name':targetFile}})

for faceMatch in response['FaceMatches']:
    position = faceMatch['Face']['BoundingBox']
    confidence = str(faceMatch['Face']['Confidence'])
    print('The face at ' +
           str(position['Left']) + ' ' +
           str(position['Top']) +
           ' matches with ' + confidence + '% confidence')

I am trying to compare two images present in my bucket but no matter which region i select i always get the following error:-

botocore.errorfactory.InvalidS3ObjectException: An error occurred (InvalidS3ObjectException) when calling the CompareFaces operation: Unable to get object metadata from S3. Check object key, region and/or access permissions.

My bucket's region is us-east-1 and I have configured the same in my code.
what am I doing wrong?


问:
How can I setup a persistence Python virtual environment in a Dockerfile?
I'm building Python 3.7.4 (It's a hard requirement for other software) on a base Ubuntu 20.04 image using a Dockerfile.  I'm following this guide.

Everything works fine if I run the image and follow the guide, but I want to setup my virtual environment in the Dockerfile and have the pip requirements persistent when running the image.

Here's the relevant part of my Dockerfile:

```<code>...
RUN echo =============== Building and Install Python =============== \
    && cd /tmp \
    && wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz \
    && tar xvf ./Python-3.7.4.tgz \
    && cd Python-3.7.4 \
    && ./configure --enable-optimizations --with-ensurepip=install \
    && make -j 8 \
    && sudo make install

ENV VIRTUAL_ENV=/opt/python-3.7.4
ENV PATH="$VIRTUAL_ENV:$PATH"
COPY  "./hourequirements.txt" /usr/local/
RUN echo =============== Setting up Python Virtual Environment =============== \
    && python3 -m venv $VIRTUAL_ENV \
    && source $VIRTUAL_ENV/bin/activate \
    && pip install --upgrade pip \
    && pip install --no-input -r /usr/local/hourequirements.txt
...
</code>```

The Dockerfile builds without errors, but when I run the image the environment doesn't exist and python 3.7.4 doesn't show any of the installed requirements.

How can I install Python modules in the virtual environment using PIP in the Dockerfile and have them persist when the docker image runs?

答:
Usual find answer just after post.

I changed:

```<code>ENV PATH="$VIRTUAL_ENV:$PATH"
</code>```

to:

```<code>ENV PATH="$VIRTUAL_ENV/bin:$PATH"
</code>```

in Dockerfile and started working correctly.

Body:
I'm building Python 3.7.4 (It's a hard requirement for other software) on a base Ubuntu 20.04 image using a Dockerfile.  I'm following this guide.

Everything works fine if I run the image and follow the guide, but I want to setup my virtual environment in the Dockerfile and have the pip requirements persistent when running the image.

Here's the relevant part of my Dockerfile:

...
RUN echo =============== Building and Install Python =============== \
    && cd /tmp \
    && wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz \
    && tar xvf ./Python-3.7.4.tgz \
    && cd Python-3.7.4 \
    && ./configure --enable-optimizations --with-ensurepip=install \
    && make -j 8 \
    && sudo make install

ENV VIRTUAL_ENV=/opt/python-3.7.4
ENV PATH="$VIRTUAL_ENV:$PATH"
COPY  "./hourequirements.txt" /usr/local/
RUN echo =============== Setting up Python Virtual Environment =============== \
    && python3 -m venv $VIRTUAL_ENV \
    && source $VIRTUAL_ENV/bin/activate \
    && pip install --upgrade pip \
    && pip install --no-input -r /usr/local/hourequirements.txt
...

The Dockerfile builds without errors, but when I run the image the environment doesn't exist and python 3.7.4 doesn't show any of the installed requirements.

How can I install Python modules in the virtual environment using PIP in the Dockerfile and have them persist when the docker image runs?

Body:
Usual find answer just after post.

I changed:

ENV PATH="$VIRTUAL_ENV:$PATH"

to:

ENV PATH="$VIRTUAL_ENV/bin:$PATH"

in Dockerfile and started working correctly.


问:
Java Program to sort
I'm trying to implement a code to mergeSort a list. I was told to use getFirst() and addAll() but I don't know how so this is what I came up with:

Also, I can't use a void for mergeSort method - because it gives me an error so I have to return something.

Any suggestions will be very appreciate

答:
Although there is an accepted answer, this code uses getFirst() and addAll() as mentioned in the original post, in what I assume is the intended purpose of this exercise. It uses a bottom up merge sort, which avoids the top down issue having to scan lists to find mid points to split lists.

The basic concept of a bottom up merge sort is two 1 node lists are merged to create a sorted 2 node list, two sorted 2 node lists are merged to create a sorted 4 node list, two sorted 4 node lists are merged to create a sorted 8 node list, and so on, similar to bottom up merge sort for arrays.

A bottom up merge sort uses a small array of lists (java), pointers to nodes (C), or iterators to nodes (C++) to hold the lists. For this example code, I use an array of 32 lists. For each member of array, the member is either null or refers to a list where the number of nodes for the list for array[i] has 2^i nodes: array[0] 1 node, array[1] 2 nodes, array[2] 4 nodes, ..., array[30] 2^30 = 1 billion nodes. The last member will have 2^31 = 2 billion nodes or more if the total number of nodes is >= 2^32 (4 billion) nodes.

Nodes are removed from the front of the source list one at a time and each node from the source list is used to create a list mm with 1 node, then mm is merged into the array, stopping at the first null encountered:

```<code>    while(source_list not empty){
        mm = source_list.removeNode(()   // mm = next node from source list
        for(i = 0; i < 32; i++){         // merge mm into array
            if(array[i] != null){
                mm = merge(array[i], mm)
                array[i] = null
            } else {
                break
            }
        }
        if(i == 32)    // if i == 32, there is no array[32], so
            i = 31     //  use array[31] instead
        array[i] = mm
    }
</code>```

The pattern looks like this:

```<code>mm = next node from source list  // 1 node list
array[0] = mm

mm = next node from source list  // 1 node list
mm = merge(array[0], mm)         // 2 node list
array[0] = null
array[1] = mm

mm = next node from source list  // 1 node list
array[0] = mm

mm = next node from source list  // 1 node list
mm = merge(array[0], mm)         // 2 node list
array[0] = null
mm = merge(array[1], mm)         // 4 node list
array[1] = null
array[2] = mm
</code>```

Once the last node is merged into the array, all the lists in the array are merged to form a single sorted list:

```<code>        mm = empty list
        for(i = 0; i < 32; i++){
            if(all[i] != null){
                mm = merge(all[i], mm);
                all[i] = null;    // (for garbage collection)
            }
        }
</code>```

Java's native double linked list class doesn't provide a means to move nodes within a list or between lists, so a node has to be deleted when an element is retrieved from the front of a list, and a node has to be created when an element is appended to the back of a list, an extra overhead. In the case of C++ standard double link list class std::list, std::list::splice() can be used to move nodes within a list or between lists, reducing the overhead, such as dst.splice(dst.end(), src, src.begin()), which moves the beginning node (first node) from src to the ending node (last node) of dst.

```<code>    public static LinkedList<Integer> merge(LinkedList<Integer> ll,
                                     LinkedList<Integer> rr)
    {
        if(ll.isEmpty())
            return rr;
        if(rr.isEmpty())
            return ll;
        LinkedList<Integer> mm = new LinkedList<>();
        while(true){
            if(ll.getFirst().compareTo(rr.getFirst()) <= 0){
                mm.add(ll.removeFirst());
                if(!ll.isEmpty())
                    continue;
                mm.addAll(rr);
                break;
            } else {
                mm.add(rr.removeFirst());
                if(!rr.isEmpty())
                    continue;
                mm.addAll(ll);
                break;
            }
        }
        return mm;
    }

    public static LinkedList<Integer> mergeSort(LinkedList<Integer> ll)
    {
        if(ll == null || ll.size() < 2)
            return ll;
        int i;
        final int ASZ = 32;                 // create array (of nulls)
        LinkedList<Integer>[] all= new LinkedList[ASZ];
        // merge nodes into array
        LinkedList<Integer> mm;
        do{
            mm = new LinkedList<>();        // mm = next node
            mm.add(ll.removeFirst());
                                            // merge mm into array
            for(i = 0; (i < ASZ) && (all[i] != null); i++){
                mm = merge(all[i], mm);
                all[i] = null;
            }
            if(i == ASZ)                    // don't go past end of array
                i--;
            all[i] = mm;
        }while(!ll.isEmpty());
        // merge array into single list
        mm = new LinkedList<>();
        for(i = 0; i < ASZ; i++){
            if(all[i] != null){
                mm = merge(all[i], mm);
                all[i] = null;
            }
        }
        return (mm);
    }
</code>```

test code, takes about 3 to 5 seconds to sort 4 million (2^22) nodes.

```<code>public static void main(String[] args) {
    final int COUNT = 4*1024*1024;
    LinkedList<Integer> ll = new LinkedList<>();
    Random r = new Random();
    for(int i = 0; i < COUNT; i++)
        ll.addLast(r.nextInt());
    long bgn, end;
    bgn = System.currentTimeMillis();
    ll = mergeSort(ll);
    end = System.currentTimeMillis();
    System.out.println("milliseconds " + (end-bgn));
    // check sort
    int i;
    i = ll.removeFirst();
    int j = i;
    while(!ll.isEmpty()){
        j = ll.removeFirst();
        if(i > j)
            break;
        i = j;
    }
    if(i == j)
        System.out.println("passed");
    else
        System.out.println("failed");
 }
</code>```

In the merge code, I'm getting faster and more consistent run times using a loop instead of addAll, from 3 to 5 seconds down to 2.8 to 3.2 seconds, but the assignment states to use addAll.

```<code>                //  mm.addAll(rr);    // replace with loop is faster
                do
                    mm.add(rr.removeFirst());
                while(!rr.isEmpty());
</code>```

Title: Java Program to sort

Body:
Although there is an accepted answer, this code uses getFirst() and addAll() as mentioned in the original post, in what I assume is the intended purpose of this exercise. It uses a bottom up merge sort, which avoids the top down issue having to scan lists to find mid points to split lists.

The basic concept of a bottom up merge sort is two 1 node lists are merged to create a sorted 2 node list, two sorted 2 node lists are merged to create a sorted 4 node list, two sorted 4 node lists are merged to create a sorted 8 node list, and so on, similar to bottom up merge sort for arrays.

A bottom up merge sort uses a small array of lists (java), pointers to nodes (C), or iterators to nodes (C++) to hold the lists. For this example code, I use an array of 32 lists. For each member of array, the member is either null or refers to a list where the number of nodes for the list for array[i] has 2^i nodes: array[0] 1 node, array[1] 2 nodes, array[2] 4 nodes, ..., array[30] 2^30 = 1 billion nodes. The last member will have 2^31 = 2 billion nodes or more if the total number of nodes is >= 2^32 (4 billion) nodes.

Nodes are removed from the front of the source list one at a time and each node from the source list is used to create a list mm with 1 node, then mm is merged into the array, stopping at the first null encountered:

    while(source_list not empty){
        mm = source_list.removeNode(()   // mm = next node from source list
        for(i = 0; i < 32; i++){         // merge mm into array
            if(array[i] != null){
                mm = merge(array[i], mm)
                array[i] = null
            } else {
                break
            }
        }
        if(i == 32)    // if i == 32, there is no array[32], so
            i = 31     //  use array[31] instead
        array[i] = mm
    }

The pattern looks like this:

mm = next node from source list  // 1 node list
array[0] = mm

mm = next node from source list  // 1 node list
mm = merge(array[0], mm)         // 2 node list
array[0] = null
array[1] = mm

mm = next node from source list  // 1 node list
array[0] = mm

mm = next node from source list  // 1 node list
mm = merge(array[0], mm)         // 2 node list
array[0] = null
mm = merge(array[1], mm)         // 4 node list
array[1] = null
array[2] = mm

Once the last node is merged into the array, all the lists in the array are merged to form a single sorted list:

        mm = empty list
        for(i = 0; i < 32; i++){
            if(all[i] != null){
                mm = merge(all[i], mm);
                all[i] = null;    // (for garbage collection)
            }
        }

Java's native double linked list class doesn't provide a means to move nodes within a list or between lists, so a node has to be deleted when an element is retrieved from the front of a list, and a node has to be created when an element is appended to the back of a list, an extra overhead. In the case of C++ standard double link list class std::list, std::list::splice() can be used to move nodes within a list or between lists, reducing the overhead, such as dst.splice(dst.end(), src, src.begin()), which moves the beginning node (first node) from src to the ending node (last node) of dst.

    public static LinkedList<Integer> merge(LinkedList<Integer> ll,
                                     LinkedList<Integer> rr)
    {
        if(ll.isEmpty())
            return rr;
        if(rr.isEmpty())
            return ll;
        LinkedList<Integer> mm = new LinkedList<>();
        while(true){
            if(ll.getFirst().compareTo(rr.getFirst()) <= 0){
                mm.add(ll.removeFirst());
                if(!ll.isEmpty())
                    continue;
                mm.addAll(rr);
                break;
            } else {
                mm.add(rr.removeFirst());
                if(!rr.isEmpty())
                    continue;
                mm.addAll(ll);
                break;
            }
        }
        return mm;
    }

    public static LinkedList<Integer> mergeSort(LinkedList<Integer> ll)
    {
        if(ll == null || ll.size() < 2)
            return ll;
        int i;
        final int ASZ = 32;                 // create array (of nulls)
        LinkedList<Integer>[] all= new LinkedList[ASZ];
        // merge nodes into array
        LinkedList<Integer> mm;
        do{
            mm = new LinkedList<>();        // mm = next node
            mm.add(ll.removeFirst());
                                            // merge mm into array
            for(i = 0; (i < ASZ) && (all[i] != null); i++){
                mm = merge(all[i], mm);
                all[i] = null;
            }
            if(i == ASZ)                    // don't go past end of array
                i--;
            all[i] = mm;
        }while(!ll.isEmpty());
        // merge array into single list
        mm = new LinkedList<>();
        for(i = 0; i < ASZ; i++){
            if(all[i] != null){
                mm = merge(all[i], mm);
                all[i] = null;
            }
        }
        return (mm);
    }

test code, takes about 3 to 5 seconds to sort 4 million (2^22) nodes.

public static void main(String[] args) {
    final int COUNT = 4*1024*1024;
    LinkedList<Integer> ll = new LinkedList<>();
    Random r = new Random();
    for(int i = 0; i < COUNT; i++)
        ll.addLast(r.nextInt());
    long bgn, end;
    bgn = System.currentTimeMillis();
    ll = mergeSort(ll);
    end = System.currentTimeMillis();
    System.out.println("milliseconds " + (end-bgn));
    // check sort
    int i;
    i = ll.removeFirst();
    int j = i;
    while(!ll.isEmpty()){
        j = ll.removeFirst();
        if(i > j)
            break;
        i = j;
    }
    if(i == j)
        System.out.println("passed");
    else
        System.out.println("failed");
 }

In the merge code, I'm getting faster and more consistent run times using a loop instead of addAll, from 3 to 5 seconds down to 2.8 to 3.2 seconds, but the assignment states to use addAll.

                //  mm.addAll(rr);    // replace with loop is faster
                do
                    mm.add(rr.removeFirst());
                while(!rr.isEmpty());


问:
Cannot read properties of undefined (reading 'transformFile') at Bundler.transformFile
I have updated node today and I'm getting this error:

```<code>error: TypeError: Cannot read properties of undefined (reading 'transformFile')
    at Bundler.transformFile (/Users/.../node_modules/metro/src/Bundler.js:48:30)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.transform (/Users/.../node_modules/metro/src/lib/transformHelpers.js:101:12)
    at async processModule (/Users/.../node_modules/metro/src/DeltaBundler/traverseDependencies.js:137:18)
    at async traverseDependenciesForSingleFile (/Users/.../node_modules/metro/src/DeltaBundler/traverseDependencies.js:131:3)
    at async Promise.all (index 0)
    at async initialTraverseDependencies (/Users/.../node_modules/metro/src/DeltaBundler/traverseDependencies.js:114:3)
    at async DeltaCalculator._getChangedDependencies (/Users/.../node_modules/metro/src/DeltaBundler/DeltaCalculator.js:164:25)
    at async DeltaCalculator.getDelta (/Users/.../node_modules/metro/src/DeltaBundler/DeltaCalculator.js:94:16)
</code>```

Other than that I haven't done anything unusual, so I'm not sure what to share. If I'm missing any info please comment and I'll add it.

While building the terminal also throws this error:

```<code>Failed to construct transformer:  Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)
    at stableHash (/Users/.../node_modules/metro-cache/src/stableHash.js:19:8)
    at Object.getCacheKey (/Users/.../node_modules/metro-transform-worker/src/index.js:593:7)
    at getTransformCacheKey (/Users/.../node_modules/metro/src/DeltaBundler/getTransformCacheKey.js:24:19)
    at new Transformer (/Users/.../node_modules/metro/src/DeltaBundler/Transformer.js:48:9)
    at /Users/.../node_modules/metro/src/Bundler.js:22:29
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
</code>```

My node, npx and react-native versions are:

node: 17.0.0

npx: 8.1.0

react-native-cli: 2.0.1

答:
I tried different node versions...same error.  Uninstalled and tried new versions of Android Studio...same error. Started brand new projects from scratch...same error. Deleted node_modules and ran npm i...same error.

Here's what did work for me.

Run

npx react-native info

Towards the top of that readout, it should say what Node version you are using. (it told me I was using Node: 17.xx.x in a stray node_modules folder.)

My fix was simply renaming that folder(in case deleting it breaks a different project). Now when I run npx react-native info it tells me the correct node version(16.13.1) and all my projects are running in the emulator again!

Body:
I have updated node today and I'm getting this error:

error: TypeError: Cannot read properties of undefined (reading 'transformFile')
    at Bundler.transformFile (/Users/.../node_modules/metro/src/Bundler.js:48:30)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Object.transform (/Users/.../node_modules/metro/src/lib/transformHelpers.js:101:12)
    at async processModule (/Users/.../node_modules/metro/src/DeltaBundler/traverseDependencies.js:137:18)
    at async traverseDependenciesForSingleFile (/Users/.../node_modules/metro/src/DeltaBundler/traverseDependencies.js:131:3)
    at async Promise.all (index 0)
    at async initialTraverseDependencies (/Users/.../node_modules/metro/src/DeltaBundler/traverseDependencies.js:114:3)
    at async DeltaCalculator._getChangedDependencies (/Users/.../node_modules/metro/src/DeltaBundler/DeltaCalculator.js:164:25)
    at async DeltaCalculator.getDelta (/Users/.../node_modules/metro/src/DeltaBundler/DeltaCalculator.js:94:16)

Other than that I haven't done anything unusual, so I'm not sure what to share. If I'm missing any info please comment and I'll add it.

While building the terminal also throws this error:

Failed to construct transformer:  Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)
    at stableHash (/Users/.../node_modules/metro-cache/src/stableHash.js:19:8)
    at Object.getCacheKey (/Users/.../node_modules/metro-transform-worker/src/index.js:593:7)
    at getTransformCacheKey (/Users/.../node_modules/metro/src/DeltaBundler/getTransformCacheKey.js:24:19)
    at new Transformer (/Users/.../node_modules/metro/src/DeltaBundler/Transformer.js:48:9)
    at /Users/.../node_modules/metro/src/Bundler.js:22:29
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

My node, npx and react-native versions are:

node: 17.0.0

npx: 8.1.0

react-native-cli: 2.0.1


问:
Not in table between dates
I have 2 tables :

terminal

```<code>id   text
1    abc
2    def
3    dfg
</code>```

termusage

```<code>id  termid   date
1   1        2010-11-01
2   1        2010-10-13
3   2        2010-11-10
4   3        2010-11-13
</code>```

+ many more records (10 million) approv half are within the date (2010-11-01 and 2010-12-01)

What i want to do is find the terminal.id of the records that do not exist in the termusage table between 2010-11-01 and 2010-12-01

I have looked at select where not exists but nothing is being returned - example

```<code>select * from terminal
where not exists (
select * from termusage where date between '2010-11-01' and '2010-12-01' group by termid)
</code>```

Can anyone please explain how i need to use the where not exists clause or another method !! Cheers

答:
Try:</p>

```<code>select * from terminal
    where id not in (
        select termid from usage where date between '2010-11-01' and '2010-12-01')
</code>```

ContentLicense: CC BY-SA 3.0

Title: Not in table between dates

Body:
I have 2 tables :

terminal

id   text
1    abc
2    def
3    dfg

termusage

id  termid   date
1   1        2010-11-01
2   1        2010-10-13
3   2        2010-11-10
4   3        2010-11-13

+ many more records (10 million) approv half are within the date (2010-11-01 and 2010-12-01)

What i want to do is find the terminal.id of the records that do not exist in the termusage table between 2010-11-01 and 2010-12-01

I have looked at select where not exists but nothing is being returned - example

select * from terminal
where not exists (
select * from termusage where date between '2010-11-01' and '2010-12-01' group by termid)

Can anyone please explain how i need to use the where not exists clause or another method !! Cheers

Body:
Try:

select * from terminal
    where id not in (
        select termid from usage where date between '2010-11-01' and '2010-12-01')


问:
Dart: How to sort the lists into the object tree
I have an array with a bunch of objects, where there are parentId and id parameters, how do I make a tree of nested objects, sort so that the first object is an object without parentId, and the rest are nested in it in the children field.

For example:

```<code>{
"id": 1,
"parentId": null,
"children": [
    {
      "id": 2,
      "parentId": 1,
      "children": [
        "id": 3,
        "parentId": 2,
        "children": [...]
      ] ...
    }
  ]
}
</code>```

https://dartpad.dev/?id=799b87806e56d036ba0dac7c9bebcbb2

答:
I came up with an idea, I can't really check if it works right now, but if it doesn't please let me know so we can sort out why together, recursion problems tend to be hard to think about:

```<code>
void main() {
  Object obj = getObjectChildren(objects).first;
}

List<Object> getObjectChildren(List<Object1> items, [int? currentId]) {
  // get current objects
  List<Object> objects = items
      .where((obj) => obj.parentId == currentId)
      .map((v) => Object.fromObject1(v))
      .toList();

  for (int i = 0; i < objects.length; i++) {
    // get object's children, recursively
    var children = getObjectChildren(items, objects[i].id);

    // set parent
    for (int j = 0; j < children.length; j++) {
      children[j].parent = objects[i];
    }

    // set children
    objects[i].children = children;
  }
  return objects;
}
</code>```

I also added a constructor to your Object class, it looks like this:

```<code>  Object.fromObject1(Object1 obj)
      : id = obj.id,
        parent = null,
        parentId = obj.parentId,
        children = [];
</code>```

Body:
I have an array with a bunch of objects, where there are parentId and id parameters, how do I make a tree of nested objects, sort so that the first object is an object without parentId, and the rest are nested in it in the children field.

For example:

{
"id": 1,
"parentId": null,
"children": [
    {
      "id": 2,
      "parentId": 1,
      "children": [
        "id": 3,
        "parentId": 2,
        "children": [...]
      ] ...
    }
  ]
}

https://dartpad.dev/?id=799b87806e56d036ba0dac7c9bebcbb2

Body:
I came up with an idea, I can't really check if it works right now, but if it doesn't please let me know so we can sort out why together, recursion problems tend to be hard to think about:

void main() {
  Object obj = getObjectChildren(objects).first;
}

List<Object> getObjectChildren(List<Object1> items, [int? currentId]) {
  // get current objects
  List<Object> objects = items
      .where((obj) => obj.parentId == currentId)
      .map((v) => Object.fromObject1(v))
      .toList();

  for (int i = 0; i < objects.length; i++) {
    // get object's children, recursively
    var children = getObjectChildren(items, objects[i].id);

    // set parent
    for (int j = 0; j < children.length; j++) {
      children[j].parent = objects[i];
    }

    // set children
    objects[i].children = children;
  }
  return objects;
}

I also added a constructor to your Object class, it looks like this:

  Object.fromObject1(Object1 obj)
      : id = obj.id,
        parent = null,
        parentId = obj.parentId,
        children = [];


问:
Xarray (from grib file) to dataset
I have a grib file containing monthly precipitation and temperature from 1989 to 2018 (extracted from ERA5-Land).

I need to have those data in a dataset format with 6 column : longitude, latitude, ID of the cell/point in the grib file, date, temperature and precipitation.

I first imported the file using cfgrib. Here is what contains the xdata list after importation:

```<code>import cfgrib

grib_data = cfgrib.open_datasets('\era5land_extract.grib')

grib_data
Out[6]:
[<xarray.Dataset>
 Dimensions:     (latitude: 781, longitude: 761, time: 372)
 Coordinates:
     number      int32 0
   * time        (time) datetime64[ns] 1989-01-01 1989-02-01 ... 2019-12-01
     step        timedelta64[ns] 1 days
     surface     float64 0.0
   * latitude    (latitude) float64 42.0 41.9 41.8 41.7 ... -35.8 -35.9 -36.0
   * longitude   (longitude) float64 -21.0 -20.9 -20.8 -20.7 ... 54.8 54.9 55.0
     valid_time  (time) datetime64[ns] ...
 Data variables:
     t2m         (time, latitude, longitude) float32 ...
 Attributes:
     GRIB_edition:            1
     GRIB_centre:             ecmf
     GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
     GRIB_subCentre:          0
     Conventions:             CF-1.7
     institution:             European Centre for Medium-Range Weather Forecasts,
 <xarray.Dataset>
 Dimensions:     (latitude: 781, longitude: 761, time: 156)
 Coordinates:
     number      int32 0
   * time        (time) datetime64[ns] 1989-01-01 1989-02-01 ... 2001-12-01
     step        timedelta64[ns] 1 days
     surface     float64 0.0
   * latitude    (latitude) float64 42.0 41.9 41.8 41.7 ... -35.8 -35.9 -36.0
   * longitude   (longitude) float64 -21.0 -20.9 -20.8 -20.7 ... 54.8 54.9 55.0
     valid_time  (time) datetime64[ns] ...
 Data variables:
     tp          (time, latitude, longitude) float32 ...
 Attributes:
     GRIB_edition:            1
     GRIB_centre:             ecmf
     GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
     GRIB_subCentre:          0
     Conventions:             CF-1.7
     institution:             European Centre for Medium-Range Weather Forecasts,
 <xarray.Dataset>
 Dimensions:     (latitude: 781, longitude: 761, time: 216)
 Coordinates:
     number      int32 0
   * time        (time) datetime64[ns] 2002-01-01 2002-02-01 ... 2019-12-01
     step        timedelta64[ns] 1 days
     surface     float64 0.0
   * latitude    (latitude) float64 42.0 41.9 41.8 41.7 ... -35.8 -35.9 -36.0
   * longitude   (longitude) float64 -21.0 -20.9 -20.8 -20.7 ... 54.8 54.9 55.0
     valid_time  (time) datetime64[ns] ...
 Data variables:
     tp          (time, latitude, longitude) float32 ...
 Attributes:
     GRIB_edition:            1
     GRIB_centre:             ecmf
     GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
     GRIB_subCentre:          0
     Conventions:             CF-1.7
     institution:             European Centre for Medium-Range Weather Forecasts]
</code>```

So the temperature variable is called "t2m" and the precipitation variable "tp".
Temperature variable is split in two xarrays but I don't understand why.

How can I obtain the needed dataset from this please ?

It's the first time I'm dealing with such data, and I'm really lost on how to proceed.

答:
The reason that you end up with two xarray.Datasets is because the two variables are mapped to different "hypercubes". You can open only one at a time using the backend_kwargs = {'typeOfLevel': <level>} syntax. See the docss for cfgrib here. You may want to use cfgrib.open_datasets but you can pass backend_kwargs as kwargs to xarray methods, too.

It is sometimes possible to merge variables from two hypercubes, as you seem to have found. In more complex situations, for example when there are data_vars with the same name on more than one hypercube, you will have to do some manual intervention to be able to combine the datasets.

Title: Xarray (from grib file) to dataset

Body:
I have a grib file containing monthly precipitation and temperature from 1989 to 2018 (extracted from ERA5-Land).

I need to have those data in a dataset format with 6 column : longitude, latitude, ID of the cell/point in the grib file, date, temperature and precipitation.

I first imported the file using cfgrib. Here is what contains the xdata list after importation:

import cfgrib

grib_data = cfgrib.open_datasets('\era5land_extract.grib')

grib_data
Out[6]:
[<xarray.Dataset>
 Dimensions:     (latitude: 781, longitude: 761, time: 372)
 Coordinates:
     number      int32 0
   * time        (time) datetime64[ns] 1989-01-01 1989-02-01 ... 2019-12-01
     step        timedelta64[ns] 1 days
     surface     float64 0.0
   * latitude    (latitude) float64 42.0 41.9 41.8 41.7 ... -35.8 -35.9 -36.0
   * longitude   (longitude) float64 -21.0 -20.9 -20.8 -20.7 ... 54.8 54.9 55.0
     valid_time  (time) datetime64[ns] ...
 Data variables:
     t2m         (time, latitude, longitude) float32 ...
 Attributes:
     GRIB_edition:            1
     GRIB_centre:             ecmf
     GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
     GRIB_subCentre:          0
     Conventions:             CF-1.7
     institution:             European Centre for Medium-Range Weather Forecasts,
 <xarray.Dataset>
 Dimensions:     (latitude: 781, longitude: 761, time: 156)
 Coordinates:
     number      int32 0
   * time        (time) datetime64[ns] 1989-01-01 1989-02-01 ... 2001-12-01
     step        timedelta64[ns] 1 days
     surface     float64 0.0
   * latitude    (latitude) float64 42.0 41.9 41.8 41.7 ... -35.8 -35.9 -36.0
   * longitude   (longitude) float64 -21.0 -20.9 -20.8 -20.7 ... 54.8 54.9 55.0
     valid_time  (time) datetime64[ns] ...
 Data variables:
     tp          (time, latitude, longitude) float32 ...
 Attributes:
     GRIB_edition:            1
     GRIB_centre:             ecmf
     GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
     GRIB_subCentre:          0
     Conventions:             CF-1.7
     institution:             European Centre for Medium-Range Weather Forecasts,
 <xarray.Dataset>
 Dimensions:     (latitude: 781, longitude: 761, time: 216)
 Coordinates:
     number      int32 0
   * time        (time) datetime64[ns] 2002-01-01 2002-02-01 ... 2019-12-01
     step        timedelta64[ns] 1 days
     surface     float64 0.0
   * latitude    (latitude) float64 42.0 41.9 41.8 41.7 ... -35.8 -35.9 -36.0
   * longitude   (longitude) float64 -21.0 -20.9 -20.8 -20.7 ... 54.8 54.9 55.0
     valid_time  (time) datetime64[ns] ...
 Data variables:
     tp          (time, latitude, longitude) float32 ...
 Attributes:
     GRIB_edition:            1
     GRIB_centre:             ecmf
     GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
     GRIB_subCentre:          0
     Conventions:             CF-1.7
     institution:             European Centre for Medium-Range Weather Forecasts]

So the temperature variable is called "t2m" and the precipitation variable "tp".
Temperature variable is split in two xarrays but I don't understand why.

How can I obtain the needed dataset from this please ?

It's the first time I'm dealing with such data, and I'm really lost on how to proceed.


问:
What is the platform-independent mypy type annotation for asyncio event loop?
I want to write mypy-typed code that uses asyncio and works on multiple platforms. Specifically, I often have classes and methods that explicitly bind to an event loop. I want to provide a type annotation for the event loop.

When I check the type of the asyncio event loop on Linux, I get:

```<code>>>> import asyncio
>>> type(asyncio.get_event_loop())
<class 'asyncio.unix_events._UnixSelectorEventLoop'>
</code>```

This type is clearly tied to the Unix/Linux platform.

Now, I can write code that explicitly types the event loop with this type:

import asyncio
from asyncio.unix_events import _UnixSelectorEventLoop  # type: ignore
def func(loop: _UnixSelectorEventLoop) -> None:
    print(loop)
func(asyncio.get_event_loop())
```

<p>But you'll notice that I have to include a <code># type: ignore</code> tag on the the <code>_UnixSelectorEventLoop</code> import because <code>asyncio.unix_events</code> has no type stubs. I am also hesitant to import a method that is intended to be private, as indicated by the the underscore at the start of the class name.</p>

<p>As an alternative, I can use <code>AbstractEventLoop</code> as the type:</p>

<pre class="lang-py prettyprint-override"><code>import asyncio
def func(loop: asyncio.AbstractEventLoop) -> None:
    print(loop)
func(asyncio.get_event_loop())
</code>```

And this passes a mypy type check successfully. I am hesitant to use AbstractEventLoop as my type because it is an abstract type.

Is there an alternative type signature that works across platforms, does not require the use of abstract class definitions, and passes mypy type checking?

答:
If you look at the CPython source code, AbstractEventLoop is actually the correct, OS independent definition of the event loop.

You can find the source code in question here.

So I think, you are actually right, and should feel good about this type-hint choice.

Body:
I want to write mypy-typed code that uses asyncio and works on multiple platforms. Specifically, I often have classes and methods that explicitly bind to an event loop. I want to provide a type annotation for the event loop.

When I check the type of the asyncio event loop on Linux, I get:

>>> import asyncio
>>> type(asyncio.get_event_loop())
<class 'asyncio.unix_events._UnixSelectorEventLoop'>

This type is clearly tied to the Unix/Linux platform.

Now, I can write code that explicitly types the event loop with this type:

import asyncio
from asyncio.unix_events import _UnixSelectorEventLoop  # type: ignore
def func(loop: _UnixSelectorEventLoop) -> None:
    print(loop)
func(asyncio.get_event_loop())

But you'll notice that I have to include a # type: ignore tag on the the _UnixSelectorEventLoop import because asyncio.unix_events has no type stubs. I am also hesitant to import a method that is intended to be private, as indicated by the the underscore at the start of the class name.

As an alternative, I can use AbstractEventLoop as the type:

import asyncio
def func(loop: asyncio.AbstractEventLoop) -> None:
    print(loop)
func(asyncio.get_event_loop())

And this passes a mypy type check successfully. I am hesitant to use AbstractEventLoop as my type because it is an abstract type.

Is there an alternative type signature that works across platforms, does not require the use of abstract class definitions, and passes mypy type checking?


问:
How to plot a pre-build map from google maps on a MapView
I'm trying to read a map from a link (http://maps.google.com/maps/ms?msid=216892338463540803496.000494dd57eb5ebce6db2&msa=0) and plot it on a MapView, is it possible?</p>

答:
As you posted more information in my previous answer ("but I don't want to parse the KML and plot point by point. I was wondering if theres a way to plot all at once"), I can now redifine my answer.

You should try these lines and adapt it to your needs:

```<code>Intent mapIntent = new Intent(Intent.ACTION_VIEW);
Uri uri1 = Uri.parse("geo:0,0?q=http://code.google.com/apis/kml/
documentation/KML_Samples.kml");
mapIntent.setData(uri1);
startActivity(Intent.createChooser(mapIntent, "Sample"));
</code>```

Unfortunately, you won't have any control, as this is not a MapActivity.
If you plan to add more stuff on your map, you have to try my first proposal and parse yourself the kml!

Similar question: How to use kml file on mapView in Android

Body:
As you posted more information in my previous answer ("but I don't want to parse the KML and plot point by point. I was wondering if theres a way to plot all at once"), I can now redifine my answer.

You should try these lines and adapt it to your needs:

Intent mapIntent = new Intent(Intent.ACTION_VIEW);
Uri uri1 = Uri.parse("geo:0,0?q=http://code.google.com/apis/kml/
documentation/KML_Samples.kml");
mapIntent.setData(uri1);
startActivity(Intent.createChooser(mapIntent, "Sample"));

Unfortunately, you won't have any control, as this is not a MapActivity.
If you plan to add more stuff on your map, you have to try my first proposal and parse yourself the kml!

Similar question: How to use kml file on mapView in Android


问:
Using the cosmosdb SQLAPI, I'm able to create the partitionKey and ID I'm specifying, but no other content
I'm using the CosmosDB SQLAPI to create temporary storage of debug data during email processing.  I only have less than a dozen known senders, and only a couple of hundred known recipients of that email.  So, here's my code for Upserting into Cosmos.

```<code>messageEntity.PartitionKey = $"{messageEntity.SenderAddress}.to.{messageEntity.RecipientAddress}";
messageEntity.Id = $"{messageEntity.PartitionKey}.at.{messageEntity.Timestamp}";

var result = await container.UpsertItemAsync<MessageEntity>(messageEntity);
</code>```

The result comes back Created, and I can see the key and id using the Cosmos Data Explorer.  But I do not see the rest of the messageEntity properties.

I've tried both with annotation...

```<code>[JsonObject(MemberSerialization.OptIn)]
public class MessageEntity
{
    ...
    [JsonProperty(PropertyName = "status")]
    public MessageStatus Status { get; set; }
    ...
}
</code>```

and without - it doesn't make a difference.

I'm not seing any exceptions or errors.  Any thoughts?

答: Turns out that the default format for timestamp includes illegal characters "/".  I'm surprised that I did not receive any errors.  The following format works just fine.  Timestamp.ToString("yyyy.MM.dd.HH.mm.ss.ffff")

Body:
I'm using the CosmosDB SQLAPI to create temporary storage of debug data during email processing.  I only have less than a dozen known senders, and only a couple of hundred known recipients of that email.  So, here's my code for Upserting into Cosmos.

messageEntity.PartitionKey = $"{messageEntity.SenderAddress}.to.{messageEntity.RecipientAddress}";
messageEntity.Id = $"{messageEntity.PartitionKey}.at.{messageEntity.Timestamp}";

var result = await container.UpsertItemAsync<MessageEntity>(messageEntity);

The result comes back Created, and I can see the key and id using the Cosmos Data Explorer.  But I do not see the rest of the messageEntity properties.

I've tried both with annotation...

[JsonObject(MemberSerialization.OptIn)]
public class MessageEntity
{
    ...
    [JsonProperty(PropertyName = "status")]
    public MessageStatus Status { get; set; }
    ...
}

and without - it doesn't make a difference.

I'm not seing any exceptions or errors.  Any thoughts?


问:
How can I enable Huawei Push Kit? Authentication parameters needed
I do all the steps according to the Huawei documentation
First, I enabled the Push Kit api through the Project Settings -> Manage Apis

Then I go to the Grow -> Push Kit and turn on Push Kit there, after which I turn on precise messaging:

After that, I try to enable precise messaging for my app, but instead I see this window

I did not find any information about what to write in the Authentication parameters window

答:
According to the screenshot, precision marketing has been enabled. For authentication parameters of Configure other android-based push , pls kindly check the link.

The settings do not affect the normal sending and receiving of Huawei push messages. If you are not sure whether to enable or disable the settings, you do not need to enable or configure the settings.

In addition, according to the screenshot you provided, only Setting options are available for the Push Kit service, and other notifications are unavailable. In this case, your team administrator needs to configure operation permissions for your account.


问:
how to assign data to fluent ui detailsList
i am new in PCF Control, i need to create a PCF Control Subgrid using react detailslist . the pcf should use the webAPI to make a webAPI.retrieveMultipleRecords  request and then to assign the result in the Subgrid.

maybe someone has an example for me?

Thanx

答:
Use PCF Builder for XrmToolBox and create the PCF Control with Dataset Template.

This will allow you to replace any sub grid with the PCF control and the data for the sub gird will be passed in the parameters in the context.

You also have access to the paging on the dataset.


问:
How to make a 5 stars review widget with an incremental of 0.5 in SwiftUI
I have the widget fully working with the 5 stars, the data binding and the interface as follows:

```<code>import SwiftUI

struct mainView: View {
    @State var rating: Double = 0.0
    var body: some View {
        VStack {
            RatingView(rating: $rating)
            Text("\(String(format: "%.1f", rating))")
                .font(.system(size: 30))
        }.background(.mint)
    }
}

struct RatingView: View {
    @Binding var rating: Double

    var offColor = Color.white
    var onColor = Color("AccentColor")
    var starHalf = Image(systemName: "star.leadinghalf.filled")

    var body: some View {
        HStack {
            ForEach(1..<6) { number in
                Image(systemName: "star.fill")
                    .foregroundColor(number > Int(self.rating) ? self.offColor : self.onColor)
                    .onTapGesture {
                        self.rating = Double(number)
                        selectionChanged()
                    }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        mainView()
    }
}
</code>```

Works perfect, but  have no idea how can I implement to have a 0.5 increment, and to change the icon for the half star. there is nothing like .onHelfLeftTapGesture() I can use?

答:
You can't do it reasonably with a tap gesture, unless you want to go a half star at a time. But using a different mechanism will make it flow better. Simply use a Slider with an .opacity(0.1) so it works, but is transparent, in an .overlay() that is keyed to the stars:

```<code>struct RatingsView: View {
    let ratingsArray: [Double]
    let color: Color
    @Binding var rating: Double

    init(rating: Binding<Double>, maxRating: Int = 5, starColor: Color = .yellow) {
        _rating = rating
        ratingsArray = Array(stride(from: 0.0, through: Double(max(1, maxRating)), by: 0.5))
        color = starColor
    }

    var body: some View {
        VStack {
            HStack(spacing: 0) {
                ForEach(ratingsArray, id: \.self) { ratingElement in
                    if ratingElement > 0 {
                        if Int(exactly: ratingElement) != nil && ratingElement <= rating {
                            Image(systemName: "star.fill")
                                .foregroundColor(color)
                        } else if Int(exactly: ratingElement) == nil && ratingElement == rating {
                            Image(systemName: "star.leadinghalf.fill")
                                .foregroundColor(color)
                        } else if Int(exactly: ratingElement) != nil && rating + 0.5 != ratingElement {
                            Image(systemName: "star")
                                .foregroundColor(color)
                        }
                    }
                }
            }
            .overlay(
                Slider(value: $rating, in: 0.0...ratingsArray.last!, step: 0.5)
                    .tint(.clear)
                    .opacity(0.1)
            )
        }
        .onAppear {
            rating = Int(exactly: rating) != nil ? rating : Double(Int(rating)) + 0.5
        }
    }
}
</code>```

No, I didn't just come up with this, but had come up with this before Christmas to play with the idea. This is the code I came up with.

Body:
I have the widget fully working with the 5 stars, the data binding and the interface as follows:

import SwiftUI

struct mainView: View {
    @State var rating: Double = 0.0
    var body: some View {
        VStack {
            RatingView(rating: $rating)
            Text("\(String(format: "%.1f", rating))")
                .font(.system(size: 30))
        }.background(.mint)
    }
}

struct RatingView: View {
    @Binding var rating: Double

    var offColor = Color.white
    var onColor = Color("AccentColor")
    var starHalf = Image(systemName: "star.leadinghalf.filled")

    var body: some View {
        HStack {
            ForEach(1..<6) { number in
                Image(systemName: "star.fill")
                    .foregroundColor(number > Int(self.rating) ? self.offColor : self.onColor)
                    .onTapGesture {
                        self.rating = Double(number)
                        selectionChanged()
                    }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        mainView()
    }
}

Works perfect, but  have no idea how can I implement to have a 0.5 increment, and to change the icon for the half star. there is nothing like .onHelfLeftTapGesture() I can use?

Body:
You can't do it reasonably with a tap gesture, unless you want to go a half star at a time. But using a different mechanism will make it flow better. Simply use a Slider with an .opacity(0.1) so it works, but is transparent, in an .overlay() that is keyed to the stars:

struct RatingsView: View {
    let ratingsArray: [Double]
    let color: Color
    @Binding var rating: Double

    init(rating: Binding<Double>, maxRating: Int = 5, starColor: Color = .yellow) {
        _rating = rating
        ratingsArray = Array(stride(from: 0.0, through: Double(max(1, maxRating)), by: 0.5))
        color = starColor
    }

    var body: some View {
        VStack {
            HStack(spacing: 0) {
                ForEach(ratingsArray, id: \.self) { ratingElement in
                    if ratingElement > 0 {
                        if Int(exactly: ratingElement) != nil && ratingElement <= rating {
                            Image(systemName: "star.fill")
                                .foregroundColor(color)
                        } else if Int(exactly: ratingElement) == nil && ratingElement == rating {
                            Image(systemName: "star.leadinghalf.fill")
                                .foregroundColor(color)
                        } else if Int(exactly: ratingElement) != nil && rating + 0.5 != ratingElement {
                            Image(systemName: "star")
                                .foregroundColor(color)
                        }
                    }
                }
            }
            .overlay(
                Slider(value: $rating, in: 0.0...ratingsArray.last!, step: 0.5)
                    .tint(.clear)
                    .opacity(0.1)
            )
        }
        .onAppear {
            rating = Int(exactly: rating) != nil ? rating : Double(Int(rating)) + 0.5
        }
    }
}

No, I didn't just come up with this, but had come up with this before Christmas to play with the idea. This is the code I came up with.


问:
Fails to Generate Message
My message does not display after I run the code. Need some direction, I double checked my code. Might be a syntactical error somewhere

HTML-
<!doctype html>

```<code><html>
    <head>
        <title>Message Generator</title>
        <link rel="stylesheet" href="index.css">
        <center><div class="wordart blues"><span class="text">Message Generator</span></div></center>
    </head>
    <body>
        <div class="quoteDisplay"><center>Your random message will be displayed here</center></div>
        <div id="quote">
            <!--Quote will display here-->
        </div>
        <center><button onclick="messageGenerator()">Click Here</button></center>
        <script src="index.js"></script>
    </body>
</html>
</code>```

Javascript-

```<code>const first = ["Mom", "Dad", "Uncle", "Dog", "Cat", "Brother", "Sister", "Aunt", "Random Stranger", "Respect", "Honor", "Dignity", "Brain", "Life"]
const second = ["Ocean", "Sea", "Volcano", "Tornado", "Ditch", "Cave", "Typhoon", "Asia", "India"]
const third=["Unknown","To explore","To prove a point","To live life with no constraints","Just cause"]

function randomGenerate(value) {
    var item = value[Math.floor(Math.random() * value.length)];
    return item;
}

const messageGenerator = () => {
    let person = randomGenerate(first);
    let place = randomGenerate(second);
    let reason = randomGenerate(third);
    let finalSentence = `Your ${person} jumped in the ${place}\nReason: ${reason}`;
</code>```

document.getElementById("quoteDisplay").innerHTML=finalSentence;
}

答:
document.getElementById("quoteDisplay") looks for an element with ID of "quoteDisplay". In this case, your targeted element is a class.

```<code>document.querySelector('.quoteDisplay').innerHTML = finalSentence
</code>```

Although, I think you are trying to target #quote, which in this case, getElementById is the right method but the wrong id

```<code>document.getElementById("quote").innerHTML = finalSentence;
</code>```

Title: Fails to Generate Message

Body:
My message does not display after I run the code. Need some direction, I double checked my code. Might be a syntactical error somewhere

HTML-
<!doctype html>

        <title>Message Generator</title>
        <link rel="stylesheet" href="index.css">

Message Generator

Your random message will be displayed here

        <button onclick="messageGenerator()">Click Here</button>

Javascript-

const first = ["Mom", "Dad", "Uncle", "Dog", "Cat", "Brother", "Sister", "Aunt", "Random Stranger", "Respect", "Honor", "Dignity", "Brain", "Life"]
const second = ["Ocean", "Sea", "Volcano", "Tornado", "Ditch", "Cave", "Typhoon", "Asia", "India"]
const third=["Unknown","To explore","To prove a point","To live life with no constraints","Just cause"]

function randomGenerate(value) {
    var item = value[Math.floor(Math.random() * value.length)];
    return item;
}

const messageGenerator = () => {
    let person = randomGenerate(first);
    let place = randomGenerate(second);
    let reason = randomGenerate(third);
    let finalSentence = `Your ${person} jumped in the ${place}\nReason: ${reason}`;

document.getElementById("quoteDisplay").innerHTML=finalSentence;
}

Body:
document.getElementById("quoteDisplay") looks for an element with ID of "quoteDisplay". In this case, your targeted element is a class.

document.querySelector('.quoteDisplay').innerHTML = finalSentence

Although, I think you are trying to target #quote, which in this case, getElementById is the right method but the wrong id

document.getElementById("quote").innerHTML = finalSentence;


问:
Angular mat date range picker, wait for both start and end date to be selected with form control
I have a Mat date range picker defined. With the ts code for the component, the start date and end date are form controls.

For my to get the values of the date picker, I'm using the combineLatest on the start and end date.

My problem is that when I select the very initial starting date/ending date, it is executed as expected but when I go back and modify the starting date and ending date, the combineLatest is executed immediately when I click on a starting date because the ending date already has a value.

How do I wait for both the starting date and the ending date change before execution of code?

parent ts code -

```<code>dateRangeStart: FormControl = new FormControl();
dateRangeEnd: FormControl = new FormControl();
...
...
...
combineLatest([
  this.dateRangeStart.valueChanges,
  this.dateRangeEnd.valueChanges
]).subscribe((dates) => {
    //logic
  }
})

</code>```

parent html

```<code>      <app-date-picker
        [dateRangeStart]="dateRangeStart"
        [dateRangeEnd]="dateRangeEnd">
      </app-date-picker>
</code>```

datepicker ts

```<code>  @Input() dateRangeStart!: FormControl;
  @Input() dateRangeEnd!: FormControl;
  maxDate: Date | undefined = undefined;

  constructor() { }

  ngOnInit(): void {
    this.dateRangeStart.valueChanges.subscribe(dateRangeStart => {
      if (!!dateRangeStart) {
        const maxDate = new Date(dateRangeStart);
        maxDate.setDate(maxDate.getDate() + 7);
        this.maxDate = maxDate;
      } else {
        this.maxDate = undefined;
      }
    })
  }
</code>```

datepicker html

```<code><div>
  <mat-form-field appearance="fill">
    <mat-label>Enter a date range</mat-label>
    <mat-date-range-input
      [rangePicker]="picker"
      [max]="maxDate">
      <input
        matStartDate
        [formControl]="dateRangeStart"
        placeholder="Start date">
      <input
        matEndDate
        [formControl]="dateRangeEnd"
        placeholder="End date">
    </mat-date-range-input>
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>
  </mat-form-field>
</div>
</code>```

答:
Well I'm guessing when you "go back" you re-initialize datepicker ts component and combineLatest will take last valid values from the observables and execute immediately. Some solutions for you could be to:

Flush this.dateRangeStart.valueChanges, this.dateRangeEnd.valueChanges in datepicker ts using ngOnDestroy lifecycle.

Move combineLatest itself into datepicker ts and have the parent subscribe to it.

Body:
I have a Mat date range picker defined. With the ts code for the component, the start date and end date are form controls.

For my to get the values of the date picker, I'm using the combineLatest on the start and end date.

My problem is that when I select the very initial starting date/ending date, it is executed as expected but when I go back and modify the starting date and ending date, the combineLatest is executed immediately when I click on a starting date because the ending date already has a value.

How do I wait for both the starting date and the ending date change before execution of code?

parent ts code -

dateRangeStart: FormControl = new FormControl();
dateRangeEnd: FormControl = new FormControl();
...
...
...
combineLatest([
  this.dateRangeStart.valueChanges,
  this.dateRangeEnd.valueChanges
]).subscribe((dates) => {
    //logic
  }
})

parent html

      <app-date-picker
        [dateRangeStart]="dateRangeStart"
        [dateRangeEnd]="dateRangeEnd">
      </app-date-picker>

datepicker ts

  @Input() dateRangeStart!: FormControl;
  @Input() dateRangeEnd!: FormControl;
  maxDate: Date | undefined = undefined;

  constructor() { }

  ngOnInit(): void {
    this.dateRangeStart.valueChanges.subscribe(dateRangeStart => {
      if (!!dateRangeStart) {
        const maxDate = new Date(dateRangeStart);
        maxDate.setDate(maxDate.getDate() + 7);
        this.maxDate = maxDate;
      } else {
        this.maxDate = undefined;
      }
    })
  }

datepicker html

  <mat-form-field appearance="fill">
    <mat-label>Enter a date range</mat-label>
    <mat-date-range-input
      [rangePicker]="picker"
      [max]="maxDate">
      <input
        matStartDate
        [formControl]="dateRangeStart"
        placeholder="Start date">
      <input
        matEndDate
        [formControl]="dateRangeEnd"
        placeholder="End date">
    </mat-date-range-input>
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>
  </mat-form-field>


问:
How to handle backslash character in PowerShell -replace string operations?
I am using -replace to change a path from source to destination. However I am not sure how to handle the \ character. For example:

```<code>$source = "\\somedir"
$dest = "\\anotherdir"

$test = "\\somedir\somefile"

$destfile = $test -replace $source, $dest
</code>```

After this operation, $destfile is set to

```<code>"\\\anotherdir\somefile"
</code>```

What is the correct way to do this to avoid the triple backslash in the result?

答:
I came here after having issues with Test-Path and Get-Item not working with a UNC path with spaces. Part of the problem was solved here, and the other part was solved as follows:

```<code>$OrginalPath = "\\Hostname\some\path with spaces"
$LiteralPath = $OriginalPath -replace "^\\{2}", "\\?\UNC\"
</code>```

Result:
\\?\UNC\Hostname\some\path with spaces

For completeness, putting this into Test-Path returns true (assuming that path actually exists). As @Sage Pourpre says, one needs to use -LiteralPath:

Test-Path -LiteralPath $LiteralPath
or
Get-Item -LiteralPath $LiteralPath

The replacement operator -replace uses regex.

^ means start of string.

\ is the escape character, so we escape the \ with a \.

As we have two \'s we tell regex to look for exactly 2 occurrences of \ using {2}.

Instead of using {2}, you can do what @Richard has said and use four \. One escapes the other.

Give it a try here.

Body:
I am using -replace to change a path from source to destination. However I am not sure how to handle the \ character. For example:

$source = "\\somedir"
$dest = "\\anotherdir"

$test = "\\somedir\somefile"

$destfile = $test -replace $source, $dest

After this operation, $destfile is set to

"\\\anotherdir\somefile"

What is the correct way to do this to avoid the triple backslash in the result?

Body:
I came here after having issues with Test-Path and Get-Item not working with a UNC path with spaces. Part of the problem was solved here, and the other part was solved as follows:

$OrginalPath = "\\Hostname\some\path with spaces"
$LiteralPath = $OriginalPath -replace "^\\{2}", "\\?\UNC\"

Result:
\\?\UNC\Hostname\some\path with spaces

For completeness, putting this into Test-Path returns true (assuming that path actually exists). As @Sage Pourpre says, one needs to use -LiteralPath:

Test-Path -LiteralPath $LiteralPath
or
Get-Item -LiteralPath $LiteralPath

The replacement operator -replace uses regex.

^ means start of string.

\ is the escape character, so we escape the \ with a \.

As we have two \'s we tell regex to look for exactly 2 occurrences of \ using {2}.

Instead of using {2}, you can do what @Richard has said and use four \. One escapes the other.

Give it a try here.


问:
Is there a way to achieve my Flexbox layout with calc?
I'm trying to arrange my containers with Flexbox (not Grid!) to look like this image

With the following HTML:

```<code><div class="container">
    <div class="sub-container">
        <div class="top-sub-container">
            <div class="box box-1">
                <img src="yourChoice.png" />
                <div class="box-text">
                    This is the text of the box 1
                </div>
            </div>
            <div class="box box-2">
                <img src="yourChoice.png" />
                <div class="box-text">
                    This is the text of the box 2
                </div>
            </div>
        </div>
        <div class="box box-3">
            <img src="yourChoice.png" />
            <div class="box-text">
                This is the text of the box 3
            </div>
        </div>
    </div>
    <div class="box box-4">
        <img src="yourChoice.png" />
        <div class="box-text">
            This is the text of the box 4
        </div>
    </div>
</div>
</code>```

And this CSS:

```<code>.container {
  display: flex;
  gap: 1rem;
  height: 25rem;
  width: 25rem;
  padding: 1rem;
  background: pink;
}

.top-sub-container {
  flex: 1 1 auto;
  display: flex;
  gap: 1rem;
}

.sub-container {
  flex: 1 1 auto;
  display: flex;
  gap: 1rem;
  flex-direction: column;
}

.box {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  border: 1px solid black;
}
</code>```

However I am getting stuck with my media queries and making this design responsive. Is it because I'm not using calc to evenly divide my flex items within the container? Or does calc have nothing to do with this problem?

If calc is irrelevant, how do I make this layout suitable for a media query with a max-width of 800px? When I test it out on different screen sizes using Dev Tools, there are large gaps.

I am trying to fix it by creating different media query outcomes, but now I'm wondering if there is a maximum amount of media queries I should be creating.

Your advice is gratefully appreciated.

答: You don't need to many containers, one parent div should be enough for the ".box" classed elements. With one parent, media queries would be much easier to control with different screen sizes.</p>

Body:
I'm trying to arrange my containers with Flexbox (not Grid!) to look like this image

With the following HTML:

                    This is the text of the box 1

                    This is the text of the box 2

                This is the text of the box 3

            This is the text of the box 4

And this CSS:

.container {
  display: flex;
  gap: 1rem;
  height: 25rem;
  width: 25rem;
  padding: 1rem;
  background: pink;
}

.top-sub-container {
  flex: 1 1 auto;
  display: flex;
  gap: 1rem;
}

.sub-container {
  flex: 1 1 auto;
  display: flex;
  gap: 1rem;
  flex-direction: column;
}

.box {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  border: 1px solid black;
}

However I am getting stuck with my media queries and making this design responsive. Is it because I'm not using calc to evenly divide my flex items within the container? Or does calc have nothing to do with this problem?

If calc is irrelevant, how do I make this layout suitable for a media query with a max-width of 800px? When I test it out on different screen sizes using Dev Tools, there are large gaps.

I am trying to fix it by creating different media query outcomes, but now I'm wondering if there is a maximum amount of media queries I should be creating.

Your advice is gratefully appreciated.