问:
Using Selenium and Beautiful Soup together
I'm scraping a google scholar profile page, and right now I have python code from the beautiful soup library which collects data from the page:

```<code>url = "https://scholar.google.com/citations?user=VjJm3zYAAAAJ&hl=en"
while True:

    response = requests.get(url)
    data = response.text
    soup = BeautifulSoup(data,'html.parser')
    research_article = soup.find_all('tr',{'class':'gsc_a_tr'})

    for research in research_article:

        title = research.find('a',{'class':'gsc_a_at'}).text
        authors = research.find('div',{'class':'gs_gray'}).text

        print('Title:', title,'\n','\nAuthors:', authors)
</code>```

I also have python code from the selenium library that automates the profile page to click the 'show more' button:

```<code>driver = webdriver.Chrome(executable_path ="/Applications/chromedriver84")
driver.get(url)

try:
    #Wait up to 10s until the element is loaded on the page
    element = WebDriverWait(driver, 10).until(
        #Locate element by id
        EC.presence_of_element_located((By.ID, 'gsc_bpf_more'))
    )
finally:
    element.click()
</code>```

How can I combine these two blocks of code so that I can click the 'show more' button, and scrape the entire page? Thanks in advance!

答:
This approach is very similar to Andrej Kesely's answer except the if statement, code style, and provides an alternative solution.

Code and example in the online IDE:

from bs4 import BeautifulSoup
import requests, lxml

# https://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
params = {
    "user": "VjJm3zYAAAAJ", # user-id
    "hl": "en",             # language
    "gl": "us",             # country to search from
    "cstart": 0,            # articles page. 0 is the first page
    "pagesize": "100"       # articles per page
}

# https://docs.python-requests.org/en/master/user/quickstart/#custom-headers
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3538.102 Safari/537.36 Edge/18.19582",
}

articles_is_present = True

while articles_is_present:
    # timeout to stop waiting for response after 30 sec
    html = requests.post("https://scholar.google.com/citations", params=params, headers=headers, timeout=30)
    soup = BeautifulSoup(html.text, "lxml")

    for index, article in enumerate(soup.select("#gsc_a_b .gsc_a_t"), start=1):
        article_title = article.select_one(".gsc_a_at").text
        article_link = f'https://scholar.google.com{article.select_one(".gsc_a_at")["href"]}'
        article_authors = article.select_one(".gsc_a_at+ .gs_gray").text
        article_publication = article.select_one(".gs_gray+ .gs_gray").text

        print(f"article #{int(params['cstart']) + index}",
              article_title,
              article_link,
              article_authors,
              article_publication, sep="\n")

    # this selector is checking for the .class that contains: "There are no articles in this profile."
    # example link: https://scholar.google.com/citations?user=VjJm3zYAAAAJ&hl=en&cstart=500&pagesize=100
    if soup.select_one(".gsc_a_e"):
        articles_is_present = False
    else:
        params["cstart"] += 100  # paginate to the next page

# output:
'''
article #1
Hyper-heuristics: A survey of the state of the art
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:5N-NJrZHaHcC
EK Burke, M Gendreau, M Hyde, G Kendall, G Ochoa, E Özcan, R Qu
Journal of the Operational Research Society 64 (12), 1695-1724, 2013

article #2
Hyper-heuristics: An emerging direction in modern search technology
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:u5HHmVD_uO8C
E Burke, G Kendall, J Newall, E Hart, P Ross, S Schulenburg
Handbook of metaheuristics, 457-474, 2003
...
article #428
A Library of Vehicle Routing Problems
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:bnK-pcrLprsC
T Pigden, G Kendall, SD Ehsan, E Ozcan, R Eglese

article #429
This symposium could not have taken place without the help of a great many people and organisations. We would like to thank the IEEE Computational Intelligence Society for …
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:D_sINldO8mEC
S Louis, G Kendall
'''
```
<hr />
<p>Alternatively, you can achieve it using Google Scholar Author API from SerpApi. It's a paid API with a free plan.</p>
<p>Essentially it is almost the same thing except you don't have to think about how to scale the number of requests, find a good proxy/captcha provider because it's done for the user, or how scrape data from JavaScript without using a browser automation.</p>
<p>Example code to scrape all author articles:</p>
<pre class="lang-py prettyprint-override"><code>from serpapi import GoogleSearch
from urllib.parse import urlsplit, parse_qsl
import os

params = {
    "api_key": os.getenv("API_KEY"),
    "engine": "google_scholar_author",
    "hl": "en",
    "author_id": "VjJm3zYAAAAJ",
    "start": "0",
    "num": "100"
}

search = GoogleSearch(params)

articles_is_present = True

while articles_is_present:
    results = search.get_dict()

    for index, article in enumerate(results["articles"], start=1):
        title = article["title"]
        link = article["link"]
        authors = article["authors"]
        publication = article.get("publication")
        citation_id = article["citation_id"]

        print(f"article #{int(params['start']) + index}",
              title,
              link,
              authors,
              publication,
              citation_id, sep="\n")

    if "next" in results.get("serpapi_pagination", []):
        # split URL in parts as a dict() and update search "params" variable to a new page
        search.params_dict.update(dict(parse_qsl(urlsplit(results["serpapi_pagination"]["next"]).query))))
    else:
        articles_is_present = False

# output:
'''
article #1
Hyper-heuristics: A survey of the state of the art
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:5N-NJrZHaHcC
EK Burke, M Gendreau, M Hyde, G Kendall, G Ochoa, E Özcan, R Qu
Journal of the Operational Research Society 64 (12), 1695-1724, 2013
VjJm3zYAAAAJ:5N-NJrZHaHcC

article #2
Hyper-heuristics: An emerging direction in modern search technology
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:u5HHmVD_uO8C
E Burke, G Kendall, J Newall, E Hart, P Ross, S Schulenburg
Handbook of metaheuristics, 457-474, 2003
VjJm3zYAAAAJ:u5HHmVD_uO8C
...
article #428
A Library of Vehicle Routing Problems
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:bnK-pcrLprsC
T Pigden, G Kendall, SD Ehsan, E Ozcan, R Eglese
None
VjJm3zYAAAAJ:bnK-pcrLprsC

article #429
This symposium could not have taken place without the help of a great many people and organisations. We would like to thank the IEEE Computational Intelligence Society for …
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:D_sINldO8mEC
S Louis, G Kendall
None
VjJm3zYAAAAJ:D_sINldO8mEC
'''
</code>```

If you would like to scrape organic, cite results from all available pages, there's a dedicated blog post of mine - Scrape historic Google Scholar results using Python at SerpApi.

Disclaimer, I work for SerpApi.

Body:
I'm scraping a google scholar profile page, and right now I have python code from the beautiful soup library which collects data from the page:

url = "https://scholar.google.com/citations?user=VjJm3zYAAAAJ&hl=en"
while True:

    response = requests.get(url)
    data = response.text
    soup = BeautifulSoup(data,'html.parser')
    research_article = soup.find_all('tr',{'class':'gsc_a_tr'})

    for research in research_article:

        title = research.find('a',{'class':'gsc_a_at'}).text
        authors = research.find('div',{'class':'gs_gray'}).text

        print('Title:', title,'\n','\nAuthors:', authors)

I also have python code from the selenium library that automates the profile page to click the 'show more' button:

driver = webdriver.Chrome(executable_path ="/Applications/chromedriver84")
driver.get(url)

try:
    #Wait up to 10s until the element is loaded on the page
    element = WebDriverWait(driver, 10).until(
        #Locate element by id
        EC.presence_of_element_located((By.ID, 'gsc_bpf_more'))
    )
finally:
    element.click()

How can I combine these two blocks of code so that I can click the 'show more' button, and scrape the entire page? Thanks in advance!

Body:
This approach is very similar to Andrej Kesely's answer except the if statement, code style, and provides an alternative solution.

Code and example in the online IDE:

from bs4 import BeautifulSoup
import requests, lxml

# https://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
params = {
    "user": "VjJm3zYAAAAJ", # user-id
    "hl": "en",             # language
    "gl": "us",             # country to search from
    "cstart": 0,            # articles page. 0 is the first page
    "pagesize": "100"       # articles per page
}

# https://docs.python-requests.org/en/master/user/quickstart/#custom-headers
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3538.102 Safari/537.36 Edge/18.19582",
}

articles_is_present = True

while articles_is_present:
    # timeout to stop waiting for response after 30 sec
    html = requests.post("https://scholar.google.com/citations", params=params, headers=headers, timeout=30)
    soup = BeautifulSoup(html.text, "lxml")

    for index, article in enumerate(soup.select("#gsc_a_b .gsc_a_t"), start=1):
        article_title = article.select_one(".gsc_a_at").text
        article_link = f'https://scholar.google.com{article.select_one(".gsc_a_at")["href"]}'
        article_authors = article.select_one(".gsc_a_at+ .gs_gray").text
        article_publication = article.select_one(".gs_gray+ .gs_gray").text

        print(f"article #{int(params['cstart']) + index}",
              article_title,
              article_link,
              article_authors,
              article_publication, sep="\n")

    # this selector is checking for the .class that contains: "There are no articles in this profile."
    # example link: https://scholar.google.com/citations?user=VjJm3zYAAAAJ&hl=en&cstart=500&pagesize=100
    if soup.select_one(".gsc_a_e"):
        articles_is_present = False
    else:
        params["cstart"] += 100  # paginate to the next page

# output:
'''
article #1
Hyper-heuristics: A survey of the state of the art
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:5N-NJrZHaHcC
EK Burke, M Gendreau, M Hyde, G Kendall, G Ochoa, E Özcan, R Qu
Journal of the Operational Research Society 64 (12), 1695-1724, 2013

article #2
Hyper-heuristics: An emerging direction in modern search technology
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:u5HHmVD_uO8C
E Burke, G Kendall, J Newall, E Hart, P Ross, S Schulenburg
Handbook of metaheuristics, 457-474, 2003
...
article #428
A Library of Vehicle Routing Problems
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:bnK-pcrLprsC
T Pigden, G Kendall, SD Ehsan, E Ozcan, R Eglese

article #429
This symposium could not have taken place without the help of a great many people and organisations. We would like to thank the IEEE Computational Intelligence Society for …
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:D_sINldO8mEC
S Louis, G Kendall
'''

Alternatively, you can achieve it using Google Scholar Author API from SerpApi. It's a paid API with a free plan.

Essentially it is almost the same thing except you don't have to think about how to scale the number of requests, find a good proxy/captcha provider because it's done for the user, or how scrape data from JavaScript without using a browser automation.

Example code to scrape all author articles:

from serpapi import GoogleSearch
from urllib.parse import urlsplit, parse_qsl
import os

params = {
    "api_key": os.getenv("API_KEY"),
    "engine": "google_scholar_author",
    "hl": "en",
    "author_id": "VjJm3zYAAAAJ",
    "start": "0",
    "num": "100"
}

