问:
What are the relative merits of developing Office 2007/2010 add-ins with and without VSTO?
Several years ago, I did some pretty serious Office add-in development for Office 2003 (Word, Excel and PowerPoint). I created some shared COM add-ins in C# using Visual Studio 2003. At the time, I looked at VSTO, but decided for reasons that I can't fully remember that it was not suitable for my needs.

My add-ins are due for an upgrade now, and no longer need to support Office 2003 - though they do still need to support Office 2007, not just 2010.

I know that things have moved on significantly, and that Visual Studio 2010 has better support for Office development. I'd like to determine whether I should re-implement my add-ins using VSTO, or continue with the shared COM add-in route.

If anyone knows of a nice summary of the pros and cons of each approach (beyond the marketing hype), I'd love to hear it.

Things that I found very frustrating first time around (not using VSTO, but may apply anyway):

the need to manage COM references explicitly (and call
  ReleaseComObject everywhere)

the need for a COM shim to get the security model to work

visual studio installation projects just plain didn't work; I ended
  up building my own MSI-based installer

lack of documentation, particularly on all of the above; I spent
  weeks of trial-and-error and searching random blogs; the MS-supplied
  example code completely ignored all of these real-world issues

It's also worth mentioning that minimising the amount of stuff that needs to be installed prior to my add-ins is important. I think that one of the things that put me off VSTO was the need to deploy additional stuff (though since I never went down that route I don't know if that concern was justified). And I'd really like to be able to deploy on a standard Windows 7 (or Vista) build without the need to first install (say) .NET 4.

答:
Partial answer but too long to fit in a comment:

Parts I can comment on:

Setup projects for VSTO addins now do actually work and there is a very good walkthrough available on how to create them properly.

Documentation in general of the office object model is poor imho and that should be equally annoying for com and c# development. Because a lot of the objects are now returned as dynamics if you use .net framework v4 you loose intellisense which does not help. The workaround for that is to be explicit in casting to known types where possible.

In order to run it obviously needs the relevant framework installed (v4 is FAR better for this than earlier version because of dynamics, optional arguments that were added under pressure from the office group and the NoPIA setting) Besides that it also needs the VSTO runtime installed.

All of these dependencies could be incorporated into the installer but they are required

You haven't specified what you used to create those com addins (My guess is c++ or vb6) and I can't tell how large they are and how much overhaul they need so it's not really possible to give advice if now is the time to make the change. One of the areas where moving to c# will certainly be far cleaner and nicer is anything related to ribbons. But again I can't estimate how relevant that is for you.


来源: stackexchange

问:
CodeWars Are they the same question swift
Question :

Given two arrays a and b, write a function comp(a, b) (orcompSame(a, b)) that checks whether the two arrays have the "same" elements, with the same multiplicities (the multiplicity of a member is the number of times it appears). "Same" means, here, that the elements in b are the elements in a square, regardless of the order.

Examples

Valid arrays

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [121, 14641, 20736, 361, 25921, 361, 20736, 361]

comp(a, b) returns true because in b 121 is the square of 11, 14641 is the square of 121, 20736 the square of 144, 361 the square of 19, 25921 the square of 161, and so on. It gets obvious if we write b's elements in terms of squares:

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [11*11, 121*121, 144*144, 19*19, 161*161, 19*19, 144*144, 19*19]

Invalid arrays

If, for example, we change the first number to something else, comp is not returning true anymore:

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [132, 14641, 20736, 361, 25921, 361, 20736, 361]

comp(a,b) returns false because in b 132 is not the square of any number of a.

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [121, 14641, 20736, 36100, 25921, 361, 20736, 361]

comp(a,b) returns false because in b 36100 is not the square of any number of a.

My answer is:

```<code>import SwiftUI

func comp(_ a: [Int], _ b: [Int]) -> Bool {
    var value = false
    let aSorted = a.sorted()
    let bSorted = b.sorted()
      for i in 0...a.count-1 {
          if a.count == b.count && aSorted[i] * aSorted[i] == bSorted[i] {
            value = true
        }
        else {
          value = false
        }
       }
  return value
}
</code>```

Kata says my answer is wrong but I tried this code with different arrays and it works fine. Can anybody say where is the error in my code thank you?

答:
You are trying to reimplement the == operator for Array. You don't need to do that.

func comp<Numbers: Sequence>(_ a: Numbers, _ b: Numbers) -> Bool
where Numbers.Element: Numeric & Comparable {
  a.sorted().map(\.squared) == b.sorted()
}
```
<pre class="lang-swift prettyprint-override"><code>public extension Numeric {
  var squared: Self { self * self }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Question :

Given two arrays a and b, write a function comp(a, b) (orcompSame(a, b)) that checks whether the two arrays have the "same" elements, with the same multiplicities (the multiplicity of a member is the number of times it appears). "Same" means, here, that the elements in b are the elements in a square, regardless of the order.

Examples

Valid arrays

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [121, 14641, 20736, 361, 25921, 361, 20736, 361]

comp(a, b) returns true because in b 121 is the square of 11, 14641 is the square of 121, 20736 the square of 144, 361 the square of 19, 25921 the square of 161, and so on. It gets obvious if we write b's elements in terms of squares:

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [11*11, 121*121, 144*144, 19*19, 161*161, 19*19, 144*144, 19*19]

Invalid arrays

If, for example, we change the first number to something else, comp is not returning true anymore:

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [132, 14641, 20736, 361, 25921, 361, 20736, 361]

comp(a,b) returns false because in b 132 is not the square of any number of a.

a = [121, 144, 19, 161, 19, 144, 19, 11]

b = [121, 14641, 20736, 36100, 25921, 361, 20736, 361]

comp(a,b) returns false because in b 36100 is not the square of any number of a.

My answer is:

import SwiftUI

func comp(_ a: [Int], _ b: [Int]) -> Bool {
    var value = false
    let aSorted = a.sorted()
    let bSorted = b.sorted()
      for i in 0...a.count-1 {
          if a.count == b.count && aSorted[i] * aSorted[i] == bSorted[i] {
            value = true
        }
        else {
          value = false
        }
       }
  return value
}

Kata says my answer is wrong but I tried this code with different arrays and it works fine. Can anybody say where is the error in my code thank you?

Body:
You are trying to reimplement the == operator for Array. You don't need to do that.

func comp<Numbers: Sequence>(_ a: Numbers, _ b: Numbers) -> Bool
where Numbers.Element: Numeric & Comparable {
  a.sorted().map(\.squared) == b.sorted()
}

public extension Numeric {
  var squared: Self { self * self }
}


问:
JS: No contents in array from parent class
I am using two classes in javascript.

class Challenge and class Modules, that extends Challenge.

in Challenge i have this constructor:

```<code>constructor() {
    this.handles = [];
}
</code>```

and this method:

```<code>bla() {

    let elmnts = document.querySelectorAll("p"); // 5x

        for(let i=0; i < elmnts.length; i++) {

            let elmnt = elmnts[i];
            this.handles[elmnt['id']] = elmnt; // saves the handles to each element in separate array for later use

        }

}
</code>```

in the child Class i am trying to use this "this.handles" array, but it is always empty.

It is not "undefined" but it is an empty array as i defined it in the constructor. its like the entries have never been set... but they are (as console.log() shows, when i insert it directly after the for()-loop)

```<code>console.log(this.handles); // --> []
</code>```

Why does this happen?

答:
You need to understand the following things:

In Javascript...

... Arrays are always index-based (0 pointing to the first array element).

... you append elements to an array using arr.push(el).

... Arrays are also objects, so adding arbitrary properties also works (which is what you are doing by using the p element id as a key and assigning it the element reference). See this example:

If you need an array (which preserves order and can easily be iterated later on), just spread the NodeList you got from querySelectorAll('p') into the array using the ES6 spread syntax ...:

```<code>this.handles = [...document.querySelectorAll("p")];
</code>```

Body:
I am using two classes in javascript.

class Challenge and class Modules, that extends Challenge.

in Challenge i have this constructor:

constructor() {
    this.handles = [];
}

and this method:

bla() {

    let elmnts = document.querySelectorAll("p"); // 5x

        for(let i=0; i < elmnts.length; i++) {

            let elmnt = elmnts[i];
            this.handles[elmnt['id']] = elmnt; // saves the handles to each element in separate array for later use

        }

}

in the child Class i am trying to use this "this.handles" array, but it is always empty.

It is not "undefined" but it is an empty array as i defined it in the constructor. its like the entries have never been set... but they are (as console.log() shows, when i insert it directly after the for()-loop)

console.log(this.handles); // --> []

Why does this happen?

Body:
You need to understand the following things:

In Javascript...

... Arrays are always index-based (0 pointing to the first array element).

... you append elements to an array using arr.push(el).

... Arrays are also objects, so adding arbitrary properties also works (which is what you are doing by using the p element id as a key and assigning it the element reference). See this example:

If you need an array (which preserves order and can easily be iterated later on), just spread the NodeList you got from querySelectorAll('p') into the array using the ES6 spread syntax ...:

this.handles = [...document.querySelectorAll("p")];


问:
AWX- provide response file
I have a project using playbook to exec shell command as following:

```<code>/tmp/fileforinst.bin -varfile response.varfile
</code>```

While I exec the shell command I provide response.varfile for installation purpose that includes some entries like target installation directory, app port, etc... The response.varfile format is like:

app.Home=/app/home
httpPort=8080
```

Currently I get the following error

"Could not find or access 'runner/project/response.varfile' on the Ansible Controller"

The reason why I get the error is clear for me. The required response.varfile file exist in GIT sever on same branch as yml file (playbook)

Any idea how can I provide response.varfile file while I exec the shell command ?

Thank you

答:
The required response.varfile file exist in Git sever on same branch as YML file (playbook)

Assuming you have a somehow similar structure in your Git repository for your role

```<code>tree APP/
├── files
├── main.yml
├── README.md
├── tasks
│   └── install_app.yml
└── templates
    └── response.file.j2
</code>```

importing the Project from Git into your Ansible AWX/Tower, than, the file is just available via the templates or files path.

- name: Download installer from binary repository
  get_url:
    url: "https://{{ REPOSITORY_URL }}/Packages/{{ INSTALLER_FILE }}"
    url_username: "{{ API_USER }}"
    url_password: "{{ API_KEY }}"
    dest: "/opt/app"
    owner: "{{ APP_USER }}"
    group: "{{ APP_GROUP }}"
    mode: 0750

- name: Copy response file for unattended installation
  template:
    src: "response.file.j2"
    dest: "/opt/app/response.file"
    owner: "{{ APP_USER }}"
    group: "{{ APP_GROUP }}"
    mode: 0750

- name: Install App
  shell:
    cmd: "/opt/app/{{ INSTALLER_FILE }} -q -varfile /opt/app/response.file"
  register: install_result

- name: Show install result
  debug:
    msg: "{{ install_result.stdout_lines }}"