search = GoogleSearch(params)

articles_is_present = True

while articles_is_present:
    results = search.get_dict()

    for index, article in enumerate(results["articles"], start=1):
        title = article["title"]
        link = article["link"]
        authors = article["authors"]
        publication = article.get("publication")
        citation_id = article["citation_id"]

        print(f"article #{int(params['start']) + index}",
              title,
              link,
              authors,
              publication,
              citation_id, sep="\n")

    if "next" in results.get("serpapi_pagination", []):
        # split URL in parts as a dict() and update search "params" variable to a new page
        search.params_dict.update(dict(parse_qsl(urlsplit(results["serpapi_pagination"]["next"]).query))))
    else:
        articles_is_present = False

# output:
'''
article #1
Hyper-heuristics: A survey of the state of the art
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:5N-NJrZHaHcC
EK Burke, M Gendreau, M Hyde, G Kendall, G Ochoa, E Özcan, R Qu
Journal of the Operational Research Society 64 (12), 1695-1724, 2013
VjJm3zYAAAAJ:5N-NJrZHaHcC

article #2
Hyper-heuristics: An emerging direction in modern search technology
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&pagesize=100&citation_for_view=VjJm3zYAAAAJ:u5HHmVD_uO8C
E Burke, G Kendall, J Newall, E Hart, P Ross, S Schulenburg
Handbook of metaheuristics, 457-474, 2003
VjJm3zYAAAAJ:u5HHmVD_uO8C
...
article #428
A Library of Vehicle Routing Problems
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:bnK-pcrLprsC
T Pigden, G Kendall, SD Ehsan, E Ozcan, R Eglese
None
VjJm3zYAAAAJ:bnK-pcrLprsC

article #429
This symposium could not have taken place without the help of a great many people and organisations. We would like to thank the IEEE Computational Intelligence Society for …
https://scholar.google.com/citations?view_op=view_citation&hl=en&user=VjJm3zYAAAAJ&cstart=400&pagesize=100&citation_for_view=VjJm3zYAAAAJ:D_sINldO8mEC
S Louis, G Kendall
None
VjJm3zYAAAAJ:D_sINldO8mEC
'''

If you would like to scrape organic, cite results from all available pages, there's a dedicated blog post of mine - Scrape historic Google Scholar results using Python at SerpApi.

Disclaimer, I work for SerpApi.


来源: stackexchange

问:
Comparing function to number in lua
```<code>    start = io.read()
    if start == "start" then
    xpr = 50
    xp = 75
    function level()
        if xp >= xpr and level < 50 then
            xpr = xpr * 1.5
            level = level + 1
            io.write("Congrats you somehow didn't die and lose every bit of progress!", "\n")
            io.write("By the way your level is ", level, "\n")
            io.write("Now you must allocate your skill points now", "\n")
            sp = 6
            io.write("Strength: ", "\n")
            strsp = io.read()
            stre = stre + strsp
            if strsp < sp then
                io.write("There are only",sp,"skill points", "\n")
                str = str + 6
            end
            io.write("Dexterity: ", "\n")
            dexsp = io.read()
            dex = dex + dexsp
            if dexsp < sp then
                io.write("There are only",sp,"skill points", "\n")
                dex = dex + 6
            end
            io.write("Constuion: ", "\n")
            consp = io.read()
            con = con + consp
            if consp < sp then
                io.write("There are only",sp,"skill points", "\n")
                con = con + 6
            end
            io.write("Intelligence: ", "\n")
            intsp = io.read()
            int = int + intsp
            if intsp < sp then
                io.write("There are only",sp,"skill points", "\n")
                int = int + 6
            end
            io.write("Wisdom: ", "\n")
            wissp = io.read()
            wis = wis + wissp
            if wissp < sp then
                io.write("There are only",sp,"skill points", "\n")
                wis = wis + 6
            end
            io.write("Charisma: ", "\n")
            chasp = io.read()
            cha = cha + chasp
            if chasp < sp then
                io.write("There are only",sp,"skill points", "\n")
                cha = cha + 6
            end
        end
    end
 end

print(level(xp))
</code>```

This is my code. But it comes back as

lua: attempt to compare function with number

How can I fix this?

答:
Comparing a function with a number doesn't make any sense.

function level() end is syntactic sugar for level = function () end. Just in case you're wondering why level is a function value.

level < 50 compares your global function level with 50.

You call level(xp) but level doesn't have any parameters btw.

Either rename the function or the variable you want to compare with 50.
Either way you need to initialize that variable with a number value or you'll get an error for comparing nil with a number.

ContentLicense: CC BY-SA 4.0

Title: Comparing function to number in lua

Body:
    start = io.read()
    if start == "start" then
    xpr = 50
    xp = 75
    function level()
        if xp >= xpr and level < 50 then
            xpr = xpr * 1.5
            level = level + 1
            io.write("Congrats you somehow didn't die and lose every bit of progress!", "\n")
            io.write("By the way your level is ", level, "\n")
            io.write("Now you must allocate your skill points now", "\n")
            sp = 6
            io.write("Strength: ", "\n")
            strsp = io.read()
            stre = stre + strsp
            if strsp < sp then
                io.write("There are only",sp,"skill points", "\n")
                str = str + 6
            end
            io.write("Dexterity: ", "\n")
            dexsp = io.read()
            dex = dex + dexsp
            if dexsp < sp then
                io.write("There are only",sp,"skill points", "\n")
                dex = dex + 6
            end
            io.write("Constuion: ", "\n")
            consp = io.read()
            con = con + consp
            if consp < sp then
                io.write("There are only",sp,"skill points", "\n")
                con = con + 6
            end
            io.write("Intelligence: ", "\n")
            intsp = io.read()
            int = int + intsp
            if intsp < sp then
                io.write("There are only",sp,"skill points", "\n")
                int = int + 6
            end
            io.write("Wisdom: ", "\n")
            wissp = io.read()
            wis = wis + wissp
            if wissp < sp then
                io.write("There are only",sp,"skill points", "\n")
                wis = wis + 6
            end
            io.write("Charisma: ", "\n")
            chasp = io.read()
            cha = cha + chasp
            if chasp < sp then
                io.write("There are only",sp,"skill points", "\n")
                cha = cha + 6
            end
        end
    end
 end

print(level(xp))

This is my code. But it comes back as

lua: attempt to compare function with number

How can I fix this?


问:
sending the value from jsp to java or javascript to java
I have a list of names in a table. When I click the name, it displays people under that particular name.
Ex:

```<code>aaa       bbb
          ccc
</code>```

Now I want to do moveover on aaa which l show 2 (number of ppl under aaa) in a tooltip.

```<code><a id="tool" title="toolTip" onmouseover="toolTip(localArrGroupNames[<%=in.intValue() %>])">

function toolTip(name){
  alert(name);
  //can I send this name to a java class ???

}
</code>```

I get the name aaa in the localArrGroupNames[0].But I am unable to get the name in a java class where i count the number of people below the aaa. How to send this value to java class? Please help me.

答:
```<code>function toolTip(name){
   alert(name);
   //can I send this name to a java class ???

    new Ajax.Request('jspFile.jsp', {
        parameters: {
            name: name
        },
        method: 'get',
        onComplete: function(transport) {
            var resp = transport.responseText.strip();
            $('tool').update(resp);
        }
    });
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I have a list of names in a table. When I click the name, it displays people under that particular name.
Ex:

aaa       bbb
          ccc

Now I want to do moveover on aaa which l show 2 (number of ppl under aaa) in a tooltip.

<a id="tool" title="toolTip" onmouseover="toolTip(localArrGroupNames[<%=in.intValue() %>])">

function toolTip(name){
  alert(name);
  //can I send this name to a java class ???

}

I get the name aaa in the localArrGroupNames[0].But I am unable to get the name in a java class where i count the number of people below the aaa. How to send this value to java class? Please help me.


问:
PHP Deprecated: Automatic conversion of false to array is deprecated adodb-mssqlnative.inc.php on line 154
We are upgrading PHP to version 8.1. Using MS Sql Server DB. It all seems to work correctly but I see repeated messages in the log file:

[03-Feb-2022 11:51:18 America/New_York] PHP Deprecated:  Automatic conversion of false to array is deprecated in C:...\includes\adodb\drivers\adodb-mssqlnative.inc.php on line 154

I've updated adodb to version version 5.22 but that did not stop the messges from logging. The ini file has

```<code>extension=php_sqlsrv_81_nts_x64.dll
extension=php_pdo_sqlsrv_81_nts_x64.dll
</code>```

Does anyone know how to fix this problem?

答:
This is a known issue of backwards incompatibility, affecting the ADOdb library version 5.22.1 and older. PHP 8.1 warns you on autovivification of false-y values and some future version of PHP will throw an error when you do it.

PHP natively allows for autovivification (auto-creation of arrays from falsey values). This feature is very useful and used in a lot of PHP projects, especially if the variable is undefined. However, there is a little oddity that allows creating an array from a false and null value.

And they give this example

```<code>// From false
$arr = false;
$arr[] = 2;
</code>```

I went and found the file in question and this is the function it's in

```<code>function ServerInfo() {
    global $ADODB_FETCH_MODE;
    static $arr = false;
    if (is_array($arr))
        return $arr;
    if ($this->fetchMode === false) {
        $savem = $ADODB_FETCH_MODE;
        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
    } elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
        $savem = $this->fetchMode;
    } else
        $savem = $this->SetFetchMode(ADODB_FETCH_NUM);

    $arrServerInfo = sqlsrv_server_info($this->_connectionID);
    $ADODB_FETCH_MODE = $savem;
    $arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
    $arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
    return $arr;
}
</code>```

The problem is that it starts with

```<code>static $arr = false;
</code>```

and then tries to autovivificate a non-array (line 154 in your error)

```<code>$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
</code>```

You should be able to fix it (in theory) by making sure it's an array (something they should have done anyways). Add this above that line to make it one before it tries to append

```<code>if(!is_array($arr)) $arr = [];
</code>```

Body:
We are upgrading PHP to version 8.1. Using MS Sql Server DB. It all seems to work correctly but I see repeated messages in the log file:

[03-Feb-2022 11:51:18 America/New_York] PHP Deprecated:  Automatic conversion of false to array is deprecated in C:...\includes\adodb\drivers\adodb-mssqlnative.inc.php on line 154

I've updated adodb to version version 5.22 but that did not stop the messges from logging. The ini file has

extension=php_sqlsrv_81_nts_x64.dll
extension=php_pdo_sqlsrv_81_nts_x64.dll

Does anyone know how to fix this problem?

Body:
This is a known issue of backwards incompatibility, affecting the ADOdb library version 5.22.1 and older. PHP 8.1 warns you on autovivification of false-y values and some future version of PHP will throw an error when you do it.

PHP natively allows for autovivification (auto-creation of arrays from falsey values). This feature is very useful and used in a lot of PHP projects, especially if the variable is undefined. However, there is a little oddity that allows creating an array from a false and null value.

And they give this example

// From false
$arr = false;
$arr[] = 2;

I went and found the file in question and this is the function it's in

function ServerInfo() {
    global $ADODB_FETCH_MODE;
    static $arr = false;
    if (is_array($arr))
        return $arr;
    if ($this->fetchMode === false) {
        $savem = $ADODB_FETCH_MODE;
        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
    } elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
        $savem = $this->fetchMode;
    } else
        $savem = $this->SetFetchMode(ADODB_FETCH_NUM);

    $arrServerInfo = sqlsrv_server_info($this->_connectionID);
    $ADODB_FETCH_MODE = $savem;
    $arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
    $arr['version'] = $arrServerInfo['SQLServerVersion'];//ADOConnection::_findvers($arr['description']);
    return $arr;
}

The problem is that it starts with

static $arr = false;

and then tries to autovivificate a non-array (line 154 in your error)

$arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];

You should be able to fix it (in theory) by making sure it's an array (something they should have done anyways). Add this above that line to make it one before it tries to append

if(!is_array($arr)) $arr = [];


问:
Retrieving currentTime from <audio> element for every 'timeupdate' event crashes browser
I'm trying to update a state variable with the value of the currentTime attribute from an  element. I add an event listener to the 'timeupdate' event so I can call setPosition with the value of currentTime (position is used to position the knob on a slider representing song playback).

However, retrieving audioElement.currentTime and using the result as the argument to setPosition makes my browser (both Chrome and Safari) crash. In fact, the Activity Monitor on my macBook shows that the number of threads being used by the local website increases continuously as the audio file plays back, but I am not sure what that means. The site also uses significant memory, but ONLY when retrieving the currentTime attribute for every 'timeupdate' event.

I have no idea what is causing performance issues in my component, at least I'm assuming it is a performance issue.

The audio file played is .wav

```<code>function SongPlayer({ file }) {
  const [audioElement] = useState(new Audio(file));
  const [playing, setPlay] = useState(null);
  const [audioContext] = useState(new AudioContext({ sampleRate: 44100 }));
  const [gainNode] = useState(audioContext.createGain());
  const [position, setPosition] = useState(0);

  useEffect(
    () => {
      const track = audioContext.createMediaElementSource(audioElement);
      track.connect(gainNode).connect(audioContext.destination);
      audioElement.addEventListener('timeupdate', () => {
        setPosition(audioElement.currentTime);
      });
    },
    [],
  );

  useEffect(
    () => {
      if (playing) audioElement.play();
      else if (!playing) audioElement.pause();
    },
    [playing],
  );

  return (
        <>
        </>
  );
}

export default SongPlayer;
</code>```

localhost using +500 threads and over 1Gb of memory

EDIT:

the problem was when I was calling new AudioContext() as an initial state value.
The constructor was getting called with every render.

This post helped me figure it out and explains it well: https://stackoverflow.com/a/64131447/13757284

答: I would recommend to you use Cleanup callback of useEffect, to remove eventListener.</p>

Body:
I'm trying to update a state variable with the value of the currentTime attribute from an  element. I add an event listener to the 'timeupdate' event so I can call setPosition with the value of currentTime (position is used to position the knob on a slider representing song playback).

However, retrieving audioElement.currentTime and using the result as the argument to setPosition makes my browser (both Chrome and Safari) crash. In fact, the Activity Monitor on my macBook shows that the number of threads being used by the local website increases continuously as the audio file plays back, but I am not sure what that means. The site also uses significant memory, but ONLY when retrieving the currentTime attribute for every 'timeupdate' event.

I have no idea what is causing performance issues in my component, at least I'm assuming it is a performance issue.

The audio file played is .wav

function SongPlayer({ file }) {
  const [audioElement] = useState(new Audio(file));
  const [playing, setPlay] = useState(null);
  const [audioContext] = useState(new AudioContext({ sampleRate: 44100 }));
  const [gainNode] = useState(audioContext.createGain());
  const [position, setPosition] = useState(0);

  useEffect(
    () => {
      const track = audioContext.createMediaElementSource(audioElement);
      track.connect(gainNode).connect(audioContext.destination);
      audioElement.addEventListener('timeupdate', () => {
        setPosition(audioElement.currentTime);
      });
    },
    [],
  );

  useEffect(
    () => {
      if (playing) audioElement.play();
      else if (!playing) audioElement.pause();
    },
    [playing],
  );

  return (
        <>
        </>
  );
}

export default SongPlayer;

localhost using +500 threads and over 1Gb of memory

EDIT:

the problem was when I was calling new AudioContext() as an initial state value.
The constructor was getting called with every render.

This post helped me figure it out and explains it well: https://stackoverflow.com/a/64131447/13757284


问:
Query field added but not visible in template
In my Symfony project I try to append new array key-value pair into the result I am rendering to twig template file.
It has some odd behaviour.

```<code>$posts = $this->entityManager->getRepository(Post::class)->getPage($listType, $page, $pageSize);

foreach ($posts['data'] as $post) {
    $post['destinationName'] = $this->destinationService->getDestinationName($posts['data']);
}

return $this->render('posts.html.twig', [
    'posts' => $posts['data'],
]);
</code>```

Trough this getPage() method in my controller I get paginated list of my data. Which is working. Than in the foreach() I am appending new key-value pair to that array.

When dumping $posts I get: IMAGE

When dumping $post from foreach, this is the output I get: IMAGE As you can see, the last pair, destinationName is added.

Then when dumping the same result in my twig template I get: IMAGE

As you can see, when template is rendered, it disappears.

My question is, that maybe it's overwritten? But I can not see why. Do I maybe need to append that filed in my query builder? But as I am adding the field after result is rendered, I suppose that should not be the case..

Any hints?

Maybe getDestinationName() will show something:

```<code>public function getDestinationName($posts)
{
    foreach ($posts as $postsData) {
        foreach ($postsData as $post) {
            $destinationName =  $this->getDestinationDetails(
                $post->getDestinationId(),
                $post->getAccountTokenId()
            );
            return $destinationName['full_name'];
        }
    }
}
</code>```

答:
It's not a good practice to mixe array with object and then add other stuff.
The best thing you could do is this :

```<code>$posts = $this->entityManager->getRepository(Post::class)->getPage($listType, $page, $pageSize);

$destinationNames = [];
foreach ($posts['data'] as $post) {
    $destinationNames[$post->getPostId()] = $this->destinationService->getDestinationName($posts['data']);
}

return $this->render('posts.html.twig', [
    'posts' => $posts['data'],
    'destinationNames' => $destinationNames,
]);
</code>```

I suppose here that $post->getPostId() is your unique identifier, if not, replace by the right identifier

And in your template you could do something like :

```<code>{% for post in posts %}
    // do your stuff
    {{ destinationNames[post.id] }}
{% endfor %}
</code>```

Body:
In my Symfony project I try to append new array key-value pair into the result I am rendering to twig template file.
It has some odd behaviour.

$posts = $this->entityManager->getRepository(Post::class)->getPage($listType, $page, $pageSize);

foreach ($posts['data'] as $post) {
    $post['destinationName'] = $this->destinationService->getDestinationName($posts['data']);
}

return $this->render('posts.html.twig', [
    'posts' => $posts['data'],
]);

Trough this getPage() method in my controller I get paginated list of my data. Which is working. Than in the foreach() I am appending new key-value pair to that array.

When dumping $posts I get: IMAGE

When dumping $post from foreach, this is the output I get: IMAGE As you can see, the last pair, destinationName is added.

Then when dumping the same result in my twig template I get: IMAGE

As you can see, when template is rendered, it disappears.

My question is, that maybe it's overwritten? But I can not see why. Do I maybe need to append that filed in my query builder? But as I am adding the field after result is rendered, I suppose that should not be the case..

Any hints?

Maybe getDestinationName() will show something:

public function getDestinationName($posts)
{
    foreach ($posts as $postsData) {
        foreach ($postsData as $post) {
            $destinationName =  $this->getDestinationDetails(
                $post->getDestinationId(),
                $post->getAccountTokenId()
            );
            return $destinationName['full_name'];
        }
    }
}

Body:
It's not a good practice to mixe array with object and then add other stuff.
The best thing you could do is this :

$posts = $this->entityManager->getRepository(Post::class)->getPage($listType, $page, $pageSize);

$destinationNames = [];
foreach ($posts['data'] as $post) {
    $destinationNames[$post->getPostId()] = $this->destinationService->getDestinationName($posts['data']);
}

return $this->render('posts.html.twig', [
    'posts' => $posts['data'],
    'destinationNames' => $destinationNames,
]);

I suppose here that $post->getPostId() is your unique identifier, if not, replace by the right identifier

And in your template you could do something like :

{% for post in posts %}
    // do your stuff
    {{ destinationNames[post.id] }}
{% endfor %}


问:
Android Failed to install HelloWorld.apk on device (null) Error
I am new to Android. When I am running my android application in eclipse I am getting these  messages in the console:

```<code>[2011-03-08 12:57:35 - HelloWorld] ------------------------------
[2011-03-08 12:57:35 - HelloWorld] Android Launch!
[2011-03-08 12:57:35 - HelloWorld] adb is running normally.
[2011-03-08 12:57:35 - HelloWorld] Performing com.oreilly.helloworld.HelloWorldActivity activity launch
[2011-03-08 12:57:35 - HelloWorld] Automatic Target Mode: Preferred AVD 'MY_AVD' is not available. Launching new emulator.
[2011-03-08 12:57:35 - HelloWorld] Launching a new emulator with Virtual Device 'MY_AVD'
[2011-03-08 12:57:39 - HelloWorld] New emulator found: emulator-5554
[2011-03-08 12:57:39 - HelloWorld] Waiting for HOME ('android.process.acore') to be launched...
[2011-03-08 13:00:14 - HelloWorld] WARNING: Application does not specify an API level requirement!
[2011-03-08 13:00:14 - HelloWorld] Device API version is 11 (Android 3.0)
[2011-03-08 13:00:14 - HelloWorld] HOME is up on device 'emulator-5554'
[2011-03-08 13:00:14 - HelloWorld] Uploading HelloWorld.apk onto device 'emulator-5554'
[2011-03-08 13:00:14 - HelloWorld] Installing HelloWorld.apk...
[2011-03-08 13:02:22 - HelloWorld] Failed to install HelloWorld.apk on device 'emulator-5554!
[2011-03-08 13:02:22 - HelloWorld] (null)
[2011-03-08 13:02:23 - HelloWorld] Launch canceled!
</code>```

How do I resolve the problems so that my application will launch?

答:
I had imported an existing project and started running...
i too was facing the same problem (WARNING: Application does not specify an API Device API version is 11 (Android 3.0) ). After all my attempts to resolve that failed,I just created new project under other package to maintain the same names and copied all the file contents of the previously imporetd projects manually and again started running...to my surprise it  successfully executed in my first attempt...i think the problem was due to the lack of compatibilty of versions when imported...i hope it may help few...</p>

Body:
I am new to Android. When I am running my android application in eclipse I am getting these  messages in the console:

[2011-03-08 12:57:35 - HelloWorld] ------------------------------
[2011-03-08 12:57:35 - HelloWorld] Android Launch!
[2011-03-08 12:57:35 - HelloWorld] adb is running normally.
[2011-03-08 12:57:35 - HelloWorld] Performing com.oreilly.helloworld.HelloWorldActivity activity launch
[2011-03-08 12:57:35 - HelloWorld] Automatic Target Mode: Preferred AVD 'MY_AVD' is not available. Launching new emulator.
[2011-03-08 12:57:35 - HelloWorld] Launching a new emulator with Virtual Device 'MY_AVD'
[2011-03-08 12:57:39 - HelloWorld] New emulator found: emulator-5554
[2011-03-08 12:57:39 - HelloWorld] Waiting for HOME ('android.process.acore') to be launched...
[2011-03-08 13:00:14 - HelloWorld] WARNING: Application does not specify an API level requirement!
[2011-03-08 13:00:14 - HelloWorld] Device API version is 11 (Android 3.0)
[2011-03-08 13:00:14 - HelloWorld] HOME is up on device 'emulator-5554'
[2011-03-08 13:00:14 - HelloWorld] Uploading HelloWorld.apk onto device 'emulator-5554'
[2011-03-08 13:00:14 - HelloWorld] Installing HelloWorld.apk...
[2011-03-08 13:02:22 - HelloWorld] Failed to install HelloWorld.apk on device 'emulator-5554!
[2011-03-08 13:02:22 - HelloWorld] (null)
[2011-03-08 13:02:23 - HelloWorld] Launch canceled!

How do I resolve the problems so that my application will launch?


问:
Unexpected results for DELETE FROM in SQL Server
Something rare its happens in my code.

Check this:

```<code>if object_id('inscriptos') is not null
    drop table inscriptos;