```

This is almost what I am using in my production environment to install and update the "App". In words, you have to copy the file over form Ansible Control Node to the Remote Node where the installation shall happen.

Further reading

Template a file out to a target host

Directory layout

Title: AWX- provide response file

Body:
I have a project using playbook to exec shell command as following:

/tmp/fileforinst.bin -varfile response.varfile

While I exec the shell command I provide response.varfile for installation purpose that includes some entries like target installation directory, app port, etc... The response.varfile format is like:

app.Home=/app/home
httpPort=8080

Currently I get the following error

"Could not find or access 'runner/project/response.varfile' on the Ansible Controller"

The reason why I get the error is clear for me. The required response.varfile file exist in GIT sever on same branch as yml file (playbook)

Any idea how can I provide response.varfile file while I exec the shell command ?

Thank you

Body:
The required response.varfile file exist in Git sever on same branch as YML file (playbook)

Assuming you have a somehow similar structure in your Git repository for your role

tree APP/
├── files
├── main.yml
├── README.md
├── tasks
│   └── install_app.yml
└── templates
    └── response.file.j2

importing the Project from Git into your Ansible AWX/Tower, than, the file is just available via the templates or files path.

- name: Download installer from binary repository
  get_url:
    url: "https://{{ REPOSITORY_URL }}/Packages/{{ INSTALLER_FILE }}"
    url_username: "{{ API_USER }}"
    url_password: "{{ API_KEY }}"
    dest: "/opt/app"
    owner: "{{ APP_USER }}"
    group: "{{ APP_GROUP }}"
    mode: 0750

- name: Copy response file for unattended installation
  template:
    src: "response.file.j2"
    dest: "/opt/app/response.file"
    owner: "{{ APP_USER }}"
    group: "{{ APP_GROUP }}"
    mode: 0750

- name: Install App
  shell:
    cmd: "/opt/app/{{ INSTALLER_FILE }} -q -varfile /opt/app/response.file"
  register: install_result

- name: Show install result
  debug:
    msg: "{{ install_result.stdout_lines }}"

This is almost what I am using in my production environment to install and update the "App". In words, you have to copy the file over form Ansible Control Node to the Remote Node where the installation shall happen.

Further reading

Template a file out to a target host

Directory layout


问:
Map is not visible at initialization using react-leaflet
I have this react component:

```<code>import React, { Fragment } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

const customMarker = new L.icon({
    iconUrl: '/images/poemEditorTools/location-pointer-new.svg',
    iconSize: [56, 72],
    iconAnchor: [26, 72],
});

const MyPopupMarker = ({ content, position }) => (
    <Marker position={position} icon={customMarker} >
      <Popup>{content}</Popup>
    </Marker>
)

const MyMarkersList = ({ markers }) => {
    const items = markers.map(({ key, ...props }) => (
        <MyPopupMarker key={key} {...props} />
    ))
    return <Fragment>{items}</Fragment>
}

const markers = [
    { key: 'marker1', position: [51.5, -0.1], content: 'My first popup' },
    { key: 'marker2', position: [51.51, -0.1], content: 'My second popup' },
    { key: 'marker3', position: [51.49, -0.05], content: 'My third popup' },
]

class MapWithPoems extends BaseComponent {
    render() {
        return (
            <Map center={[51.505, -0.09]} zoom={13} style={{ height: "500px", width: "100%" }} >
                <TileLayer
                    url={
                        "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"
                    }
                />
                <MyMarkersList markers={markers} />
            </Map>
        );
    }
}

export default MapWithPoems;
</code>```

The problem is when the page is downloaded the map is shrinket to the left side of the container. I have to resize the window to make the map to show up in the full width. See images.

What is wrong here? :)

答:
Using react hooks, without setTimeout(). This implementation worked for me.

```<code>const setMap = ( map: LeafletMap ) => {
        const resizeObserver = new ResizeObserver( () => {
                map.invalidateSize()
        })
        const container = document.getElementById('map-container')
        resizeObserver.observe(container!)
}

<MapContainer
...other properties
id='map-container'
whenCreated={setMap}

>

</MapContainer>
</code>```

whenCreated allows you to use the map instance as argument to the function please check this react-leaflet documentation.

I got the idea of using ResizeObersver from Michael MacFadden's StackOverflow answer

Body:
I have this react component:

import React, { Fragment } from 'react';
import L from 'leaflet';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

const customMarker = new L.icon({
    iconUrl: '/images/poemEditorTools/location-pointer-new.svg',
    iconSize: [56, 72],
    iconAnchor: [26, 72],
});

const MyPopupMarker = ({ content, position }) => (
    <Marker position={position} icon={customMarker} >
      <Popup>{content}</Popup>
    </Marker>
)

const MyMarkersList = ({ markers }) => {
    const items = markers.map(({ key, ...props }) => (
        <MyPopupMarker key={key} {...props} />
    ))
    return <Fragment>{items}</Fragment>
}

const markers = [
    { key: 'marker1', position: [51.5, -0.1], content: 'My first popup' },
    { key: 'marker2', position: [51.51, -0.1], content: 'My second popup' },
    { key: 'marker3', position: [51.49, -0.05], content: 'My third popup' },
]

class MapWithPoems extends BaseComponent {
    render() {
        return (
            <Map center={[51.505, -0.09]} zoom={13} style={{ height: "500px", width: "100%" }} >
                <TileLayer
                    url={
                        "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"
                    }
                />
                <MyMarkersList markers={markers} />
            </Map>
        );
    }
}

export default MapWithPoems;

The problem is when the page is downloaded the map is shrinket to the left side of the container. I have to resize the window to make the map to show up in the full width. See images.

What is wrong here? :)

Body:
Using react hooks, without setTimeout(). This implementation worked for me.

const setMap = ( map: LeafletMap ) => {
        const resizeObserver = new ResizeObserver( () => {
                map.invalidateSize()
        })
        const container = document.getElementById('map-container')
        resizeObserver.observe(container!)
}

<MapContainer
...other properties
id='map-container'
whenCreated={setMap}

>

</MapContainer>

whenCreated allows you to use the map instance as argument to the function please check this react-leaflet documentation.

I got the idea of using ResizeObersver from Michael MacFadden's StackOverflow answer


问:
Extracting text from a PDF using JBoss Richfaces
I am trying to write a web-app to manage references for my PhD thesis.

I used to manage this information inside a personal Confluence (fantastic tool! - http://www.atlassian.com/software/confluence/) instance however I'm fed-up with the opening of PDF's and cutting and pasting values into fields that I wish to record.

I have exposed a webservice that will return me images based on a PDF filename and a page number. The same webservice also exposes a method that will return the text inside of a provided rectangle (top left x-y coord, bottom right x-y coord).

I would like to be able to drag a rectangle over part of the PDF image and then call the webservice to give me the text (which I will then store on a EntityBean). I am looking at using the JBoss application stack (Application Server, Hibernate, Seam and Richfaces). Does anybody know how I could go about achieving this? I have seen the ability to draw custom images in other RIA toolkits (e.g. dojo), but I can't see a way of doing this inside of Richfaces.

Hopefully somebody out there could prove me wrong, or provide some idea about what I can do (as I am not a web developer - I'm mainly building this tool because the RIA frameworks available now have got me interested!)

I already have the code to extract the text, my problem is purely how can I get the user to draw a "selection rectangle" inside the web browser over the top of the image?

Many Thanks,

Aidos

答:
Try using the RichFaces Paint 2D tag

It exposes the Graphics2D package to the user interface.

Track user drag events on the image using javascript, then post the co-ordrdinates to the backing bean to re-render the image with a drawn on selection box.

OwnerDisplayName: Aidos

LastEditorDisplayName: Aidos

ContentLicense: CC BY-SA 2.5


问:
Whitespace as a value in .ini file
I want my .ini file to have an option to specify a certain character as a splitter for the parameters which is then handled with Python. That is:

```<code>[meta]
split_char = " "

[stuff]
field = value_1 value_2
</code>```

How can I specify a whitespace as a split char so it is recognizable? I have tried " " or [ ] and some other oprions, neither of them works.

As I've been asked, here is the Python scripts to read the .ini file:

```<code>from configparser import ConfigParser

config = ConfigParser()
config.read('config.ini')

# I need a nested dictionary, but this is not the point
split_char = config["meta"]["split_char"]
config = {section: dict(config.items(section)) for section in config.sections() if section != "meta"}
for section in config:
    for parameter in config[section]:
        config[section][parameter] = config[section][parameter].split(split_char)
</code>```

If I place a whitespace as it is, Python considers the splitter empty, adding quotes or any other auxiliary signs does not get the things done.

Update

The thing is that I would also like to be able to require splitters like ', ', which is a string with a whitespace.

答:
If you enforce a convention that the value in the ini file will always be:

```<code><delim>sep<delim>
</code>```

eg " " or [ ], the you can just have:

split_char = config["meta"]["split_char"][1]
```

Title: Whitespace as a value in .ini file

Body:
I want my .ini file to have an option to specify a certain character as a splitter for the parameters which is then handled with Python. That is:

[meta]
split_char = " "

[stuff]
field = value_1 value_2

How can I specify a whitespace as a split char so it is recognizable? I have tried " " or [ ] and some other oprions, neither of them works.

As I've been asked, here is the Python scripts to read the .ini file:

from configparser import ConfigParser

config = ConfigParser()
config.read('config.ini')

# I need a nested dictionary, but this is not the point
split_char = config["meta"]["split_char"]
config = {section: dict(config.items(section)) for section in config.sections() if section != "meta"}
for section in config:
    for parameter in config[section]:
        config[section][parameter] = config[section][parameter].split(split_char)

If I place a whitespace as it is, Python considers the splitter empty, adding quotes or any other auxiliary signs does not get the things done.

Update

The thing is that I would also like to be able to require splitters like ', ', which is a string with a whitespace.

Body:
If you enforce a convention that the value in the ini file will always be:

<delim>sep<delim>

eg " " or [ ], the you can just have:

split_char = config["meta"]["split_char"][1]


问:
Links to element IDs not working in Safari + React
I am developing a simple single-page website with React.

On top of the page I have a menu bar, with links to certain parts of the page:

```<code>    <li><a href="/#about">About us</a></li>
    <li><a href="/#services">Services</a></li>
    <li><a href="/#team">Team</a></li>
</code>```

The parts of my page (not necessarily components) have the corresponding ID attribute, eg:

```<code>...
        <div id="about" className="rn-about-area ptb--120 bg_color--5">
             ... <CONTENT>
        </div>
</code>```

When a link in the menu bar gets clicked, the page should jump to the corresponding part of the page. The problem: The links are working in Chrome and Firefox, but not in Safari.

What I tried so far based on similar StackOverflow questions (that are over ten years old):

Omitting the / before the #anchor:

About us

Defining the absolute URL path to each anchor:

About us

Implementing methods like scrollTo() or scrollIntoView()

Wrapping the anchor-elements in React  components

Checking for redirects that may cause problems using https://www.redirect-checker.org/index.php

but nothing works.

Is there any other way I could try? If not, my only idea is to destructure the page into seperate pages, so I can link them without using anchors.

EDIT: There might be an issue with React and the way the website is set up, because I checked a similar page, created without React, and there the first mentioned approach works, also in Safari.

答:
It was in fact a React problem:

Using this package it finally works now!

Body:
I am developing a simple single-page website with React.

On top of the page I have a menu bar, with links to certain parts of the page:

About us

Services

Team

The parts of my page (not necessarily components) have the corresponding ID attribute, eg:

...

             ... <CONTENT>

When a link in the menu bar gets clicked, the page should jump to the corresponding part of the page. The problem: The links are working in Chrome and Firefox, but not in Safari.

What I tried so far based on similar StackOverflow questions (that are over ten years old):

Omitting the / before the #anchor:

About us

Defining the absolute URL path to each anchor:

About us