if object_id('socios') is not null
    drop table socios;

create table socios
(
    numero int identity,
    documento char(8),
    nombre varchar(30),
    domicilio varchar(30),
    primary key (numero)
);

create table inscriptos
(
    numerosocio int not null,
    deporte varchar(20) not null,
    matricula char(1),-- 'n' o 's'
    primary key(numerosocio, deporte),
    constraint FK_inscriptos_socio
          foreign key (numerosocio) references socios(numero)
);
GO

insert into socios values('23333333', 'Alberto Paredes', 'Colon 111');
insert into socios values('24444444', 'Carlos Conte', 'Sarmiento 755');
insert into socios values('25555555', 'Fabian Fuentes', 'Caseros 987');
insert into socios values('26666666', 'Hector Lopez', 'Sucre 344');

insert into inscriptos values(1, 'tenis', 's');
insert into inscriptos values(1, 'basquet', 's');
insert into inscriptos values(1, 'natacion', 's');
insert into inscriptos values(2, 'tenis', 's');
insert into inscriptos values(2, 'natacion', 's');
insert into inscriptos values(2, 'basquet', 'n');
insert into inscriptos values(2, 'futbol', 'n');
insert into inscriptos values(3, 'tenis', 's');
insert into inscriptos values(3, 'basquet', 's');
insert into inscriptos values(3, 'natacion', 'n');
insert into inscriptos values(4, 'basquet', 'n');
</code>```

And here comes the error that I don't understand, I must delete all the rows where in the field "registration" = "n", as you can see there are only 4 records where the value "n" appears in the field registration. But in the following query deletes 8 RECORDS instead of deleting 4 RECORDS.

CODE

```<code>DELETE FROM inscriptos
WHERE numerosocio IN (SELECT s.numero
                      FROM socios AS s
                      JOIN inscriptos AS i ON (i.numerosocio = s.numero)
                      WHERE i.matricula = 'n');
</code>```

Do you know why this happens? I really can't understand it

THANKS!

答:
Your inner SELECT returns this:

```<code>numero
------
2
2
3
4
</code>```

And so your DELETE becomes

```<code>DELETE FROM inscriptos
WHERE numerosocio IN (2, 3, 4)
</code>```

If you check what rows match that condition:

```<code>SELECT * FROM inscriptos
WHERE numerosocio IN (2, 3, 4)
</code>```

you get this result - 8 rows - and those will be deleted:

```<code>numerosocio   deporte   matricula
-----------------------------------
    2         basquet       n
    2         futbol        n
    2         natacion      s
    2         tenis         s
    3         basquet       s
    3         natacion      n
    3         tenis         s
    4         basquet       n
</code>```

So what exactly do you want to delete??

How about this:

```<code>DELETE FROM inscriptos
WHERE matricula = 'n'
</code>```

This would delete those 4 rows with matricula = 'n' - why do you even need that subquery?!?!

Body:
Something rare its happens in my code.

Check this:

if object_id('inscriptos') is not null
    drop table inscriptos;

if object_id('socios') is not null
    drop table socios;

create table socios
(
    numero int identity,
    documento char(8),
    nombre varchar(30),
    domicilio varchar(30),
    primary key (numero)
);

create table inscriptos
(
    numerosocio int not null,
    deporte varchar(20) not null,
    matricula char(1),-- 'n' o 's'
    primary key(numerosocio, deporte),
    constraint FK_inscriptos_socio
          foreign key (numerosocio) references socios(numero)
);
GO

insert into socios values('23333333', 'Alberto Paredes', 'Colon 111');
insert into socios values('24444444', 'Carlos Conte', 'Sarmiento 755');
insert into socios values('25555555', 'Fabian Fuentes', 'Caseros 987');
insert into socios values('26666666', 'Hector Lopez', 'Sucre 344');

insert into inscriptos values(1, 'tenis', 's');
insert into inscriptos values(1, 'basquet', 's');
insert into inscriptos values(1, 'natacion', 's');
insert into inscriptos values(2, 'tenis', 's');
insert into inscriptos values(2, 'natacion', 's');
insert into inscriptos values(2, 'basquet', 'n');
insert into inscriptos values(2, 'futbol', 'n');
insert into inscriptos values(3, 'tenis', 's');
insert into inscriptos values(3, 'basquet', 's');
insert into inscriptos values(3, 'natacion', 'n');
insert into inscriptos values(4, 'basquet', 'n');

And here comes the error that I don't understand, I must delete all the rows where in the field "registration" = "n", as you can see there are only 4 records where the value "n" appears in the field registration. But in the following query deletes 8 RECORDS instead of deleting 4 RECORDS.

CODE

DELETE FROM inscriptos
WHERE numerosocio IN (SELECT s.numero
                      FROM socios AS s
                      JOIN inscriptos AS i ON (i.numerosocio = s.numero)
                      WHERE i.matricula = 'n');

Do you know why this happens? I really can't understand it

THANKS!

Body:
Your inner SELECT returns this:

numero
------
2
2
3
4

And so your DELETE becomes

DELETE FROM inscriptos
WHERE numerosocio IN (2, 3, 4)

If you check what rows match that condition:

SELECT * FROM inscriptos
WHERE numerosocio IN (2, 3, 4)

you get this result - 8 rows - and those will be deleted:

numerosocio   deporte   matricula
-----------------------------------
    2         basquet       n
    2         futbol        n
    2         natacion      s
    2         tenis         s
    3         basquet       s
    3         natacion      n
    3         tenis         s
    4         basquet       n

So what exactly do you want to delete??

How about this:

DELETE FROM inscriptos
WHERE matricula = 'n'

This would delete those 4 rows with matricula = 'n' - why do you even need that subquery?!?!


问:
Beautiful Soup Find href text based on partial attribute value
I am trying to identify tags in an html document based on part of the attribute value.

I'm interested in any 'a' under 'tr' tag as long as it starts or has :

"AnnoncesImmobilier.asp?rech_cod_pay=" in the href attribute.

HTML source :

```<code><tr bgcolor="#f1efe2" class="Tableau1" valign="middle">
   <td bgcolor="#294a73" height="20"><img alt="" height="1" src="/images/space.gif" width="1"/></td>
   <td>  <a href="AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=10117&rech_cod_loc=1011701" onmouseover="return escape('<b>Gouvernorat</b> : Tunis<br/><b>Délégation</b> : La Marsa<br/><b>Localité</b> : Berge Du Lac');">Berge Du Lac</a> </td>
   <td bgcolor="#294a73"><img alt="" height="1" src="/images/space.gif" width="1"/></td>
   <td onmouseover="return escape('<b>Rubrique</b> : Offres<br/><b>Nature</b> : Terrain<br/><b>Type</b> : Terrain nu');" style="CURSOR:pointer;">  Terrain</td>
</code>```

will give ad_title = "Berge Du Lac"

In the source HTML , each "tr" tag with class "Tableau1" contains an ad with different tr , a , tags for title, price, description etc...

Below is my code :

```<code>import re
from bs4 import BeautifulSoup

# The URL to get data from
URL = 'http://www.tunisie-annonce.com/AnnoncesImmobilier.asp'

data = requests.get(URL)

soup = BeautifulSoup(data.content, "html.parser")

# Variable to extract the ads
ads = soup.find_all("tr", {"class":"Tableau1"})

for ad in ads:
    ad_title = ads.find(text=re.compile('AnnoncesImmobilier.asp?rech_cod_pay=')).parent.get_text())
print(title)
</code>```

ad_title = ads.find(text=re.compile('AnnoncesImmobilier.asp?rech_cod_pay=')).parent.get_text())  is the last snippet that I tried to retrieve the text, but neither this or previous code worked for me.

How can i proceed ?

答:
I'm interested in any 'a' under 'tr' tag as long as it starts or has :
"AnnoncesImmobilier.asp?rech_cod_pay=" in the href attribute.

You can make your selection more specific with css selectors:

```<code>soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])')
</code>```

To get a list of all the href texts just iterat the result set:

```<code>[row.a.text for row in soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])')]
</code>```

Using set() you can filter the list to unique values:

```<code>set([row.a.text for row in soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])')])
</code>```

Output

```<code>{'Hammam Lif', 'El Manar 2', 'El Menzah 8', 'Chotrana 1', 'Rades', 'Sousse Corniche', 'Cite De La Sant', 'Sousse', 'Bizerte', 'Ain Zaghouan', 'Hammamet', 'La Soukra', 'Riadh Landlous', 'El Menzah 5', 'Khezama Ouest', 'Montplaisir', 'Sousse Khezama', 'Hergla', 'El Ouerdia', 'Hammam Sousse', 'El Menzah 1', 'Cite Ennasr 2', 'Bab El Khadra'}
</code>```

To extract more than just the href text you can do the following:

```<code>data = []
for row in soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])'):
    d = list(row.stripped_strings)
    d.append(row.a['href'])
    data.append(d)
pd.DataFrame(data)
</code>```

Output

Région
Nature
Type
Texte annonce
Prix
Modifiée
Link

Sousse Corniche
Location
App. 3 pièc
Magnifique appartement s2 fac
1 000
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=12114&rech_cod_loc=1211413

Riadh Landlous
Location
App. 4 pièc
S3 situé au 1ér étage à riadh
850
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=10201&rech_cod_loc=1020135

Khezama Ouest
Vente
App. 4 pièc
Magnifique s3 khzema pré
250 000
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=12112&rech_cod_loc=1211209

El Menzah 8
Location
App. 1 pièc
Studio meublé manzah 8 vv
600
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=10201&rech_cod_loc=1020126

Hergla
Vente
App. 3 pièc
Appartement s 2 vue mer
300 000
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=12105&rech_cod_loc=1210502

...

Body:
I am trying to identify tags in an html document based on part of the attribute value.

I'm interested in any 'a' under 'tr' tag as long as it starts or has :

"AnnoncesImmobilier.asp?rech_cod_pay=" in the href attribute.

HTML source :

     <a href="AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=10117&rech_cod_loc=1011701" onmouseover="return escape('Gouvernorat : Tunis
Délégation : La Marsa
Localité : Berge Du Lac');">Berge Du Lac

   <td onmouseover="return escape('Rubrique : Offres
Nature : Terrain
Type : Terrain nu');" style="CURSOR:pointer;">  Terrain

will give ad_title = "Berge Du Lac"

In the source HTML , each "tr" tag with class "Tableau1" contains an ad with different tr , a , tags for title, price, description etc...

Below is my code :

import re
from bs4 import BeautifulSoup

# The URL to get data from
URL = 'http://www.tunisie-annonce.com/AnnoncesImmobilier.asp'

data = requests.get(URL)

soup = BeautifulSoup(data.content, "html.parser")

# Variable to extract the ads
ads = soup.find_all("tr", {"class":"Tableau1"})

for ad in ads:
    ad_title = ads.find(text=re.compile('AnnoncesImmobilier.asp?rech_cod_pay=')).parent.get_text())
print(title)

ad_title = ads.find(text=re.compile('AnnoncesImmobilier.asp?rech_cod_pay=')).parent.get_text())  is the last snippet that I tried to retrieve the text, but neither this or previous code worked for me.

How can i proceed ?

Body:
I'm interested in any 'a' under 'tr' tag as long as it starts or has :
"AnnoncesImmobilier.asp?rech_cod_pay=" in the href attribute.

You can make your selection more specific with css selectors:

soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])')

To get a list of all the href texts just iterat the result set:

[row.a.text for row in soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])')]

Using set() you can filter the list to unique values:

set([row.a.text for row in soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])')])

Output

{'Hammam Lif', 'El Manar 2', 'El Menzah 8', 'Chotrana 1', 'Rades', 'Sousse Corniche', 'Cite De La Sant', 'Sousse', 'Bizerte', 'Ain Zaghouan', 'Hammamet', 'La Soukra', 'Riadh Landlous', 'El Menzah 5', 'Khezama Ouest', 'Montplaisir', 'Sousse Khezama', 'Hergla', 'El Ouerdia', 'Hammam Sousse', 'El Menzah 1', 'Cite Ennasr 2', 'Bab El Khadra'}

To extract more than just the href text you can do the following:

data = []
for row in soup.select('tr.Tableau1:has(a[href*="AnnoncesImmobilier.asp?rech_cod_pay="])'):
    d = list(row.stripped_strings)
    d.append(row.a['href'])
    data.append(d)
pd.DataFrame(data)

Output

Région
Nature
Type
Texte annonce
Prix
Modifiée
Link

Sousse Corniche
Location
App. 3 pièc
Magnifique appartement s2 fac
1 000
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=12114&rech_cod_loc=1211413

Riadh Landlous
Location
App. 4 pièc
S3 situé au 1ér étage à riadh
850
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=10201&rech_cod_loc=1020135

Khezama Ouest
Vente
App. 4 pièc
Magnifique s3 khzema pré
250 000
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=12112&rech_cod_loc=1211209

El Menzah 8
Location
App. 1 pièc
Studio meublé manzah 8 vv
600
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=10201&rech_cod_loc=1020126

Hergla
Vente
App. 3 pièc
Appartement s 2 vue mer
300 000
08/02/2022
AnnoncesImmobilier.asp?rech_cod_pay=TN&rech_cod_vil=12105&rech_cod_loc=1210502

...


问:
WCF and problem with JSON
Gentelmens,

I'm working with WCF services and I would like to see result as JSON.
But I don't have any ideas how to do it. I have marked my method as

```<code>[WebGet(ResponseFormat = WebMessageFormat.Json)]
</code>```

but this doesn't help me. In "Wcf test client" I see result as xml.

I have tried to add behaviour(WebHttp with Json) to endpoint but I have error:

```<code>The endpoint at 'http://localhost:8732/Design_Time_Addresses/PlayingWithWCF2/Service1/' does not have a Binding
with the None MessageVersion.  'System.ServiceModel.Description.WebHttpBehavior' is only intended for use
with WebHttpBinding or similar bindings.
</code>```

DataContract:

```<code>  [DataContract]
  public class Foo
  {
    [DataMember]
    public string Name { get; set; }
  }
</code>```

Interface:

```<code>  [ServiceContract]
  public interface IFooService
  {
    [OperationContract]
    List<Foo> GetList();
  }
</code>```

Service:

```<code>  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
  [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
  public class FooSerivce : IFooService
  {
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public List<Foo> GetList()
    {
      return new List<Foo> {new Foo {Name = "Name1"}, new Foo {Name = "Name2"}};
    }
  }
</code>```

Web.config:

```<code><system.serviceModel>
    <services>
      <service name="PlayingWithWCF2.FooSerivce">
        <endpoint address="" behaviorConfiguration="" binding="wsHttpBinding"
         contract="PlayingWithWCF2.IFooService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/PlayingWithWCF2/Service1/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</code>```

Could you give me several advices how I can solve this problem?

P.S. Sorry if question is stupid but I'm newbie in WCF

答:
I believe that your problem lies in your web.config, your binding configuration should be set to webHttp.
Have a look at the following question/answer on stackoverflow</p>

Title: WCF and problem with JSON

Body:
Gentelmens,

I'm working with WCF services and I would like to see result as JSON.
But I don't have any ideas how to do it. I have marked my method as

[WebGet(ResponseFormat = WebMessageFormat.Json)]

but this doesn't help me. In "Wcf test client" I see result as xml.

I have tried to add behaviour(WebHttp with Json) to endpoint but I have error:

The endpoint at 'http://localhost:8732/Design_Time_Addresses/PlayingWithWCF2/Service1/' does not have a Binding
with the None MessageVersion.  'System.ServiceModel.Description.WebHttpBehavior' is only intended for use
with WebHttpBinding or similar bindings.

DataContract:

  [DataContract]
  public class Foo
  {
    [DataMember]
    public string Name { get; set; }
  }

Interface:

  [ServiceContract]
  public interface IFooService
  {
    [OperationContract]
    List<Foo> GetList();
  }

Service:

  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
  [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
  public class FooSerivce : IFooService
  {
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public List<Foo> GetList()
    {
      return new List<Foo> {new Foo {Name = "Name1"}, new Foo {Name = "Name2"}};
    }
  }

Web.config:

<system.serviceModel>
    <services>
      <service name="PlayingWithWCF2.FooSerivce">
        <endpoint address="" behaviorConfiguration="" binding="wsHttpBinding"
         contract="PlayingWithWCF2.IFooService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/PlayingWithWCF2/Service1/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Could you give me several advices how I can solve this problem?

P.S. Sorry if question is stupid but I'm newbie in WCF


问:
How to add man and zip to "git bash" installation on Windows
I am using git bash on Windows - that is git for Windows via the integrated bash. Apparently it uses the MINGW/MSYS underpinning. (Update from @VonC: It now uses msys2 since msysgit is obsolete since Q4 2015.)

So there are already a lot of MSYS tools installed - from awk to zcat. However I miss the man command and zip to compress multiple files into a zip file (unzip exists!).

Where from can I install them? I do not want to install another copy of the MINGW system! Any way just to add some pre-compiled tools to the git bash installation?

答:
steps to install SDKMAN on windows

Run Windows Terminal in Admin rights. open git bash inside. (Ctrl + Shift + 4)

winget install -e --id GnuWin32.Zip
mkdir ~/bin
cp /usr/bin/unzip ~/bin/zip
curl -s "https://beta.sdkman.io" | bash
source "${HOME}/.sdkman/bin/sdkman-init.sh"
sdk selfupdate force
```
<p>After you can install Java like this.</p>
<pre class="lang-bash prettyprint-override"><code>sdk install java 17.0.2-open
</code>```

Done ! :)

Body:
steps to install SDKMAN on windows

Run Windows Terminal in Admin rights. open git bash inside. (Ctrl + Shift + 4)

winget install -e --id GnuWin32.Zip
mkdir ~/bin
cp /usr/bin/unzip ~/bin/zip
curl -s "https://beta.sdkman.io" | bash
source "${HOME}/.sdkman/bin/sdkman-init.sh"
sdk selfupdate force

After you can install Java like this.

sdk install java 17.0.2-open

Done ! :)


问:
How to send push notification in flutter, so that it will not stay in system tray? Or delete it from system tray after showing up
The app is in the foreground. I am showing a local notification to the user. After showing up, I don't want the user to see this notification in the system tray. Can this package or other allow me to send notification without entering to the system tray, or delete this notification just after showing up.</p>

答:
The flutter_local_notifications plugin provides a method to cancel all notifications or cancel a single notification. You have to call them in the appropriate place for it to work

```<code>await flutterLocalNotificationsPlugin.cancelAll(); \\ Removes all Notifications

await flutterLocalNotificationsPlugin.cancel(1); \\ Removes notification with id = 1
</code>```

If this does not work, you can also try this plugin
https://pub.dev/packages/eraser

Body:
The flutter_local_notifications plugin provides a method to cancel all notifications or cancel a single notification. You have to call them in the appropriate place for it to work

await flutterLocalNotificationsPlugin.cancelAll(); \\ Removes all Notifications

await flutterLocalNotificationsPlugin.cancel(1); \\ Removes notification with id = 1

If this does not work, you can also try this plugin
https://pub.dev/packages/eraser


问:
Updating Python on Mac
I wanted to update my python 2.6.1 to 3.x on mac but I was wondering if it's possible to do it using the terminal or I have to download the installer from python website?

I am asking this question because the installer is not updating my terminal python version.

答:
Install Home brew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Install python 3 brew install python3 && cp /usr/local/bin/python3 /usr/local/bin/python

Update python to latest version ln -s -f /usr/local/bin/python[your-latest-version-just-installed] /usr/local/bin/python

Title: Updating Python on Mac