Implementing methods like scrollTo() or scrollIntoView()

Wrapping the anchor-elements in React  components

Checking for redirects that may cause problems using https://www.redirect-checker.org/index.php

but nothing works.

Is there any other way I could try? If not, my only idea is to destructure the page into seperate pages, so I can link them without using anchors.

EDIT: There might be an issue with React and the way the website is set up, because I checked a similar page, created without React, and there the first mentioned approach works, also in Safari.


问:
Fuzzy matching in Google Sheets
Trying to compare two columns in GoogleSheets with this formula in Column C:

=if(A1=B1,"","Mismatch")

Works fine, but I'm getting a lot of false positives:

A.
B
C

MARY JO
Mary Jo

JAY, TIM
TIM JAY
Mismatch

Sam  Ron
Sam Ron
Mismatch

Jack *Ma
Jack MA
Mismatch

Any ideas how to work this?

答:
This uses a score based approach to determine a match. You can determine what is/isn't a match based on that score:

```<code>Score Formula = getMatchScore(A1,B1)
Match Formula = if(C1<.7,"mismatch",)
</code>```
```<code>function getMatchScore(strA, strB, ignoreCase=true) {
  strA = String(strA);
  strB = String(strB)
  const toLowerCase = ignoreCase ? str => str.toLowerCase() : str => str;
  const splitWords = str => str.split(/\b/);
  let [maxLenStr, minLenStr] = strA.length > strB.length ? [strA, strB] : [strB, strA];

  maxLenStr = toLowerCase(maxLenStr);
  minLenStr = toLowerCase(minLenStr);

  const maxLength = maxLenStr.length;
  const minLength = minLenStr.length;
  const lenScore = minLength / maxLength;

  const orderScore = Array.from(maxLenStr).reduce(
    (oldItem, nItem, index) => nItem === minLenStr[index] ? oldItem + 1 : oldItem, 0
  ) / maxLength;

  const maxKeyWords = splitWords(maxLenStr);
  const minKeyWords = splitWords(minLenStr);

  const keywordScore = minKeyWords.reduce(({ score, searchWord }, nItem) => {
    const newSearchWord = searchWord?.replace(new RegExp(nItem, ignoreCase ? 'i' : ''), '');
    score += searchWord.length != newSearchWord.length ? 1: 0;

    return { score, searchWord: newSearchWord };
  }, { score: 0, searchWord: maxLenStr }).score / minKeyWords.length;

  const sortedMaxLenStr = Array.from(maxKeyWords.sort().join(''));
  const sortedMinLenStr = Array.from(minKeyWords.sort().join(''));

  const charScore = sortedMaxLenStr.reduce((oldItem, nItem, index) => {
    const surroundingChars = [sortedMinLenStr[index-1], sortedMinLenStr[index], sortedMinLenStr[index+1]]
    .filter(char => char != undefined);

    return surroundingChars.includes(nItem)? oldItem + 1 : oldItem
  }, 0) / maxLength;

  const score = (lenScore * .15) + (orderScore * .25) + (charScore * .25) + (keywordScore * .35);

  return score;
}
</code>```

Title: Fuzzy matching in Google Sheets

Body:
This uses a score based approach to determine a match. You can determine what is/isn't a match based on that score:

Score Formula = getMatchScore(A1,B1)
Match Formula = if(C1<.7,"mismatch",)

function getMatchScore(strA, strB, ignoreCase=true) {
  strA = String(strA);
  strB = String(strB)
  const toLowerCase = ignoreCase ? str => str.toLowerCase() : str => str;
  const splitWords = str => str.split(/\b/);
  let [maxLenStr, minLenStr] = strA.length > strB.length ? [strA, strB] : [strB, strA];

  maxLenStr = toLowerCase(maxLenStr);
  minLenStr = toLowerCase(minLenStr);

  const maxLength = maxLenStr.length;
  const minLength = minLenStr.length;
  const lenScore = minLength / maxLength;

  const orderScore = Array.from(maxLenStr).reduce(
    (oldItem, nItem, index) => nItem === minLenStr[index] ? oldItem + 1 : oldItem, 0
  ) / maxLength;

  const maxKeyWords = splitWords(maxLenStr);
  const minKeyWords = splitWords(minLenStr);

  const keywordScore = minKeyWords.reduce(({ score, searchWord }, nItem) => {
    const newSearchWord = searchWord?.replace(new RegExp(nItem, ignoreCase ? 'i' : ''), '');
    score += searchWord.length != newSearchWord.length ? 1: 0;

    return { score, searchWord: newSearchWord };
  }, { score: 0, searchWord: maxLenStr }).score / minKeyWords.length;

  const sortedMaxLenStr = Array.from(maxKeyWords.sort().join(''));
  const sortedMinLenStr = Array.from(minKeyWords.sort().join(''));

  const charScore = sortedMaxLenStr.reduce((oldItem, nItem, index) => {
    const surroundingChars = [sortedMinLenStr[index-1], sortedMinLenStr[index], sortedMinLenStr[index+1]]
    .filter(char => char != undefined);

    return surroundingChars.includes(nItem)? oldItem + 1 : oldItem
  }, 0) / maxLength;

  const score = (lenScore * .15) + (orderScore * .25) + (charScore * .25) + (keywordScore * .35);

  return score;
}


问:
Looking for a way to split cells in excel based the last five numbers in a cell
I am looking for a way to fix a mixed data set representing addresses in Excel.

Here is an example dataset.

```<code>Kirchgasse 2389179 Beimerstetten
</code>```

All this should result in three datasets.

```<code>A1 = Kirchgasse 2389179 Beimerstetten
A2 = Kirchgasse 23
A3 = 89179
A4 = Beimerstetten
</code>```

Pattern is, that A3 is always the last 5 numbers in the dataset.

I am totally lost here, as Excel is usually not my weapon of choice.

答:
You can use Excel Formulas as well, to split cells, Excel gives us ample opportunity to use the features, there are lot of ways for a query to resolve, you can follow any of the following approaches, to accomplish the desired output

To Extract The First Part From Cell A1, Formula Used In Cell A2

```<code>=LEFT($A1,FIND(" ",$A1)+2)
</code>```

To Extract The Second Part From Cell A1, Formula Used In Cell A3

```<code>=LEFT(REPLACE($A1,1,LEN($A2),""),5)
</code>```

To Extract The Last Part Of The String From Cell A1, Formula Used In Cell A4

```<code>=TRIM(RIGHT(SUBSTITUTE(A1," ",REPT(" ",100)),100))
</code>```

However To Extract The 5 Numbers, you can use any one of the following as well that suits with your Excel Version

Formula shown in cell A11

```<code>=MAX(IFERROR(MID($A$1,ROW(INDIRECT("1:"&LEN($A$1))),5)*1,""))
</code>```

Formula shown in cell A13

```<code>=LARGE(IFERROR(--MID($A1,SEQUENCE(LEN($A1)),COLUMN($A$1:$E$1)),0),1)
</code>```

Formula shown in cell A15

```<code>=AGGREGATE(14,6,IFERROR(--MID($A1,ROW($1:$10000),COLUMN($A$1:$E$1)),0),1)
</code>```

Formula shown in cell A17

```<code>=--RIGHT(FILTERXML("<p><w>"&SUBSTITUTE($A1," ","</w><w>")&"</w></p>","//w[.*0=0]"),5)
</code>```

To get a detailed knowledge on FILTERXML Function you can refer the link below, prepared by JvdV Sir

FILTERXML FUNCTION DETAILED ANALYSIS BY JvdV Sir

Here is few more ways

Formula used in cell A2

```<code>=SUBSTITUTE(TRIM(FILTERXML("<p><w>"&SUBSTITUTE(SUBSTITUTE(LEFT($A1,FIND(" ",$A1)+2)&REPLACE($A1,1,FIND(" ",$A1)+2," ")," ","@",1)," ","</w><w>")&"</w></p>","//w")),"@"," ")
</code>```

Just enter the formula in cell A2, and it will spill if you are using O365 or Excel 2021

And if you are not using the above Excel Version then you may try this and Fill Down   The Formula

Formula Used In Cell B2 & Fill Down

```<code>=SUBSTITUTE(TRIM(FILTERXML("<p><w>"&SUBSTITUTE(SUBSTITUTE(LEFT($A$1,FIND(" ",$A$1)+2)&REPLACE($A$1,1,FIND(" ",$A$1)+2," ")," ","@",1)," ","</w><w>")&"</w></p>","//w["&ROW(A1)&"]")),"@"," ")
</code>```

Body:
I am looking for a way to fix a mixed data set representing addresses in Excel.

Here is an example dataset.

Kirchgasse 2389179 Beimerstetten

All this should result in three datasets.

A1 = Kirchgasse 2389179 Beimerstetten
A2 = Kirchgasse 23
A3 = 89179
A4 = Beimerstetten

Pattern is, that A3 is always the last 5 numbers in the dataset.

I am totally lost here, as Excel is usually not my weapon of choice.

Body:
You can use Excel Formulas as well, to split cells, Excel gives us ample opportunity to use the features, there are lot of ways for a query to resolve, you can follow any of the following approaches, to accomplish the desired output

To Extract The First Part From Cell A1, Formula Used In Cell A2

=LEFT($A1,FIND(" ",$A1)+2)

To Extract The Second Part From Cell A1, Formula Used In Cell A3

=LEFT(REPLACE($A1,1,LEN($A2),""),5)

To Extract The Last Part Of The String From Cell A1, Formula Used In Cell A4

=TRIM(RIGHT(SUBSTITUTE(A1," ",REPT(" ",100)),100))

However To Extract The 5 Numbers, you can use any one of the following as well that suits with your Excel Version

Formula shown in cell A11

=MAX(IFERROR(MID($A$1,ROW(INDIRECT("1:"&LEN($A$1))),5)*1,""))

Formula shown in cell A13

=LARGE(IFERROR(--MID($A1,SEQUENCE(LEN($A1)),COLUMN($A$1:$E$1)),0),1)

Formula shown in cell A15

=AGGREGATE(14,6,IFERROR(--MID($A1,ROW($1:$10000),COLUMN($A$1:$E$1)),0),1)

Formula shown in cell A17

=--RIGHT(FILTERXML("<p><w>"&SUBSTITUTE($A1," ","</w><w>")&"</w></p>","//w[.*0=0]"),5)

To get a detailed knowledge on FILTERXML Function you can refer the link below, prepared by JvdV Sir

FILTERXML FUNCTION DETAILED ANALYSIS BY JvdV Sir

Here is few more ways

Formula used in cell A2

=SUBSTITUTE(TRIM(FILTERXML("<p><w>"&SUBSTITUTE(SUBSTITUTE(LEFT($A1,FIND(" ",$A1)+2)&REPLACE($A1,1,FIND(" ",$A1)+2," ")," ","@",1)," ","</w><w>")&"</w></p>","//w")),"@"," ")

Just enter the formula in cell A2, and it will spill if you are using O365 or Excel 2021

And if you are not using the above Excel Version then you may try this and Fill Down   The Formula

Formula Used In Cell B2 & Fill Down

=SUBSTITUTE(TRIM(FILTERXML("<p><w>"&SUBSTITUTE(SUBSTITUTE(LEFT($A$1,FIND(" ",$A$1)+2)&REPLACE($A$1,1,FIND(" ",$A$1)+2," ")," ","@",1)," ","</w><w>")&"</w></p>","//w["&ROW(A1)&"]")),"@"," ")