问:
Calculating the mean by name of a named numeric returing another named numeric as a result
I am working on a code which has a for loop. At the end of each iteration, a named numeric vector is concatenated to the one of the previous loop.

```<code>all_obj <- c()
for (i in 1:3){
  obj <- 1:3*i
  names(obj) <- c('foo', 'baz', 'bar')
  all_obj <- c(all_obj, obj)
}
</code>```

At the end, all_obj looks like this:

```<code>foo baz bar foo baz bar foo baz bar
  1   2   3   2   4   6   3   6   9
</code>```

What I would need now is to have a result which is the mean by name of this vector, and it is a named numeric itself.

Expected result

```<code>foo baz bar
  2   4   6
</code>```

I know I can get the values with name foo (for example) with all_obj[names(all_obj) == "foo"]. But I am bit stuck as to how would I reach my desired result from here without having to convert the data too much (e.g. avoiding doing as.data.frame for instance). Not that there is anything wrong with this, it's just a matter of preference and curiosity.

This was my best attempt so far.

```<code>lapply(unique(names(all_obj)), function(x) mean(all_obj[names(all_obj) == x]))
#[[1]]
#[1] 2
#
#[[2]]
#[1] 4
#
#[[3]]
#[1] 6
</code>```

答:
An other way in base R is to split all_obj according to names, and calculate mean for each group using sapply.

```<code>sapply(split(all_obj, names(all_obj)), mean)
bar baz foo
  6   4   2
</code>```

Body:
I am working on a code which has a for loop. At the end of each iteration, a named numeric vector is concatenated to the one of the previous loop.

all_obj <- c()
for (i in 1:3){
  obj <- 1:3*i
  names(obj) <- c('foo', 'baz', 'bar')
  all_obj <- c(all_obj, obj)
}

At the end, all_obj looks like this:

foo baz bar foo baz bar foo baz bar
  1   2   3   2   4   6   3   6   9

What I would need now is to have a result which is the mean by name of this vector, and it is a named numeric itself.

Expected result

foo baz bar
  2   4   6

I know I can get the values with name foo (for example) with all_obj[names(all_obj) == "foo"]. But I am bit stuck as to how would I reach my desired result from here without having to convert the data too much (e.g. avoiding doing as.data.frame for instance). Not that there is anything wrong with this, it's just a matter of preference and curiosity.

This was my best attempt so far.

lapply(unique(names(all_obj)), function(x) mean(all_obj[names(all_obj) == x]))
#[[1]]
#[1] 2
#
#[[2]]
#[1] 4
#
#[[3]]
#[1] 6

Body:
An other way in base R is to split all_obj according to names, and calculate mean for each group using sapply.

sapply(split(all_obj, names(all_obj)), mean)
bar baz foo
  6   4   2


问:
which library is linked when i am using stdio.h,conio.h
see when ever we are going to use any library at that time we include one .h file in our application & at compiling that application we link that library. if  that library is .so then link at run time.

Now my question is in any system when i am including basic header file like stdio.h conio.h string.h at that time which library is going to link with my program.?

Is it static or dynamic.?

how can i install it in ma system.? any documentation for that?

we are not linking that library still does that library automatically link.?

答: The implementations for those functions are usually found in the libc directly, e.g. libc.so.6 or msvcrt90.dll.</p>


问:
React Antd Tree : get parent ID of selected Node
I'm using Tree of antd and i want to be able to console.log the parent of the selected node.
This is an example :

When i select Leaf for example : i want to get

parent 1-0

id in the console

this is my sample code, if you have any idea please :)
Thank you

答:
I got this piece of code from antd's "Searchable" example.

const getParentKey = (key, tree) => {
  let parentKey;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentKey = node.key;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey;
};
```
<p>The function takes in the key of the child, and the tree data, and then it returns the parent's key. Since you want to get the parent's title, you can tweak a bit and use it in your code like this</p>
<pre class="lang-js prettyprint-override"><code>const getParentTitle = (key, tree) => {
  let parentTitle;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentTitle = node.title;
      } else if (getParentTitle(key, node.children)) {
        parentTitle = getParentTitle(key, node.children);
      }
    }
  }
  return parentTitle;
}

const Demo = () => {
  const onSelect = (selectedKeys, info) => {
    console.log('selected', selectedKeys, info);
    console.log(getParentTitle(selectedKeys[0], treeData))
};

  const onCheck = (checkedKeys, info) => {
    console.log('onCheck', checkedKeys, info);
  };

  return (
    <Tree
      checkable
      defaultExpandedKeys={['0-0-0', '0-0-1']}
      defaultSelectedKeys={['0-0-0', '0-0-1']}
      defaultCheckedKeys={['0-0-0', '0-0-1']}
      onSelect={onSelect}
      onCheck={onCheck}
      treeData={treeData}
    />
  );
};
</code>```

Or you can even go bigger by getting the entire parent node object, and then selectively choose which attribute you want to use

const getParentNode = (key, tree) => {
  let parentNode;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentNode = node;
      } else if (getParentNode(key, node.children)) {
        parentNode = getParentNode (key, node.children);
      }
    }
  }
  return parentNode;
}

const Demo = () => {
  const onSelect = (selectedKeys, info) => {
    console.log('selected', selectedKeys, info);
    let parentNode = getParentNode(selectedKeys[0], treeData)
    console.log(parentNode.key, parentNode.title)
  };
  ...
```

You can see the entire shape of the node object if you console.log it

One of my experience using antd is that their doc does not have the best explanations so sometimes you have to go through a lot of examples to fully understand the antd API

Body:
I got this piece of code from antd's "Searchable" example.

const getParentKey = (key, tree) => {
  let parentKey;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentKey = node.key;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey;
};

The function takes in the key of the child, and the tree data, and then it returns the parent's key. Since you want to get the parent's title, you can tweak a bit and use it in your code like this

const getParentTitle = (key, tree) => {
  let parentTitle;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentTitle = node.title;
      } else if (getParentTitle(key, node.children)) {
        parentTitle = getParentTitle(key, node.children);
      }
    }
  }
  return parentTitle;
}

const Demo = () => {
  const onSelect = (selectedKeys, info) => {
    console.log('selected', selectedKeys, info);
    console.log(getParentTitle(selectedKeys[0], treeData))
};

  const onCheck = (checkedKeys, info) => {
    console.log('onCheck', checkedKeys, info);
  };

  return (
    <Tree
      checkable
      defaultExpandedKeys={['0-0-0', '0-0-1']}
      defaultSelectedKeys={['0-0-0', '0-0-1']}
      defaultCheckedKeys={['0-0-0', '0-0-1']}
      onSelect={onSelect}
      onCheck={onCheck}
      treeData={treeData}
    />
  );
};

Or you can even go bigger by getting the entire parent node object, and then selectively choose which attribute you want to use

const getParentNode = (key, tree) => {
  let parentNode;
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children) {
      if (node.children.some(item => item.key === key)) {
        parentNode = node;
      } else if (getParentNode(key, node.children)) {
        parentNode = getParentNode (key, node.children);
      }
    }
  }
  return parentNode;
}

const Demo = () => {
  const onSelect = (selectedKeys, info) => {
    console.log('selected', selectedKeys, info);
    let parentNode = getParentNode(selectedKeys[0], treeData)
    console.log(parentNode.key, parentNode.title)
  };
  ...

You can see the entire shape of the node object if you console.log it

One of my experience using antd is that their doc does not have the best explanations so sometimes you have to go through a lot of examples to fully understand the antd API


问:
gmail API : ModuleNotFoundError: No module named 'google'
While running the quickstart.py of Gmail, I get the following error on macOS.

```<code>Traceback (most recent call last):
  File "quickstart.py", line 4, in <module>
    from googleapiclient.discovery import build
  File "/Users/<user>/Documents/venv/bin/googleapiclient/discovery.py", line 49, in <module>
    import google.api_core.client_options
ModuleNotFoundError: No module named 'google'
</code>```

These are the installed Google libraries.

```<code>$ pip freeze | grep google
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
google-api-core==1.16.0
google-api-python-client==1.8.0
google-auth==1.12.0
google-auth-httplib2==0.0.3
google-auth-oauthlib==0.4.1
google-cloud-bigquery==1.24.0
google-cloud-core==1.3.0
google-resumable-media==0.5.0
googleapis-common-protos==1.51.0
</code>```

答:
I suspect that you are using python3 rather than python2.7. Using pip is pointing to your python2.7 installation. You can use pip for python3 by slightly editing the command you are running in your shell:

pip3 install --upgrade google-api-python-client
```
<p>Even more secure could be this (do note that we use pip, not pip3 in this command):</p>
<pre class="lang-sh prettyprint-override"><code>python3 -m pip install --upgrade google-api-python-client
</code>```

This command will point to the python3 interpreter you are currently using.

Also make sure your venv is activated when using the above commands if you want to work in your virtual environment.

Body:
While running the quickstart.py of Gmail, I get the following error on macOS.

Traceback (most recent call last):
  File "quickstart.py", line 4, in <module>
    from googleapiclient.discovery import build
  File "/Users/<user>/Documents/venv/bin/googleapiclient/discovery.py", line 49, in <module>
    import google.api_core.client_options
ModuleNotFoundError: No module named 'google'

These are the installed Google libraries.

$ pip freeze | grep google
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
google-api-core==1.16.0
google-api-python-client==1.8.0
google-auth==1.12.0
google-auth-httplib2==0.0.3
google-auth-oauthlib==0.4.1
google-cloud-bigquery==1.24.0
google-cloud-core==1.3.0
google-resumable-media==0.5.0
googleapis-common-protos==1.51.0

Body:
I suspect that you are using python3 rather than python2.7. Using pip is pointing to your python2.7 installation. You can use pip for python3 by slightly editing the command you are running in your shell:

pip3 install --upgrade google-api-python-client

Even more secure could be this (do note that we use pip, not pip3 in this command):

python3 -m pip install --upgrade google-api-python-client

This command will point to the python3 interpreter you are currently using.

Also make sure your venv is activated when using the above commands if you want to work in your virtual environment.


问:
std::ranges algorithm function object customisation points AKA niebloids - problems with std lib types
All done with gcc 11.2 and libstdc++-11

Below code shows a variety of ways of using std::sort and then std::ranges::sort to sort builtins, user defined types and a std library type.

Only the std library type gives me trouble:

I can't easily define a custom operator< or operator<=> because it is UB to add that to namespace std. I think there is no way around this? (without using a lambda or similar)

for some reason I cannot pass a public member function as the proj parameter on the std lib type (but it works on the user defined type). Why? I was unable to penetrate the "wall of errors" enough to find out. gcc basically says: no known conversion for argument 3 from ‘<unresolved overloaded function type>’ to ‘std::identity’..

Update: My only theory on 2. above is that "unresolved overloaded function type" means that std::complex<double>::real has 2 overloads. One which takes a parameter (the "setter") and one which doesn't (the "getter"). Is there a syntax which allows me to specify that I want the "address of" the one without a parameter?

Update2: Thanks to 康桓瑋 for pointing out in the comments that taking the address of a member function in std is just UB anyway. However if I add a sum(int c) overload to thing (now added below) I get the same "unresolved overloaded" error. So the question remains, how can I select the one with no params. Or is there no way?

#include <algorithm>
#include <compare>
#include <complex>
#include <iostream>
#include <ranges>
#include <vector>

namespace std {
// this is UNDEFINED BEHAVIOUR!!! --- but "it works", so we know this option is what would be
// required, but is not available to us
std::partial_ordering operator<=>(const std::complex<double>& a, const std::complex<double>& b) {
  return std::abs(a) <=> std::abs(b);
}
} // namespace std

// a user defined type
struct thing {
  int x{};
  int y{};

  [[nodiscard]] int sum() const { return x + y; }
  [[nodiscard]] int sum(int c) const { return x + y + c; } // added for update 2

  friend std::strong_ordering operator<=>(const thing& a, const thing& b) {
    return a.x + a.y <=> b.x + b.y;
  }

  friend bool operator==(const thing& a, const thing& b) { return a.x + a.y == b.x + b.y; }

  friend std::ostream& operator<<(std::ostream& os, const thing& rhs) {
    return os << "[" << rhs.x << "," << rhs.y << "]";
  }
};

int main() {
  // builtin types
  auto ints = std::vector<int>{9, 10, 7, 8, 5, 6, 3, 4, 1, 2};
  std::ranges::sort(ints);
  std::ranges::sort(ints, {}, [](const auto& c) { return -c; });
  for (const auto& e: ints) std::cout << e << " ";
  std::cout << "\n";

  auto things = std::vector<thing>{{9, 10}, {7, 8}, {3, 4}, {1, 2}, {5, 6}};
  std::sort(things.begin(), things.end());
  std::ranges::sort(things);
  std::ranges::sort(things, {}, [](const auto& e) { return e.sum(); });
  std::ranges::sort(things, [](const auto& a, const auto& b) { return a < b; }, {});
  std::ranges::sort(things, {}, &thing::x);
  std::ranges::sort(things, {}, &thing::sum); // COMPILE ERROR afte r update 2
  for (const auto& e: things) std::cout << e << " ";
  std::cout << "\n";

  auto complexes = std::vector<std::complex<double>>{{9, 10}, {7, 8}, {3, 4}, {1, 2}, {5, 6}};
  std::sort(complexes.begin(), complexes.end()); // requires operator< or <=> which is UB
  std::ranges::sort(complexes);                  // requires operator<=> which is UB
  std::ranges::sort(complexes, {}, [](const auto& c) { return std::abs(c); });
  std::ranges::sort(complexes, {}, &std::complex<double>::real); // COMPILE ERROR!!
  for (const auto& e: complexes) std::cout << e << " ";
  std::cout << "\n";

  return EXIT_SUCCESS;
}
```

答:
You need to specify a comparison for T if std::less<T> is unavailable.

Both std::sort and std::ranges::sort require a strict weak ordering predicate, not operator<=> (but that can supply one, via < and std::less)

```<code>template<typename T>
bool complex_less (std::complex<T> lhs, std::complex<T> rhs) { return abs(lhs) < abs(rhs); };

int main() {
  auto things = std::vector<thing>{{9, 10}, {7, 8}, {3, 4}, {1, 2}, {5, 6}};
  std::sort(things.begin(), things.end());
  std::ranges::sort(things);
  std::ranges::sort(things, {}, [](const auto& e) { return e.sum(); });
  std::ranges::sort(things, [](const auto& a, const auto& b) { return a < b; }, {});
  std::ranges::sort(things, {}, &thing::x);
  std::ranges::sort(things, {}, static_cast<int (thing::*)()>(&thing::sum)); // need cast to disambiguate pointer-to-member
  for (const auto& e: things) std::cout << e << " ";
  std::cout << "\n";

  auto complexes = std::vector<std::complex<double>>{{9, 10}, {7, 8}, {3, 4}, {1, 2}, {5, 6}};
  std::sort(complexes.begin(), complexes.end(), complex_less<double>); // fine
  std::ranges::sort(complexes, complex_less<double>);                  // also fine
  std::ranges::sort(complexes, {}, [](const auto& c) { return std::abs(c); }); // still fine
  std::ranges::sort(complexes, {}, [](const auto& c) { return c.real(); }); // fine
  for (const auto& e: complexes) std::cout << e << " ";
  std::cout << "\n";

  return EXIT_SUCCESS;
}
</code>```

Body:
You need to specify a comparison for T if std::less<T> is unavailable.

Both std::sort and std::ranges::sort require a strict weak ordering predicate, not operator<=> (but that can supply one, via < and std::less)

template<typename T>
bool complex_less (std::complex<T> lhs, std::complex<T> rhs) { return abs(lhs) < abs(rhs); };

int main() {
  auto things = std::vector<thing>{{9, 10}, {7, 8}, {3, 4}, {1, 2}, {5, 6}};
  std::sort(things.begin(), things.end());
  std::ranges::sort(things);
  std::ranges::sort(things, {}, [](const auto& e) { return e.sum(); });
  std::ranges::sort(things, [](const auto& a, const auto& b) { return a < b; }, {});
  std::ranges::sort(things, {}, &thing::x);
  std::ranges::sort(things, {}, static_cast<int (thing::*)()>(&thing::sum)); // need cast to disambiguate pointer-to-member
  for (const auto& e: things) std::cout << e << " ";
  std::cout << "\n";

  auto complexes = std::vector<std::complex<double>>{{9, 10}, {7, 8}, {3, 4}, {1, 2}, {5, 6}};
  std::sort(complexes.begin(), complexes.end(), complex_less<double>); // fine
  std::ranges::sort(complexes, complex_less<double>);                  // also fine
  std::ranges::sort(complexes, {}, [](const auto& c) { return std::abs(c); }); // still fine
  std::ranges::sort(complexes, {}, [](const auto& c) { return c.real(); }); // fine
  for (const auto& e: complexes) std::cout << e << " ";
  std::cout << "\n";

  return EXIT_SUCCESS;
}


问:
PHP8/EventListener - Getting Socket instance from file descriptor
PHP8 has introduced Socket class that replaces old socket resource. Now all socket functions works with the instance of this class.

The 2nd argument of EventListener's constructor (https://www.php.net/manual/en/class.eventlistener.php) is callback function. It is called when new connection event arises. There is signature of this callback function: https://www.php.net/manual/en/eventlistener.setcallback.php . It receives file descriptor as the 2nd argument.
File descriptor is numeric value, but I need instance of Socket class, because next I will pass it to constructor of EventBufferEvent.

Please advice how can I acquire instance of Socket for this file descriptor?

Solution that doesn't work:

I tried to find address and port that are bound to the file descriptor, then create new socket and bind it to this address and port. But that creates new socket with new file descriptor, not related to connection received in callback of event listener.

I'm stuck on finding any useful documentation or code samples for my problem while migrating my event-based socket server to php8.

答:
Use can also use an undocumented EventUtil::createSocket function:

$socket = EventUtil::createSocket($fd);
socket_set_nonblock($socket);
$socketFd = EventUtil::getSocketFd($socket);
```

Only make sure to save the reference to the socket somewhere, if you are using the $fd with other classes such as EventBufferEvent. Otherwise, the $socket variable may be closed together with the underlying file descriptor.

Body:
Use can also use an undocumented EventUtil::createSocket function:

$socket = EventUtil::createSocket($fd);
socket_set_nonblock($socket);
$socketFd = EventUtil::getSocketFd($socket);

Only make sure to save the reference to the socket somewhere, if you are using the $fd with other classes such as EventBufferEvent. Otherwise, the $socket variable may be closed together with the underlying file descriptor.


问:
iOS: Add ability to delete files from my app using system menu (Settings->General->iPhone Storage)
I notice for some apps, you have the ability to delete data (stored) files from that app, using the system menu (Settings->General->iPhone Storage->AppName)

How can I add the ability to my app? Is it enabling permission, or do I have to write code too?

答:
You should make both of these raw keys true in the info.plist. then any files inside the documents folder will appear there.

```<code>UIFileSharingEnabled
</code>```
```<code>LSSupportsOpeningDocumentsInPlace
</code>```

they should be added like:

Note that now the user can access the files directly without using your app. (with a computer or using the Files app or etc.)

Body:
You should make both of these raw keys true in the info.plist. then any files inside the documents folder will appear there.

UIFileSharingEnabled

LSSupportsOpeningDocumentsInPlace

they should be added like:

Note that now the user can access the files directly without using your app. (with a computer or using the Files app or etc.)


问:
Guidewire- unable to save details to entity
i am trying to save some details in policy center. i am getting those details from billing center and immediately trying to save it but it is giving me exception.

i have called "issuePolicyPeriod" function of billingAPI and returned some values and i need to save this in Policy center.

Exception:
Exception came while saving commision detais: java.lang.RuntimeException: com.guidewire.pl.system.exception.TransactionException: commitBundle must not be called in a transaction.

Code
/**
  * Issue a policy period in Billing Center
  * @param period: the policy period
  * @param transactionID: the unique transaction id to make this call idempotent
  */

override function createPolicyPeriod(period: PolicyPeriod, transactionID : String) : String {
    var issuePolicyInfo = new IssuePolicyInfo()
    issuePolicyInfo.sync(period)
    PCLoggerCategory.BILLING_SYSTEM_PLUGIN.info("Sending policy ${period} to Billing System")

```<code> var commissionList = callUpdate(\ b -> b.issuePolicyPeriod(issuePolicyInfo, transactionID))

gw.transaction.Transaction.runWithNewBundle(\ bundle -> {
  var commission = new CommissionDetails()
  bundle.add(commission)
  commission.Commission_SI = new BigDecimal( commissionList.get(1))
  commission.CommissionGST_SI = new BigDecimal(commissionList.get(2))
  commission.CommissionRate_SI = commissionList.get(3).toString()

})

return  commissionList.get(0)
</code>```

}

I am calling issuePolicyPeriod() function from PC using BillingAPI and returning commission details from BC and trying to save it in PC entity immediately.

Hi,
thank you for your answer. I tried the above code but it is not saving to entity  and nor giving any exception. I have a doubt here will current bundle still available? because here we are calling billing center and don't know when BC responds.
in web service calls will guidewire hold the current bundle until response comes back?
When guidewire commits the current bundle in web service calls?

答:
I had a similar error with a bundle (java.lang.RuntimeException: com.guidewire.pl.system.exception.TransactionException: commitBundle must not be called in a transaction)
and I could be solved with this steps

quit or comment this: gw.transaction.Transaction.runWithNewBundle(\ bundle -> {})

The problem was that I had an existing bundle, so I only needed to call it with getCurrent()

var bundle = gw.transaction.Transaction.getCurrent()

Body:
i am trying to save some details in policy center. i am getting those details from billing center and immediately trying to save it but it is giving me exception.

i have called "issuePolicyPeriod" function of billingAPI and returned some values and i need to save this in Policy center.

Exception:
Exception came while saving commision detais: java.lang.RuntimeException: com.guidewire.pl.system.exception.TransactionException: commitBundle must not be called in a transaction.

Code
/**
  * Issue a policy period in Billing Center
  * @param period: the policy period
  * @param transactionID: the unique transaction id to make this call idempotent
  */

override function createPolicyPeriod(period: PolicyPeriod, transactionID : String) : String {
    var issuePolicyInfo = new IssuePolicyInfo()
    issuePolicyInfo.sync(period)
    PCLoggerCategory.BILLING_SYSTEM_PLUGIN.info("Sending policy ${period} to Billing System")

 var commissionList = callUpdate(\ b -> b.issuePolicyPeriod(issuePolicyInfo, transactionID))

gw.transaction.Transaction.runWithNewBundle(\ bundle -> {
  var commission = new CommissionDetails()
  bundle.add(commission)
  commission.Commission_SI = new BigDecimal( commissionList.get(1))
  commission.CommissionGST_SI = new BigDecimal(commissionList.get(2))
  commission.CommissionRate_SI = commissionList.get(3).toString()

})

return  commissionList.get(0)

}

I am calling issuePolicyPeriod() function from PC using BillingAPI and returning commission details from BC and trying to save it in PC entity immediately.

Hi,
thank you for your answer. I tried the above code but it is not saving to entity  and nor giving any exception. I have a doubt here will current bundle still available? because here we are calling billing center and don't know when BC responds.
in web service calls will guidewire hold the current bundle until response comes back?
When guidewire commits the current bundle in web service calls?


问:
concat two strings by sub-stringing with same length
I want to concat two strings, by sub-stringing each one with same length, and concatenation should happen like I mentioned below
for suppose,
I have str1 = raines, str2 = bowls, and LENGTH as 2, then my output should be raboinwless.

edit: starting from leftmost alphabet, identify LENGTH number of letters from str1 and str2, and add the identified letters to output string respectively. repeat this until either str1 or str2 or both have less than LENGTH letters left. Add the remaining letters (if any) from str1 followed by remaining letter (if any) from str2 to output string.

(first two letters from str1 is 'ra', and 'bo' from str2, concatenating them gives 'rabo', in next cycle the next two letters are 'in' from str1 and 'wl' from str2 by concatenating we'll get 'inwl', the total output now is 'raboinwl', at last we now have 'es' from str1, 's' from str2, the overall output is 'raboinwless')

```<code>import java.util.Scanner;

public class practice
{
    //input str1 = raines
    // str2 = bowls
    // num = 2
    //expected output = raboinwless
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        String instr1 = input.nextLine();
        String instr2 = input.nextLine();
        int innum = input.nextInt();
        String outstr="";
        if(innum > instr1.length() || innum > instr2.length()) {
                outstr = instr1+instr2;
                System.out.println(outstr);
        }else if(innum < instr1.length() || innum < instr2.length()) {
            String[] chunks1 = instr1.split("(?<=\\G.{" + innum + "})");
            String[] chunks2 = instr2.split("(?<=\\G.{" + innum + "})");
            int itrCount = 0;
            if(chunks1.length > chunks2.length)
                itrCount = chunks1.length;
            else itrCount = chunks2.length;

                for(int i= 0 ; i< itrCount;i++) {
                    outstr = outstr+chunks1[i];
                    outstr = outstr+chunks2[i];
                }
            System.out.println(outstr);
        }
    }
}
</code>```

if I'm not making any sense or my way the questioning is bad, please comment or restructure my question,

答:
Recursive version

```<code>public static String substringZip (String str1, String str2, int n) {
    if(str1.length() < n || str2.length() < n)
        return str1 + str2;
    else
        return str1.substring(0, n) + str2.substring(0, n) + substringZip(str1.substring(n), str2.substring(n), n);
}
</code>```

Parameters

str1 -> first String

str2 -> second String

n -> number of characters per cicle. if <= 0 Exception (check it in the main)

Body:
I want to concat two strings, by sub-stringing each one with same length, and concatenation should happen like I mentioned below
for suppose,
I have str1 = raines, str2 = bowls, and LENGTH as 2, then my output should be raboinwless.

edit: starting from leftmost alphabet, identify LENGTH number of letters from str1 and str2, and add the identified letters to output string respectively. repeat this until either str1 or str2 or both have less than LENGTH letters left. Add the remaining letters (if any) from str1 followed by remaining letter (if any) from str2 to output string.

(first two letters from str1 is 'ra', and 'bo' from str2, concatenating them gives 'rabo', in next cycle the next two letters are 'in' from str1 and 'wl' from str2 by concatenating we'll get 'inwl', the total output now is 'raboinwl', at last we now have 'es' from str1, 's' from str2, the overall output is 'raboinwless')

import java.util.Scanner;

public class practice
{
    //input str1 = raines
    // str2 = bowls
    // num = 2
    //expected output = raboinwless
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        String instr1 = input.nextLine();
        String instr2 = input.nextLine();
        int innum = input.nextInt();
        String outstr="";
        if(innum > instr1.length() || innum > instr2.length()) {
                outstr = instr1+instr2;
                System.out.println(outstr);
        }else if(innum < instr1.length() || innum < instr2.length()) {
            String[] chunks1 = instr1.split("(?<=\\G.{" + innum + "})");
            String[] chunks2 = instr2.split("(?<=\\G.{" + innum + "})");
            int itrCount = 0;
            if(chunks1.length > chunks2.length)
                itrCount = chunks1.length;
            else itrCount = chunks2.length;

                for(int i= 0 ; i< itrCount;i++) {
                    outstr = outstr+chunks1[i];
                    outstr = outstr+chunks2[i];
                }
            System.out.println(outstr);
        }
    }
}

if I'm not making any sense or my way the questioning is bad, please comment or restructure my question,

Body:
Recursive version

public static String substringZip (String str1, String str2, int n) {
    if(str1.length() < n || str2.length() < n)
        return str1 + str2;
    else
        return str1.substring(0, n) + str2.substring(0, n) + substringZip(str1.substring(n), str2.substring(n), n);
}

Parameters

str1 -> first String

str2 -> second String

n -> number of characters per cicle. if <= 0 Exception (check it in the main)


问:
Copy file to a different directory
I am working on a project where I want to copy some files in one directory to a second already existing directory.

I can't find a way to simply copy from one folder to another. I can find copy file to a new file, or directory to a new directory.

The way I have my program set up right now is I copy the file and leave it in same directory, then move that copy to the directory that I want.

Edit:

Thanks everyone. All of your answers worked. I realized what I did wrong, when i set the destination path I didn't add a filename. Everything works now, Thanks for the super speedy responses.

答:
NET6 - Extension method</p>
```<code>[DebuggerStepThrough]
public static FileInfo CopyToDir(this FileInfo srcFile, string destDir) =>
    (srcFile == null || !srcFile.Exists) ? throw new ArgumentException($"The specified source file [{srcFile.FullName}] does not exist", nameof(srcFile)) :
    (destDir == null || !Directory.Exists(destDir)) ? throw new ArgumentException($"The specified destination directory [{destDir}] does not exist", nameof(destDir)) :
    srcFile.CopyTo(Path.Combine(destDir, srcFile.Name), true);