问:
How can i solve a "Property 'style' does not exist on type 'Element' error?
I really need help to solve this error. I wrote the following JavaScript code below to enable my tab indicator to show on a clicked tab when clicked on but all I am getting is an error which says: "Property 'style' doesn't exist on type 'Element'". The tabs work perfectly fine, I can switch from one tab to the other. I have seen similar questions but my issue wasn't resolved following their lead suggestions. I am currently building an angular project and i wrote my JavaScript in the ngInit(){} function in my .ts file. The code is below:

```<code>ngOnInit() {
    let tabPanes = this._class('tab-header')[0].getElementsByTagName('div');

    for (let i = 0; i < tabPanes.length; i++) {
      tabPanes[i].addEventListener('click', () => {
        this._class('tab-header')[0]
          .getElementsByClassName('active')[0]
          .classList.remove('active');
          tabPanes[i].classList.add("active");

          this._class('tab-indicator')[0].style.top = 'calc(80px + ${i*50}px)'; // This flags a "property 'style' doe not exist on type 'Element'" error.

          this._class('tab-content')[0]
          .getElementsByClassName('active')[0]
          .classList.remove('active');

          this._class('tab-content')[0]
          .getElementsByTagName('div')[i]
          .classList.add('active');
      });
    }
  }

_class(name: any) {
    return document.getElementsByClassName(name);
  }
</code>```

Where did i go wrong? Any idea on how to solve this?

答:
Change _class method to :-</p>
```<code>_class(name: any): NodeList<HTMLElement> {
    return document.getElementsByClassName(name) as NodeList<HTMLElement>;
  }
</code>```

Body:
I really need help to solve this error. I wrote the following JavaScript code below to enable my tab indicator to show on a clicked tab when clicked on but all I am getting is an error which says: "Property 'style' doesn't exist on type 'Element'". The tabs work perfectly fine, I can switch from one tab to the other. I have seen similar questions but my issue wasn't resolved following their lead suggestions. I am currently building an angular project and i wrote my JavaScript in the ngInit(){} function in my .ts file. The code is below:

ngOnInit() {
    let tabPanes = this._class('tab-header')[0].getElementsByTagName('div');

    for (let i = 0; i < tabPanes.length; i++) {
      tabPanes[i].addEventListener('click', () => {
        this._class('tab-header')[0]
          .getElementsByClassName('active')[0]
          .classList.remove('active');
          tabPanes[i].classList.add("active");

          this._class('tab-indicator')[0].style.top = 'calc(80px + ${i*50}px)'; // This flags a "property 'style' doe not exist on type 'Element'" error.

          this._class('tab-content')[0]
          .getElementsByClassName('active')[0]
          .classList.remove('active');

          this._class('tab-content')[0]
          .getElementsByTagName('div')[i]
          .classList.add('active');
      });
    }
  }

_class(name: any) {
    return document.getElementsByClassName(name);
  }

Where did i go wrong? Any idea on how to solve this?

Body:
Change _class method to :-

_class(name: any): NodeList<HTMLElement> {
    return document.getElementsByClassName(name) as NodeList<HTMLElement>;
  }


问:
T-SQL: Find maximum concurrent number of people per day with null values
I have a table that stores people's sign-ins and sign-outs in rooms. One of them logs in and tells the system how many people they are in total. As long as they don't log out, the value in the LogOut column remains NULL.
This is a query for a report I have to do but I am stuck.

I want to find the maximum concurrent number of people per day in each room in a given time span. However, I also want to count the number of people that are NULL, since they are actually still logged in.

I created this query based on several answers on Stackoverflow. Unfortunately I haven't figured out how to get the number of people with NULL values on a day when no one logs into that room.
The reason might be the cumulative total, but how do I work around this issue?

Here is an example table:

```<code>CREATE TABLE Registrations(
    [RoomName] VARCHAR(32),
    [LogIn] DATETIME,
    [LogOut] DATETIME,
    [NumberOfPeople] INT
)

INSERT INTO Registrations (RoomName, LogIn, LogOut, NumberOfPeople)
VALUES
('MainHall', '2022-01-31 08:00:00.000', NULL, 5),
('MainHall', '2022-01-31 08:00:00.000', '2022-01-31 10:00:00.000', 5),
('MainHall', '2022-01-31 09:00:00.000', '2022-01-31 11:00:00.000', 2),
('MainHall', '2022-01-31 12:00:00.000', '2022-01-31 14:00:00.000', 2),
('SmallRoom', '2022-01-31 08:00:00.000', NULL, 3),
('SmallRoom', '2022-01-31 10:00:00.000', '2022-01-31 12:00:00.000', 3),
('SmallRoom', '2022-01-31 11:00:00.000', '2022-01-31 14:00:00.000', 3),
('MainHall', '2022-02-01 08:00:00.000', NULL, 5),
('MainHall', '2022-02-01 08:00:00.000', '2022-02-01 10:00:00.000', 5),
('MainHall', '2022-02-01 09:00:00.000', '2022-02-01 11:00:00.000', 2),
('MainHall', '2022-02-01 12:00:00.000', '2022-02-01 14:00:00.000', 2)
</code>```

This is how the first entries of MainHall on 2022-01-31 should look like:

```<code>-- A    |-------------------
-- B    |-----|
-- C       |-----|
-- D                |-----|
</code>```

This is the result I want to get:

```<code>Day         |    Room     | MaxNumberOfConcurrentLoggedInPeople
------------+-------------+-------------------------------------
2022-01-31  |  MainHall   |                 12
2022-01-31  |  SmallRoom  |                 9
2022-02-01  |  MainHall   |                 17
2022-02-01  |  SmallRoom  |                 3
</code>```

This is my query:

```<code>SELECT  ct.RoomName,
        ct.DatePeak,
        ct.RegistrationPeak
FROM
(
    SELECT  cte.RoomName,
            CONVERT(DATE, cte.DatePeak) AS DatePeak,
            MAX(cte.RegistrationPeak) AS RegistrationPeak
    FROM
        (
        SELECT  MarkedDateTime.RoomName,
                SUM(SUM(MarkedDateTime.NumberOfPeople)) OVER (PARTITION BY MarkedDateTime.RoomName ORDER BY MarkedDateTime.DatePeak) AS RegistrationPeak,
                CONVERT(DATE, MarkedDateTime.DatePeak) AS DatePeak
        FROM
            (
                SELECT      RoomName,
                            NumberOfPeople,
                            LogIn AS DatePeak

                FROM        Registrations

                WHERE       (LogOut >=  '2022-01-31 00:00:00.000' OR LogOut IS NULL)
                AND         LogIn < DATEADD(DAY, 1, '2022-02-01 00:00:00.000')

                UNION ALL

                SELECT      RoomName,
                            -NumberOfPeople,
                            COALESCE(LogOut, DATEADD(MILLISECOND, - 3, DATEADD(DAY, 1, '2022-02-01 00:00:00.000'))) AS DatePeak

                FROM        Registrations

                WHERE       (LogOut >=  '2022-01-31 00:00:00.000' OR LogOut IS NULL)
                AND         LogIn < DATEADD(DAY, 1, '2022-02-01 00:00:00.000')
            ) AS MarkedDateTime

        GROUP BY RoomName, DatePeak
        ) AS cte

    GROUP BY DatePeak, RoomName
    ) AS ct

WHERE   ct.DatePeak <= '2022-02-01 00:00:00.000'
AND     ct.DatePeak >= '2022-01-31 00:00:00.000'
</code>```

EDIT: I added the solution and a small visual help.
2. EDIT: Fixed the wrong dates in the provided test table.

答:
Your data doesn't seem to quite match your expected output, and some of the data doesn't even make sense (logouts before logins), but I think you can solve it like this:

Unpivot the log-ins and -outs into separate events, with the quantity positive or negative respectively. Exclude nulls.

Calculate a running sum of the quantity, partitioned by room and date, ordered by time.

Then simply group by room and day, and take the maximum of the running sum.

SELECT
  evnt.Day,
  evnt.RoomName,
  MaxNumberOfConcurrentLoggedInPeople = MAX(evnt.RunningSum)
FROM (
    SELECT
      r.RoomName,
      Day = CAST(v.EventDateTime AS date),
      v.DiffQuantity,
      RunningSum = SUM(v.DiffQuantity) OVER (PARTITION BY r.RoomName, CAST(v.EventDateTime AS date) ORDER BY v.EventDateTime ROWS UNBOUNDED PRECEDING)
    FROM Registrations r
    CROSS APPLY (VALUES
        (r.LogIn, r.NumberOfPeople),
        (r.LogOut, -r.NumberOfPeople)
    ) v(EventDateTime, DiffQuantity)
    WHERE v.EventDateTime IS NOT NULL
) evnt
GROUP BY
  evnt.RoomName,
  evnt.Day;
```

db<>fiddle

Body:
I have a table that stores people's sign-ins and sign-outs in rooms. One of them logs in and tells the system how many people they are in total. As long as they don't log out, the value in the LogOut column remains NULL.
This is a query for a report I have to do but I am stuck.

I want to find the maximum concurrent number of people per day in each room in a given time span. However, I also want to count the number of people that are NULL, since they are actually still logged in.

I created this query based on several answers on Stackoverflow. Unfortunately I haven't figured out how to get the number of people with NULL values on a day when no one logs into that room.
The reason might be the cumulative total, but how do I work around this issue?

Here is an example table:

CREATE TABLE Registrations(
    [RoomName] VARCHAR(32),
    [LogIn] DATETIME,
    [LogOut] DATETIME,
    [NumberOfPeople] INT
)

INSERT INTO Registrations (RoomName, LogIn, LogOut, NumberOfPeople)
VALUES
('MainHall', '2022-01-31 08:00:00.000', NULL, 5),
('MainHall', '2022-01-31 08:00:00.000', '2022-01-31 10:00:00.000', 5),
('MainHall', '2022-01-31 09:00:00.000', '2022-01-31 11:00:00.000', 2),
('MainHall', '2022-01-31 12:00:00.000', '2022-01-31 14:00:00.000', 2),
('SmallRoom', '2022-01-31 08:00:00.000', NULL, 3),
('SmallRoom', '2022-01-31 10:00:00.000', '2022-01-31 12:00:00.000', 3),
('SmallRoom', '2022-01-31 11:00:00.000', '2022-01-31 14:00:00.000', 3),
('MainHall', '2022-02-01 08:00:00.000', NULL, 5),
('MainHall', '2022-02-01 08:00:00.000', '2022-02-01 10:00:00.000', 5),
('MainHall', '2022-02-01 09:00:00.000', '2022-02-01 11:00:00.000', 2),
('MainHall', '2022-02-01 12:00:00.000', '2022-02-01 14:00:00.000', 2)

This is how the first entries of MainHall on 2022-01-31 should look like:

-- A    |-------------------
-- B    |-----|
-- C       |-----|
-- D                |-----|

This is the result I want to get:

Day         |    Room     | MaxNumberOfConcurrentLoggedInPeople
------------+-------------+-------------------------------------
2022-01-31  |  MainHall   |                 12
2022-01-31  |  SmallRoom  |                 9
2022-02-01  |  MainHall   |                 17
2022-02-01  |  SmallRoom  |                 3

This is my query:

SELECT  ct.RoomName,
        ct.DatePeak,
        ct.RegistrationPeak
FROM
(
    SELECT  cte.RoomName,
            CONVERT(DATE, cte.DatePeak) AS DatePeak,
            MAX(cte.RegistrationPeak) AS RegistrationPeak
    FROM
        (
        SELECT  MarkedDateTime.RoomName,
                SUM(SUM(MarkedDateTime.NumberOfPeople)) OVER (PARTITION BY MarkedDateTime.RoomName ORDER BY MarkedDateTime.DatePeak) AS RegistrationPeak,
                CONVERT(DATE, MarkedDateTime.DatePeak) AS DatePeak
        FROM
            (
                SELECT      RoomName,
                            NumberOfPeople,
                            LogIn AS DatePeak

                FROM        Registrations

                WHERE       (LogOut >=  '2022-01-31 00:00:00.000' OR LogOut IS NULL)
                AND         LogIn < DATEADD(DAY, 1, '2022-02-01 00:00:00.000')

                UNION ALL

                SELECT      RoomName,
                            -NumberOfPeople,
                            COALESCE(LogOut, DATEADD(MILLISECOND, - 3, DATEADD(DAY, 1, '2022-02-01 00:00:00.000'))) AS DatePeak

                FROM        Registrations

                WHERE       (LogOut >=  '2022-01-31 00:00:00.000' OR LogOut IS NULL)
                AND         LogIn < DATEADD(DAY, 1, '2022-02-01 00:00:00.000')
            ) AS MarkedDateTime

        GROUP BY RoomName, DatePeak
        ) AS cte

    GROUP BY DatePeak, RoomName
    ) AS ct

WHERE   ct.DatePeak <= '2022-02-01 00:00:00.000'
AND     ct.DatePeak >= '2022-01-31 00:00:00.000'

EDIT: I added the solution and a small visual help.
2. EDIT: Fixed the wrong dates in the provided test table.

Body:
Your data doesn't seem to quite match your expected output, and some of the data doesn't even make sense (logouts before logins), but I think you can solve it like this:

Unpivot the log-ins and -outs into separate events, with the quantity positive or negative respectively. Exclude nulls.

Calculate a running sum of the quantity, partitioned by room and date, ordered by time.

Then simply group by room and day, and take the maximum of the running sum.

SELECT
  evnt.Day,
  evnt.RoomName,
  MaxNumberOfConcurrentLoggedInPeople = MAX(evnt.RunningSum)
FROM (
    SELECT
      r.RoomName,
      Day = CAST(v.EventDateTime AS date),
      v.DiffQuantity,
      RunningSum = SUM(v.DiffQuantity) OVER (PARTITION BY r.RoomName, CAST(v.EventDateTime AS date) ORDER BY v.EventDateTime ROWS UNBOUNDED PRECEDING)
    FROM Registrations r
    CROSS APPLY (VALUES
        (r.LogIn, r.NumberOfPeople),
        (r.LogOut, -r.NumberOfPeople)
    ) v(EventDateTime, DiffQuantity)
    WHERE v.EventDateTime IS NOT NULL
) evnt
GROUP BY
  evnt.RoomName,
  evnt.Day;

db<>fiddle


问:
Moving trail after my image in HTML5 Canvas & Javascript
I am trying to move an image in HTML5 canvas but when it moves it creates a long trail/line behind it. I'm not sure how to have just the image move without a long trail line appearing. Any help would be greatly appreciated</p>
```<code>//Create bullets
class Projectile {
  constructor({position, velocity}){
    this.position = position
    this.velocity = velocity
    this.width = 5
    this.height = 10
    this.color = "red";
  }

  draw() {
    ctx.fillStyle = this.color;
    ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
  }

  update() {
    this.draw()
    this.position.x += this.velocity.x
    this.position.y += this.velocity.y
  }
}

const projectiles = [new Projectile({
  position: {
    x: 300,
    y: 300
  },
  velocity: {
    x: 0,
    y: 0
  }
})]

function animate() {
  projectiles.forEach(projectile => {
    projectile.update()
  })
}

animate()
</code>```

答:
You have to clear the canvas between the update draw calls, otherwise the projectiles get drawn over and over again. You can use clearRect or empty the canvas on your own like this:</p>
```<code>ctx.fillStyle = 'black'; //try out 'rgba(0,0,0,0.9)'
ctx.fillRect(0,0,canvas.width,canvas.height);
</code>```

Body:
I am trying to move an image in HTML5 canvas but when it moves it creates a long trail/line behind it. I'm not sure how to have just the image move without a long trail line appearing. Any help would be greatly appreciated

//Create bullets
class Projectile {
  constructor({position, velocity}){
    this.position = position
    this.velocity = velocity
    this.width = 5
    this.height = 10
    this.color = "red";
  }

  draw() {
    ctx.fillStyle = this.color;
    ctx.fillRect(this.position.x, this.position.y, this.width, this.height);
  }

  update() {
    this.draw()
    this.position.x += this.velocity.x
    this.position.y += this.velocity.y
  }
}

const projectiles = [new Projectile({
  position: {
    x: 300,
    y: 300
  },
  velocity: {
    x: 0,
    y: 0
  }
})]

function animate() {
  projectiles.forEach(projectile => {
    projectile.update()
  })
}

animate()

Body:
You have to clear the canvas between the update draw calls, otherwise the projectiles get drawn over and over again. You can use clearRect or empty the canvas on your own like this:

ctx.fillStyle = 'black'; //try out 'rgba(0,0,0,0.9)'
ctx.fillRect(0,0,canvas.width,canvas.height);


问:
Yii CSV export to browser getting reamed with log messages instead of data
I am trying to export a CSV to the browser using Yii and the CSV keeps being filled by Yii log messages.

```<code>header('Content-Description: File Transfer');
header('Content-Type: application/csv');
header('Content-disposition: attachment; filename=enrollment_course.csv');

$enrollment = Reports::getEnrollment($courseId);
$separator=",";

foreach ($enrollment as $users)
{
    $tmp = array(
        $users->userid,
        $users->firstname,
        $users->lastname,
        );

    echo join($separator, $tmp)."\n";

}

Yii::app()->end();
</code>```

Any ideas why this doesn't work properly?

答:
yeah, I actually wrote an extension to do that: http://www.yiiframework.com/extension/csvexport/

Basically it amounts to calling exit, take a look at the last few lines of the example:

```<code>// options for file, changing delimeter and enclosure
$content = $csv->toCSV('../myfilename.csv', "\t", "'");
Yii::app()->getRequest()->sendFile($filename, $content, "text/csv", false);

// call exit instead of letting sendFile do it, because if you are using
// CWebLogRoute, the onEndRequest event will fire and output your log and not csv file :(
exit();
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am trying to export a CSV to the browser using Yii and the CSV keeps being filled by Yii log messages.

header('Content-Description: File Transfer');
header('Content-Type: application/csv');
header('Content-disposition: attachment; filename=enrollment_course.csv');

$enrollment = Reports::getEnrollment($courseId);
$separator=",";

foreach ($enrollment as $users)
{
    $tmp = array(
        $users->userid,
        $users->firstname,
        $users->lastname,
        );

    echo join($separator, $tmp)."\n";

}

Yii::app()->end();

Any ideas why this doesn't work properly?

Body:
yeah, I actually wrote an extension to do that: http://www.yiiframework.com/extension/csvexport/

Basically it amounts to calling exit, take a look at the last few lines of the example:

// options for file, changing delimeter and enclosure
$content = $csv->toCSV('../myfilename.csv', "\t", "'");
Yii::app()->getRequest()->sendFile($filename, $content, "text/csv", false);

// call exit instead of letting sendFile do it, because if you are using
// CWebLogRoute, the onEndRequest event will fire and output your log and not csv file :(
exit();


问:
What is the dart function type syntax for variable declaration?
I know you can specify function types in formal arg list, but how would I do this for instance variables? I would like to do this:

class A<T> {
  int compare(T a, T b);
}
```

<p>where compare is a function variable with the appropriate type. I would like to be able to write:</p>

<pre class="lang-dart prettyprint-override"><code>A a = new A();
a.compare = ...
</code>```

答:
In addition to the Alexandre Ardhuin's answer, direct declaration, without typedef:

```<code>class A<T> {
  late int Function(T a, T b) compare;
}

main() {
  A<int> a = new A<int>();
  a.compare = (int a, int b) => a.compareTo(b);
  print(a.compare(1, 2));
}
</code>```

Body:
I know you can specify function types in formal arg list, but how would I do this for instance variables? I would like to do this:

class A<T> {
  int compare(T a, T b);
}

where compare is a function variable with the appropriate type. I would like to be able to write:

A a = new A();
a.compare = ...

Body:
In addition to the Alexandre Ardhuin's answer, direct declaration, without typedef:

class A<T> {
  late int Function(T a, T b) compare;
}

main() {
  A<int> a = new A<int>();
  a.compare = (int a, int b) => a.compareTo(b);
  print(a.compare(1, 2));
}


问:
UDP Server works only on local network
I'm trying to run an UDP Client-Server message exchange program for a university course, when I try it in a local network even with different PCs works really fine. But the moment I try to run it on different internet connections it seems like the server doesn't receive anything. I am running Ubuntu and allowed the specific port for UDP connection but maybe I'm missing something else

Server side:

```<code>int sockfd;
struct sockaddr_in servaddr;

//creating socket file descriptor
if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
    perror("socket creation failed");
    exit(EXIT_FAILURE);
}

memset(&servaddr, 0 , sizeof(servaddr));

//filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);

//bind the socket with  server address
if( bind(sockfd,(const struct sockaddr *) &servaddr ,sizeof(servaddr)) < 0){
    perror("bind failed");
    exit(EXIT_FAILURE);
}
</code>```

Client side:

```<code>int main(int argc, char ** argv) {
    int sockfd;
    char username[MAXLENGHT];
    struct sockaddr_in  servaddr;

    //creating socket file descriptor
    if( (sockfd = socket(AF_INET,SOCK_DGRAM, 0)) < 0 ){
        perror("socket creation failed!");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr,0, sizeof(servaddr));

    //filling server info
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);
</code>```

I am using as address 192.168.1.179 and the port I am using is 8080

答:
... when I try it in a local network even with different PCs works really fine.

For this reason I doubt that it is a problem in your program.

maybe I'm missing something else

First of all, most internet connections today use a NAT.

This means that one internet access (e.g. at your home) has one IP address in the internet (called the "global address") and multiple computers share that IP address.

The computer's IP address (e.g. 192.168.1.179) is only valid in the local network; in other local networks, there are other computers having that address.

If you send a UDP packet to the IP address of the computer (192.168.1.179), both computers must be in the same local network.

If you send a UDP packet to the "global IP address" of the internet access, the router does not know which computer shall receive the packet because all computers in the local network share the same "global address".

You may configure your router (e.g. WLAN router) in a way that it knows that UDP packets from the internet to port 8080 shall be sent to the computer 192.168.1.179. This is called "port forwarding".

The sending computer must send the UDP packet to the "global IP address" of the internet access, not to the IP address of the computer (192.168.1.179) in this case.

And if it's not your internet access (e.g. it is not your WLAN router), you already have a problem here.

However, because this has nothing to do with programming, it is out of scope on this web site; you might ask further questions on the SuperUser web site, which also belongs to the StackExchange network. Your account (user name and password) is valid on all StackExchange web sites.

Today, many internet connections even use CGNAT.

This means that even multiple customers share one IP address in the internet.