</code>```

Title: Copy file to a different directory

Body:
NET6 - Extension method

[DebuggerStepThrough]
public static FileInfo CopyToDir(this FileInfo srcFile, string destDir) =>
    (srcFile == null || !srcFile.Exists) ? throw new ArgumentException($"The specified source file [{srcFile.FullName}] does not exist", nameof(srcFile)) :
    (destDir == null || !Directory.Exists(destDir)) ? throw new ArgumentException($"The specified destination directory [{destDir}] does not exist", nameof(destDir)) :
    srcFile.CopyTo(Path.Combine(destDir, srcFile.Name), true);


问:
Changing background color on any number input higher than 0 in JavaScript
My question is simple so I hope it shouldn't be so hard to solve. Not as hard as it is for me at least :).

```<code><div id="block">
    <input type="number" min="0" value="0">
</div>
</code>```

https://jsfiddle.net/wbrnmldr/9n60r82y/2/

[EDIT ]Ok since I'm clearly too dumb to explain it properly I will do it again. The grey  around the input field is supposed to go yellow, not the input field itself.

So I have this simple div as seen above. What is supposed to happen is that the background color of this div changes from #F1F1F1 to #FFD200 anytime the input value doesn't equal 0 anymore. And to make it more complicated, if the value is zero again it should return to #F1F1F1. I already got it to work when submitting the value but my goal is to see it happen in real-time.

Can anybody help me tackle this problem?
Thanks in advance!

Following are some of the things I tried but I didn't get to work:

```<code>$('.input').each(function() {
    var inputValue = $(this);

    inputValue.data('oldValue', inputValue.val());

    inputValue.bind("propertychange change click keyup input paste",   function(event){
        if (inputValue.data('oldValue') != inputValue.val()) {
        inputValue.data('oldValue', inputValue.val());

        document.getElementsByClassName('block').style.backgroundColor = "#FFD200";
    }

    });
});
</code>```
```<code>function changeColor() {
    document.getElementById("tracker-option-block").style.backgroundColor = "FFD200";
    return false;
}
</code>```

答:
enter image description here

please remember that text in an input doesn't have its background color , rather it have color that i've shown in the code that you can use,
Happy programming!

Body:
My question is simple so I hope it shouldn't be so hard to solve. Not as hard as it is for me at least :).

    <input type="number" min="0" value="0">

https://jsfiddle.net/wbrnmldr/9n60r82y/2/

[EDIT ]Ok since I'm clearly too dumb to explain it properly I will do it again. The grey  around the input field is supposed to go yellow, not the input field itself.

So I have this simple div as seen above. What is supposed to happen is that the background color of this div changes from #F1F1F1 to #FFD200 anytime the input value doesn't equal 0 anymore. And to make it more complicated, if the value is zero again it should return to #F1F1F1. I already got it to work when submitting the value but my goal is to see it happen in real-time.

Can anybody help me tackle this problem?
Thanks in advance!

Following are some of the things I tried but I didn't get to work:

$('.input').each(function() {
    var inputValue = $(this);

    inputValue.data('oldValue', inputValue.val());

    inputValue.bind("propertychange change click keyup input paste",   function(event){
        if (inputValue.data('oldValue') != inputValue.val()) {
        inputValue.data('oldValue', inputValue.val());

        document.getElementsByClassName('block').style.backgroundColor = "#FFD200";
    }

    });
});

function changeColor() {
    document.getElementById("tracker-option-block").style.backgroundColor = "FFD200";
    return false;
}