In this case, it depends on your internet provider if it is possible at all to receive UDP packets:

If your internet access shares the IP address with another person that also wants to receive UDP packets on port 8080, there is a problem...

Title: UDP Server works only on local network

Body:
I'm trying to run an UDP Client-Server message exchange program for a university course, when I try it in a local network even with different PCs works really fine. But the moment I try to run it on different internet connections it seems like the server doesn't receive anything. I am running Ubuntu and allowed the specific port for UDP connection but maybe I'm missing something else

Server side:

int sockfd;
struct sockaddr_in servaddr;

//creating socket file descriptor
if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
    perror("socket creation failed");
    exit(EXIT_FAILURE);
}

memset(&servaddr, 0 , sizeof(servaddr));

//filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);

//bind the socket with  server address
if( bind(sockfd,(const struct sockaddr *) &servaddr ,sizeof(servaddr)) < 0){
    perror("bind failed");
    exit(EXIT_FAILURE);
}

Client side:

int main(int argc, char ** argv) {
    int sockfd;
    char username[MAXLENGHT];
    struct sockaddr_in  servaddr;

    //creating socket file descriptor
    if( (sockfd = socket(AF_INET,SOCK_DGRAM, 0)) < 0 ){
        perror("socket creation failed!");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr,0, sizeof(servaddr));

    //filling server info
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);

I am using as address 192.168.1.179 and the port I am using is 8080


问:
How can I get a specific element value of object in localstorage
I'm trying to get "city" value (in case: Porto, Lisboa, Leiria, Londres) of localstorage and put It in a variable. I wish to do this in a loop for and use each city name in a function.

Now, I'm here:

```<code>Object.entries(localStorage).map(([id, valueJSON]) => {
  cityName = JSON.parse(JSON.stringify(localStorage.getItem('persist:root', 'allWeather', 'city')));
  console.log(cityName)
</code>```

My return is this:

{"allWeather":"[{"id":0.47266066302275545,"city":"Porto"},{"id":0.8669553925029849,"city":"Lisboa"},{"id":0.5502373167192611,"city":"Leiria"},{"id":0.19655712000371484,"city":"Londres"}]","_persist":"{"version":-1,"rehydrated":true}"}

How can I do this? I appreciate any help.

答:
You need to convert the object string to JSON using JSON.parse

[{ city }] this part is not right. Change it to city

Body:
I'm trying to get "city" value (in case: Porto, Lisboa, Leiria, Londres) of localstorage and put It in a variable. I wish to do this in a loop for and use each city name in a function.

Now, I'm here:

Object.entries(localStorage).map(([id, valueJSON]) => {
  cityName = JSON.parse(JSON.stringify(localStorage.getItem('persist:root', 'allWeather', 'city')));
  console.log(cityName)

My return is this:

{"allWeather":"[{"id":0.47266066302275545,"city":"Porto"},{"id":0.8669553925029849,"city":"Lisboa"},{"id":0.5502373167192611,"city":"Leiria"},{"id":0.19655712000371484,"city":"Londres"}]","_persist":"{"version":-1,"rehydrated":true}"}

How can I do this? I appreciate any help.


问:
how scanf with character class work without format specifier
```<code>char info[30];
scanf("%79[^\n]", info);
printf("%s", info);
</code>```

This code works successfully. But

```<code>scanf("%79", info);
</code>```

will not work. I need to modify it like that:

```<code>scanf("%79s", info);
</code>```

I understand that first code snippet means read till newline. But how does it work without "s" format specifier?

答:
The brackets "[^\n]" itself is a specifier like "s" in "%s".

https://en.cppreference.com/w/c/io/fscanf

Body:
char info[30];
scanf("%79[^\n]", info);
printf("%s", info);

This code works successfully. But

scanf("%79", info);

will not work. I need to modify it like that:

scanf("%79s", info);

I understand that first code snippet means read till newline. But how does it work without "s" format specifier?


问:
create default html opening code in Visual Studio Code
In some html editors when you create a new html file, some default codes as below created automatically:

```<code><!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8"/>
</head>
<body>

</body>
</html>
</code>```

how can I enable this feature in VSCode editor?

Thanks.

答: Press shift and 1 (!)  It will show two options select the first one or type html:5 and enter the option it will give you default boilerplate for html</p>

Body:
In some html editors when you create a new html file, some default codes as below created automatically:

<!DOCTYPE html>

<title></title>
<meta charset="utf-8"/>

how can I enable this feature in VSCode editor?

Thanks.


问:
Trying to get transacation details for FinalExecutionOutcome after calling changemethods on near
I do have a smart contract that has both viewMethods as well as changeMethods.

I am able to deploy the contract and we are able to successfully call both the viewmethods as well as chnagementhods.

As per near documentation whenever a function is called it return the promise.
async functionCall(contractId: string, methodName: string, args: any, gas: number, amount?: BN): Promise<FinalExecutionOutcome> {}

but when I try to get the result, it is always null.

The idea is to get transaction details from the response.

This is sample code

```<code>import * as nearAPI from "near-api-js"
import { getConfig } from './config'

async initContract() {

if (!this.contract) {
    //initialize near
    await this.initNear();

    this.contract = await this.near.loadContract(process.env.CONTRACT_NAME, { // eslint-disable-line require-atomic-updates
        // NOTE: This configuration only needed while NEAR is still in development

        viewMethods: [...],
        // Change methods can modify the state. But you don't receive the returned value when called.
        changeMethods: [ ...."set_comments"],
        // Sender is the account ID to initialize transactions.
        sender: ....
    });
}

return this;
}

    async setComments(
        id: String,
        comments: String
    ) {
        if (this.contract) {
           const respone=  await this.contract.set_comments(
                {
                    id: id,
                    comments: comments
                });
            return respone;
//response is always coming as null even though the comments are updated on near
        }
        return null;

       }
</code>```

Thanks

答:
You are not using the functionCall method, you are using the method on the contract directly. If you want the transaction details, you need to use the functionCall method on the account, like the below example:

I assume you return near inside initNear(), and can connect to the wallet.

// initialize near
const near = await this.initNear();

// connect to the wallet
const wallet = new WalletConnection(near,'APP_KEY_PREFIX');

// Inside setComments function
const response = await wallet.account().functionCall({
  contractId: this.contract.contractId,
  methodName: 'set_comments',
  args: {
   id: id,
   comments: comments
  },
});
```

Body:
I do have a smart contract that has both viewMethods as well as changeMethods.

I am able to deploy the contract and we are able to successfully call both the viewmethods as well as chnagementhods.

As per near documentation whenever a function is called it return the promise.
async functionCall(contractId: string, methodName: string, args: any, gas: number, amount?: BN): Promise<FinalExecutionOutcome> {}

but when I try to get the result, it is always null.

The idea is to get transaction details from the response.

This is sample code

import * as nearAPI from "near-api-js"
import { getConfig } from './config'

async initContract() {

if (!this.contract) {
    //initialize near
    await this.initNear();

    this.contract = await this.near.loadContract(process.env.CONTRACT_NAME, { // eslint-disable-line require-atomic-updates
        // NOTE: This configuration only needed while NEAR is still in development

        viewMethods: [...],
        // Change methods can modify the state. But you don't receive the returned value when called.
        changeMethods: [ ...."set_comments"],
        // Sender is the account ID to initialize transactions.
        sender: ....
    });
}

return this;
}

    async setComments(
        id: String,
        comments: String
    ) {
        if (this.contract) {
           const respone=  await this.contract.set_comments(
                {
                    id: id,
                    comments: comments
                });
            return respone;
//response is always coming as null even though the comments are updated on near
        }
        return null;

       }

Thanks


问:
Is a useEffect cleanup necessary in the top level component
Do I need to clean up the subscription in the code example if this code is running in the top-level component and the component being unmounted means the app is being closed? When I try to log out a comment in the clean up I never see it actually being written out in the console. I couldn't find a scenario where it would actually run and, therefore, I feel like I might as well remove it. Is it worth keeping it around for some reason?

Thank you.

```<code>useEffect(() => {
    const subscription = AppState.addEventListener(
      "change",
      _handleAppStateChange
    );

    return () => {
      subscription.remove();
    };
  }, []);
</code>```

答:
Are you saying this just for top-level component or general for cleanup function?

I will go with the second thought. Since it was a big problem for me when I started React. I recommend reading this article Cleanup-useEffect helped me a lot.

Body:
Do I need to clean up the subscription in the code example if this code is running in the top-level component and the component being unmounted means the app is being closed? When I try to log out a comment in the clean up I never see it actually being written out in the console. I couldn't find a scenario where it would actually run and, therefore, I feel like I might as well remove it. Is it worth keeping it around for some reason?

Thank you.

useEffect(() => {
    const subscription = AppState.addEventListener(
      "change",
      _handleAppStateChange
    );

    return () => {
      subscription.remove();
    };
  }, []);


问:
How can I do a search and replace in a PHP string based on values in a JSON string?
In PHP I have this json string with search and replace words

```<code>$json = '[{"Original":"test1","Replacement":"test1a"},{"Original":"test2","Replacement":"test2a"}]';
</code>```

Now I want to do a search and replace in a text string for all items in this json file.

```<code>$searchReplaceArray = '[{"Original":"test1","Replacement":"test1a"},{"Original":"test2","Replacement":"test2a"}]';

$text1 = 'Hello test1, let me see if test2 is also replaced...';
$text2 = str_ireplace(array_keys($searchReplaceArray), array_values($searchReplaceArray),$text1);

echo 'Original: ' . $text1 . '<br>';
echo 'Replace: '  . $text2;
</code>```

I expect $text2 to be: "Hello test1a, let me see if test2a is also replaced..."

However, it does not work. Any help would be appreciated.

答:
```<code>// It's not a valid Json,  so you need add square brackets around it
$searchReplaceArray = '['. $json .']';

$searchReplaceArray = json_decode($searchReplaceArray, true);
// get search array
$Original = array_column($searchReplaceArray , 'Original');
// get replacement array
$Replacement = array_column($searchReplaceArray , 'Replacement');

$text1 = 'Hello test1, let me see if test2 is also replaced...';
$text2 = str_ireplace($Original, $Replacement,$text1);

echo 'Original: ' . $text1 . '<br>';
echo 'Replace: '  . $text2;

// Replace: Hello test1a, let me see if test2a is also replaced...
</code>```

Body:
In PHP I have this json string with search and replace words

$json = '[{"Original":"test1","Replacement":"test1a"},{"Original":"test2","Replacement":"test2a"}]';

Now I want to do a search and replace in a text string for all items in this json file.

$searchReplaceArray = '[{"Original":"test1","Replacement":"test1a"},{"Original":"test2","Replacement":"test2a"}]';

$text1 = 'Hello test1, let me see if test2 is also replaced...';
$text2 = str_ireplace(array_keys($searchReplaceArray), array_values($searchReplaceArray),$text1);

echo 'Original: ' . $text1 . '
';
echo 'Replace: '  . $text2;

I expect $text2 to be: "Hello test1a, let me see if test2a is also replaced..."

However, it does not work. Any help would be appreciated.


问:
Difficulty Scraping Product Information from Website
I am having difficulties scraping the "product name" and "price" from this website: https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571

Looking to scrap "$4.30" and "Zespri New Zealand Kiwifruit - Green" from the webpage. I have tried various approaches (Beautiful Soup, request_html, selenium) without any success. Attached the sample code approaches I have taken.

I am able to view the 'price' and 'product name' details in the "Developer Tools" tab of Chrome. It seems like that webpage uses Javascript to dynamically load the product information, so the various approaches mentioned above are not able to scrape the information properly.

Appreciate any assistance on this issue.

Requests_html Approach:

```<code>from requests_html import HTMLSession
import json

url='https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571'
session = HTMLSession()
r = session.get(url)
r.html.render(timeout=20)

json_text=r.html.xpath("//script[@type='application/ld+json']/text()")[0][:-1]
json_data = json.loads(json_text)
print(json_data['name']['price'])
</code>```

Beautiful Soup Approach:

```<code>import sys
import time
from bs4 import BeautifulSoup
import requests
import re

url='https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571'

headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36 Edg/97.0.1072.69'}
page=requests.get(url, headers=headers)

time.sleep(2)
soup=BeautifulSoup(page.text,'html.parser')

linkitem=soup.find_all('span',attrs={'class':'sc-1bsd7ul-1 djlKtC'})
print(linkitem)

linkprice=soup.find_all('span',attrs={'class':'sc-1bsd7ul-1 sc-13n2dsm-5 kxEbZl deQJPo'})
print(linkprice)
</code>```

Selenium Approach:

```<code>import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

url = "https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571"

options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=options)
driver.get(url)
time.sleep(3)

page = driver.page_source
driver.quit()
soup = BeautifulSoup(page, 'html.parser')

linkitem = soup.find_all('span',attrs={'class':'sc-1bsd7ul-1 djlKtC'})
print(linkitem)
</code>```

答:
That approach of yours with the embedded JSON needs some refinement. In other words, you're almost there. Also, this can be done with pure requests and bs4.

PS. I'm using different URLS, as the one you give returns a 404.

Here's how:

import json

import requests
from bs4 import BeautifulSoup

urls = [
    "https://www.fairprice.com.sg/product/11798142",
    "https://www.fairprice.com.sg/product/vina-maipo-cabernet-sauvignon-merlot-750ml-11690254",
    "https://www.fairprice.com.sg/product/new-moon-new-zealand-abalone-425g-75342",
]

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0",
}

for url in urls:
    product_data = (
        json.loads(
            BeautifulSoup(requests.get(url, headers=headers).text, "lxml")
            .find("script", type="application/ld+json")
            .string[:-1]
        )
    )

    print(product_data["name"])
    print(product_data["offers"]["price"])
```
<p>This should output:</p>
```Nongshim Instant Cup Noodle - Spicy
1.35
Vina Maipo Red Wine - Cabernet Sauvignon Merlot
14.95
New Moon New Zealand Abalone
33.8
```

Body:
I am having difficulties scraping the "product name" and "price" from this website: https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571

Looking to scrap "$4.30" and "Zespri New Zealand Kiwifruit - Green" from the webpage. I have tried various approaches (Beautiful Soup, request_html, selenium) without any success. Attached the sample code approaches I have taken.

I am able to view the 'price' and 'product name' details in the "Developer Tools" tab of Chrome. It seems like that webpage uses Javascript to dynamically load the product information, so the various approaches mentioned above are not able to scrape the information properly.

Appreciate any assistance on this issue.

Requests_html Approach:

from requests_html import HTMLSession
import json

url='https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571'
session = HTMLSession()
r = session.get(url)
r.html.render(timeout=20)

json_text=r.html.xpath("//script[@type='application/ld+json']/text()")[0][:-1]
json_data = json.loads(json_text)
print(json_data['name']['price'])

Beautiful Soup Approach:

import sys
import time
from bs4 import BeautifulSoup
import requests
import re

url='https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571'

headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36 Edg/97.0.1072.69'}
page=requests.get(url, headers=headers)

time.sleep(2)
soup=BeautifulSoup(page.text,'html.parser')

linkitem=soup.find_all('span',attrs={'class':'sc-1bsd7ul-1 djlKtC'})
print(linkitem)

linkprice=soup.find_all('span',attrs={'class':'sc-1bsd7ul-1 sc-13n2dsm-5 kxEbZl deQJPo'})
print(linkprice)

Selenium Approach:

import time
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

url = "https://www.fairprice.com.sg/product/zespri-new-zealand-kiwifruit-green-4-6-per-pack-13045571"

options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=options)
driver.get(url)
time.sleep(3)

page = driver.page_source
driver.quit()
soup = BeautifulSoup(page, 'html.parser')

linkitem = soup.find_all('span',attrs={'class':'sc-1bsd7ul-1 djlKtC'})
print(linkitem)

Body:
That approach of yours with the embedded JSON needs some refinement. In other words, you're almost there. Also, this can be done with pure requests and bs4.

PS. I'm using different URLS, as the one you give returns a 404.

Here's how:

import json

import requests
from bs4 import BeautifulSoup

urls = [
    "https://www.fairprice.com.sg/product/11798142",
    "https://www.fairprice.com.sg/product/vina-maipo-cabernet-sauvignon-merlot-750ml-11690254",
    "https://www.fairprice.com.sg/product/new-moon-new-zealand-abalone-425g-75342",
]

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0",
}

for url in urls:
    product_data = (
        json.loads(
            BeautifulSoup(requests.get(url, headers=headers).text, "lxml")
            .find("script", type="application/ld+json")
            .string[:-1]
        )
    )

    print(product_data["name"])
    print(product_data["offers"]["price"])

This should output:

Nongshim Instant Cup Noodle - Spicy
1.35
Vina Maipo Red Wine - Cabernet Sauvignon Merlot
14.95
New Moon New Zealand Abalone
33.8


问:
Is there a way to reference the function you are inside of in C?
I am writing a function that just looks up values inside of a table. Is it possible to call that function inside of itself? I've seen stuff about this and self and don't really understand it.

答:
See Recursion (computer science) (Wikipedia).

An example of calling a function inside a function:

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

int factorial(unsigned int number)
{
    if (number <= 1)
        return 1;
    return number * factorial(number - 1);
}

void main()
{
    int x = 5;
    printf("factorial of %d is %d",x,factorial(x));
}
</code>```

Body:
See Recursion (computer science) (Wikipedia).

An example of calling a function inside a function:

# include<stdio.h>

int factorial(unsigned int number)
{
    if (number <= 1)
        return 1;
    return number * factorial(number - 1);
}

void main()
{
    int x = 5;
    printf("factorial of %d is %d",x,factorial(x));
}


问:
How can I list all of the configuration sources or properties in ASP.NET Core?
I want to ensure that a particular configuration property is being read from a configuration source. I was going to print out all of the configuration sources (or print out all of the configuration properties), but I can’t seem to figure out how to do that.

Can this be done?

答:
Recently, I have been faced a similar problem.
I found the solution to a task here:
https://github.com/Wallsmedia/DotNetCore.Configuration.Formatter</p>
```<code>    public static List<string> AllConfigurationKeys(this IConfigurationRoot root)
    {
        (string Value, IConfigurationProvider Provider) GetValueAndProvider(
                                                            IConfigurationRoot root,
                                                            string key)
        {
            foreach (IConfigurationProvider provider in root.Providers.Reverse())
            {
                if (provider.TryGet(key, out string value))
                {
                    return (value, provider);
                }
            }

            return (null, null);
        }

        void RecurseChildren(
                HashSet<string> keys,
                IEnumerable<IConfigurationSection> children, string rootPath)
        {
            foreach (IConfigurationSection child in children)
            {
                (string Value, IConfigurationProvider Provider) valueAndProvider = GetValueAndProvider(root, child.Path);

                if (valueAndProvider.Provider != null)
                {
                    keys.Add(rootPath + ":" + child.Key);
                }

                RecurseChildren(keys, child.GetChildren(), child.Path);
            }
        }

        var keys = new HashSet<string>();
        RecurseChildren(keys, root.GetChildren(), "");
        return keys.ToList();
    }
</code>```

Body:
Recently, I have been faced a similar problem.
I found the solution to a task here:
https://github.com/Wallsmedia/DotNetCore.Configuration.Formatter

    public static List<string> AllConfigurationKeys(this IConfigurationRoot root)
    {
        (string Value, IConfigurationProvider Provider) GetValueAndProvider(
                                                            IConfigurationRoot root,
                                                            string key)
        {
            foreach (IConfigurationProvider provider in root.Providers.Reverse())
            {
                if (provider.TryGet(key, out string value))
                {
                    return (value, provider);
                }
            }

            return (null, null);
        }

        void RecurseChildren(
                HashSet<string> keys,
                IEnumerable<IConfigurationSection> children, string rootPath)
        {
            foreach (IConfigurationSection child in children)
            {
                (string Value, IConfigurationProvider Provider) valueAndProvider = GetValueAndProvider(root, child.Path);

                if (valueAndProvider.Provider != null)
                {
                    keys.Add(rootPath + ":" + child.Key);
                }

                RecurseChildren(keys, child.GetChildren(), child.Path);
            }
        }

        var keys = new HashSet<string>();
        RecurseChildren(keys, root.GetChildren(), "");
        return keys.ToList();
    }


问:
MatSort is undefined - Angular 5
I'm trying to implement a Material table in my angular application. Pagination and Filter are working fine, but i'm not able to sort my table. My reference to MatSort is undefined.

I did import it in AppModule:

```<code>import {MatTableModule} from '@angular/material/table';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatButtonModule, MatCheckboxModule,MatPaginatorModule,MatInputModule} from '@angular/material';
import {MatSortModule} from '@angular/material/sort';

...
@NgModule({
  declarations: [...],
  imports: [
     MatSortModule,
     MatTableModule,
     MatPaginatorModule,
     MatInputModule,
     ...
   ]
  })
</code>```

Here is my component.ts:

```<code>import { Component, OnInit , ViewChild, AfterViewInit} from '@angular/core';
...
import {MatTableDataSource,MatSort,MatPaginator} from '@angular/material';
...
export class MyClass inplements OnInit, AfterViewInit{
  @ViewChild(MatSort) sort:MatSort;
  @ViewChild(MatPaginator) paginator:MatPaginator;
  ...
  ngAfterViewInit(){
     this.dataSource = new MatTableDataSource(this.fake_data);
     this.dataSource.paginator = this.paginator
     this.dataSource.sort = this.sort
  }
 ...
}
</code>```

And here is my component HTML:

```<code><mat-form-field *ngIf="ready" class="width-80">
   <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<mat-table #table class = "mat-elevation-z8 animate" matSort [dataSource]="dataSource" display:flex>
   <ng-container matColumnDef="fake_name">
       <mat-header-cell *matHeaderCellDef mat-sort-header class="columnTitle"><b>{{fake_label.name}}</b></mat-header-cell>
       <mat-cell *matCellDef="let fake;" class="cellContent">{{fake.name}}</mat-cell>
   </ng-container>
   <mat-header-row *matHeaderRowDef="fakeColumns"></mat-header-row>
   <mat-row *matRowDef="let row; columns: fakeColumns" class="animate"></mat-row>
</mat-table>
<mat-paginator [length]="length" [pageSize]="5" [pageSizeOptions]="[5,10,15,20,25,50,100]" showFirstLastButtons></mat-paginator>
</code>```

Does anyone know what I'm doing wrong?

答:
For me, I was using two MatTables and for the second one, I was doing pagination and sorting. By mistake I wrote matSort for the first table also.
So, in component file, it was searching for sort and paginator of first table and I was defining it for second table.</p>

Title: MatSort is undefined - Angular 5

Body:
I'm trying to implement a Material table in my angular application. Pagination and Filter are working fine, but i'm not able to sort my table. My reference to MatSort is undefined.

I did import it in AppModule:

import {MatTableModule} from '@angular/material/table';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatButtonModule, MatCheckboxModule,MatPaginatorModule,MatInputModule} from '@angular/material';
import {MatSortModule} from '@angular/material/sort';

...
@NgModule({
  declarations: [...],
  imports: [
     MatSortModule,
     MatTableModule,
     MatPaginatorModule,
     MatInputModule,
     ...
   ]
  })

Here is my component.ts:

import { Component, OnInit , ViewChild, AfterViewInit} from '@angular/core';
...
import {MatTableDataSource,MatSort,MatPaginator} from '@angular/material';
...
export class MyClass inplements OnInit, AfterViewInit{
  @ViewChild(MatSort) sort:MatSort;
  @ViewChild(MatPaginator) paginator:MatPaginator;
  ...
  ngAfterViewInit(){
     this.dataSource = new MatTableDataSource(this.fake_data);
     this.dataSource.paginator = this.paginator
     this.dataSource.sort = this.sort
  }
 ...
}

And here is my component HTML:

<mat-form-field *ngIf="ready" class="width-80">
   <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<mat-table #table class = "mat-elevation-z8 animate" matSort [dataSource]="dataSource" display:flex>
   <ng-container matColumnDef="fake_name">
       <mat-header-cell *matHeaderCellDef mat-sort-header class="columnTitle">{{fake_label.name}}</mat-header-cell>
       <mat-cell *matCellDef="let fake;" class="cellContent">{{fake.name}}</mat-cell>
   </ng-container>
   <mat-header-row *matHeaderRowDef="fakeColumns"></mat-header-row>
   <mat-row *matRowDef="let row; columns: fakeColumns" class="animate"></mat-row>
</mat-table>
<mat-paginator [length]="length" [pageSize]="5" [pageSizeOptions]="[5,10,15,20,25,50,100]" showFirstLastButtons></mat-paginator>

Does anyone know what I'm doing wrong?


问:
how to get Attribute associated Angular FormControl
I have  multiple angular forms which are generated inside a ngFor loop as follows. and each form is a wizard step which a user can move forward by completing the form individually. in the form input fields i have added custom attribute that holds the error message by the dynamic building name. what i m struggling is to display error message associated formControl when click on Next as I cannot get the Native element from the FormControl.

```<code> <div *ngFor="let building of buildings;let i = index" >
   <form #childForms="ngForm" name="{{building.id}}" id="{{building.id}}" >
<input [attr.errorLabel]="'please name of the ' + building.Class " [name]="i + 'buildingName'" type="text" [(ngModel)]="building.Name"  class="text-iput" [required]="true">
   </form>
 </div>

<button styleClass="action" label="Next" (onClick)="goNext(activeStep)"></button>
</code>```

bellow is how i m trying to get the current step from the TS file and try to call validate manually

```<code>   activeStep : number = 0;
   @ViewChildren('childForms', {read: NgForm}) childForms: QueryList<NgForm>;

   goNext(activeStep) {

     errors = [];
     for (const name in this.childForms[activeStep].controls) {
         if (this.childForms[activeStep].controls[name].invalid) {
            // How Can I get the ATTRIBUTE associated with the form control here
             // any way that i can get the native element of the Form Control
             // in my case [attr.errorLabel]="'please name of the ' + building.Class "
         }
     }
  }
</code>```

答:
you can use a template reference variable in the inputs (I suggest also the name of the input was the same that the name of the control (*))

```<code><input #input [attr.errorLabel]="..." [name]="building.Name'" ...>
</code>```

then you can use

```<code>@ViewChildren('input',{read:ElementRef}) inputs:Query<ElementRef>
</code>```

Then you can use some like

```<code>if (this.childForms[activeStep].controls[name].invalid) {
    const input=this.inputs.find(x=>x.nativeElement==name)
    const attr=input.nativeElement.getAttribute('errorLabel')
    ....
}
</code>```

(*)If only has the inputs and you can not change the name you can use

```<code>let i=0;
for (const name in this.childForms[activeStep].controls) {
    if (this.childForms[activeStep].controls[name].invalid) {
        const input=this.inputs.find((x,index)=>index==i)
        const attr=input.nativeElement.getAttribute('errorLabel')
        ....
    }
    i++;
}
</code>```

NOTE: you should check if exist the input to avoid errors. You can use a ternary operator

```<code>    const attr=input?input.nativeElement.getAttribute('errorLabel'):null
</code>```

Body:
I have  multiple angular forms which are generated inside a ngFor loop as follows. and each form is a wizard step which a user can move forward by completing the form individually. in the form input fields i have added custom attribute that holds the error message by the dynamic building name. what i m struggling is to display error message associated formControl when click on Next as I cannot get the Native element from the FormControl.

   <form #childForms="ngForm" name="{{building.id}}" id="{{building.id}}" >
<input [attr.errorLabel]="'please name of the ' + building.Class " [name]="i + 'buildingName'" type="text" [(ngModel)]="building.Name"  class="text-iput" [required]="true">
   </form>

<button styleClass="action" label="Next" (onClick)="goNext(activeStep)"></button>

bellow is how i m trying to get the current step from the TS file and try to call validate manually

   activeStep : number = 0;
   @ViewChildren('childForms', {read: NgForm}) childForms: QueryList<NgForm>;

   goNext(activeStep) {

     errors = [];
     for (const name in this.childForms[activeStep].controls) {
         if (this.childForms[activeStep].controls[name].invalid) {
            // How Can I get the ATTRIBUTE associated with the form control here
             // any way that i can get the native element of the Form Control
             // in my case [attr.errorLabel]="'please name of the ' + building.Class "
         }
     }
  }

Body:
you can use a template reference variable in the inputs (I suggest also the name of the input was the same that the name of the control (*))

<input #input [attr.errorLabel]="..." [name]="building.Name'" ...>

then you can use

@ViewChildren('input',{read:ElementRef}) inputs:Query<ElementRef>

Then you can use some like

if (this.childForms[activeStep].controls[name].invalid) {
    const input=this.inputs.find(x=>x.nativeElement==name)
    const attr=input.nativeElement.getAttribute('errorLabel')
    ....
}

(*)If only has the inputs and you can not change the name you can use

let i=0;
for (const name in this.childForms[activeStep].controls) {
    if (this.childForms[activeStep].controls[name].invalid) {
        const input=this.inputs.find((x,index)=>index==i)
        const attr=input.nativeElement.getAttribute('errorLabel')
        ....
    }
    i++;
}

NOTE: you should check if exist the input to avoid errors. You can use a ternary operator

    const attr=input?input.nativeElement.getAttribute('errorLabel'):null


问:
Why does fmt.Scan() behave in a weird way?
I'm trying to validate the user input. If the user inputs an integer number it works like expected. However, if the user inputs a non-integer string, the variable userTickets gets assigned value 0, but prints Try again! It must be more than zero:  many times. To be exact, it prints len(input) times and I don't understand why.

Also tried achieving desired result using fmt.Scanf("%d", &usertickets) but got an identical result.

Why does it behave this way and how can I write a workaround for it?

```<code>package main

import "fmt"

func main() {

    var remainingTickets uint = 50
    var userTickets uint

    fmt.Print("Enter the number of tickets you want to purchase: ")
    fmt.Scan(&userTickets)

    for userTickets > remainingTickets {
        fmt.Printf("We only have %v tickets available!\n", remainingTickets)
        fmt.Print("Try again! Enter the number of tickets: ")
        fmt.Scan(&userTickets)
    }

    for userTickets == 0 {
        fmt.Print("Try again! It must be more than zero: ")
        fmt.Scan(&userTickets)
    }

    fmt.Printf("Remaining tickets: %v\n", remainingTickets-userTickets)

}

</code>```

答:
Scan is able to determine that the input isn't numeric without reading the entire contents of stdin.  This is why you validation logic loops for len(input) when non-numeric.  While you can use a Scanner as well (and people do recommend that approach), below is an approach similar to yours.  Note that all validation checking is done within a single "for" loop as well:</p>
```<code>package main

import (
    "fmt"
    "strconv"
)

func main() {

    var remainingTickets uint64 = 50

    fmt.Print("Enter the number of tickets you want to purchase: ")

    for {
        var userTickets string
        fmt.Scanln(&userTickets)

        // parse to make sure we get a positive (unsigned) integer
        u64, err := strconv.ParseUint(userTickets,10,64)
        // make sure it's a postive integer and not equal to zero
        if err != nil || u64==0{
            fmt.Print("Try again! You must enter a number greater than zero: ")
            continue
        }

        // check to make sure we have enough tickets left
        if u64 > remainingTickets {
            fmt.Printf("We only have %v tickets available!\n", remainingTickets)
            fmt.Print("Try again! Enter the number of tickets: ")
            continue
        }

        // update remaining tickets
        remainingTickets -= u64
        break
    }

    fmt.Printf("Remaining tickets: %d\n", remainingTickets)
}
</code>```

Body:
I'm trying to validate the user input. If the user inputs an integer number it works like expected. However, if the user inputs a non-integer string, the variable userTickets gets assigned value 0, but prints Try again! It must be more than zero:  many times. To be exact, it prints len(input) times and I don't understand why.

Also tried achieving desired result using fmt.Scanf("%d", &usertickets) but got an identical result.

Why does it behave this way and how can I write a workaround for it?

package main

import "fmt"

func main() {

    var remainingTickets uint = 50
    var userTickets uint

    fmt.Print("Enter the number of tickets you want to purchase: ")
    fmt.Scan(&userTickets)

    for userTickets > remainingTickets {
        fmt.Printf("We only have %v tickets available!\n", remainingTickets)
        fmt.Print("Try again! Enter the number of tickets: ")
        fmt.Scan(&userTickets)
    }

    for userTickets == 0 {
        fmt.Print("Try again! It must be more than zero: ")
        fmt.Scan(&userTickets)
    }

    fmt.Printf("Remaining tickets: %v\n", remainingTickets-userTickets)

}

Body:
Scan is able to determine that the input isn't numeric without reading the entire contents of stdin.  This is why you validation logic loops for len(input) when non-numeric.  While you can use a Scanner as well (and people do recommend that approach), below is an approach similar to yours.  Note that all validation checking is done within a single "for" loop as well:

package main

import (
    "fmt"
    "strconv"
)

func main() {

    var remainingTickets uint64 = 50

    fmt.Print("Enter the number of tickets you want to purchase: ")

    for {
        var userTickets string
        fmt.Scanln(&userTickets)

        // parse to make sure we get a positive (unsigned) integer
        u64, err := strconv.ParseUint(userTickets,10,64)
        // make sure it's a postive integer and not equal to zero
        if err != nil || u64==0{
            fmt.Print("Try again! You must enter a number greater than zero: ")
            continue
        }

        // check to make sure we have enough tickets left
        if u64 > remainingTickets {
            fmt.Printf("We only have %v tickets available!\n", remainingTickets)
            fmt.Print("Try again! Enter the number of tickets: ")
            continue
        }

        // update remaining tickets
        remainingTickets -= u64
        break
    }

    fmt.Printf("Remaining tickets: %d\n", remainingTickets)
}